Add a Grid View, Object DataSource and a dropdown to a web form. Also you will need a class which has two methods with different names and can be marked as SelectMethod (return a List Here is my sample web form: |
<asp:DropDownList ID="ddProductCategory" runat="server"
onselectedindexchanged="ddProductCategory_SelectedIndexChanged"
AutoPostBack="true">
<asp:ListItem Value="0">All Categories</asp:ListItem>
<asp:ListItem Value="1">Electronics</asp:ListItem>
</asp:DropDownList>
asp:Panel>
<asp:Panel ID="pnlProducts" runat="server" GroupingText="Products:">
<asp:GridView ID="grdProducts"
runat="server"
DataSourceID="odsProducts"
AutoGenerateColumns="true"
AllowPaging="true"
PageSize="2">
asp:GridView>
<asp:ObjectDataSource ID="odsProducts" runat="server"
DataObjectTypeName="string"
TypeName="WebApplication2.ProductsCollection"
SelectMethod="SelectAll">
asp:ObjectDataSource>
asp:Panel>
Here is the code in the code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ddProductCategory_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.ddProductCategory.SelectedValue == "0")
{
// Select all products from all categories
// SelectAll() doesn't take any parameters.
this.odsProducts.SelectMethod = "SelectAll";
this.odsProducts.SelectParameters.Clear();
}
else
{
this.odsProducts.SelectMethod = "GetByCategoryID";
this.odsProducts.SelectParameters.Clear();
// Pass category id:
this.odsProducts.SelectParameters.Add("categoryID", TypeCode.Int32, "1");
}
}
And finally the sample class:
public class ProductsCollection
{
public ProductsCollection() { }
public List<string> SelectAll()
{
List<string> retList = new List<string>();
retList.Add("Notebook");
retList.Add("PDA");
retList.Add("GSM");
retList.Add("Tomatoes");
return retList;
}
public List<string> GetByCategoryID(int categoryID)
{
// We will imagine that here we have some processing based on
// categoryid.
List<string> retList = new List<string>();
retList.Add("Notebook");
retList.Add("PDA");
retList.Add("GSM");
return retList;
}
}
What we want to achieve here?
Well, we simply want to display all products from all categories when the user loads the page for the first time. Then we want to give him / her a way to narrow down the results, by selecting a concrete category of products (in our case there is only one category named “Electronics”
The most logical is to change the SelectMethod of the ObjectDataSource from SelectAll() to GetByCategoryID and vise versa.
And, yes, at first sight it seems to work like a charm. But try to navigate to the second page of the GridView (I made the PageSize to be 2 items so the paging control can appear).
You will receive exception in some cases. To see do the following.
1. Refresh the page so you can start from the beginning.
2. Select “Electronics” from the Categories Dropdown.
3. Click on page 2 in the GridView.
Where is the problem here?
As you may already noticed the ObjectDataSource is trying to invoke the Products using the SelectAll() method, passing it parameters for GetByCategoryID.
The reason is that the ObjectDataSource seems to maintain only the SelectParameters and get the SelectMethod from the markup. But for some reason this only happens when the GridView asks for rebind (PageIndex changed and Sorted events).
When you change in the dropdown selected index changed it works.
I have kind of workaround which I will post a bit later and it is not proven to work in all cases but did the trick for me.