How to fire RowCommand event of nested GridView?
In ASP.Net you can use a Repeater or GridView controls to simply display any data collection came from any data source(database,XML file,...etc). Sometimes each item of that collection has a property that is another collection and to display it you will use another Repeater or another GridView(nested Repeater or nested GridView).
To edit, delete or to execute a command on any GridView row you use OnRowCommand event to handle it, but what about the commands on the child(nested) GridView rows. In case of nested Repeater you can set the OnItemCommand event of the child Repeater. You can find many articles explain how to do that. The problem which my friend faced is handling the OnRowCommand event of nested GridView. We googled it but we didn't find a lot of article that explain how to handle it, so I write this post to help any one facing the same issue.
Assume we have a set of Inventories, each Inventory have a set of products. To display All inventories with all products of each one, we will use a GridView for inventories main properties and a nest GridView to list the products of each inventory.
We will bind the GridView of products inside the OnRowDataBound event of the parent GridView.
Again you need to find the child GridView by its ID property but this time inside the RowCreated event of the parent GridView.
To edit, delete or to execute a command on any GridView row you use OnRowCommand event to handle it, but what about the commands on the child(nested) GridView rows. In case of nested Repeater you can set the OnItemCommand event of the child Repeater. You can find many articles explain how to do that. The problem which my friend faced is handling the OnRowCommand event of nested GridView. We googled it but we didn't find a lot of article that explain how to handle it, so I write this post to help any one facing the same issue.
Assume we have a set of Inventories, each Inventory have a set of products. To display All inventories with all products of each one, we will use a GridView for inventories main properties and a nest GridView to list the products of each inventory.
class Inventory
{
public String Name { get; set; }
public Int32 Id { get; set; }
public List<Product> Products { get; set; }
}
class Product
{
public String Name { get; set; }
public Int32 Id { get; set; }
public Int32 Quantity { get; set; }
}
The following image shows our GridView. Note the third column lists the products of an inventory, the forth column in the products grid is button to delete the corresponding product. This is the command that we want to execute.
protected void inventoriesGrid_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridView productsGrid = e.Row.FindControl("productsGrid") as GridView;
productsGrid.DataSource = (e.Row.DataItem as Inventory).Products;
productsGrid.DataBind();
//productsGrid.RowCommand += new GridViewCommandEventHandler(productsGrid_RowCommand);
}
}
In this event we do the following for each row of inventories GridView- Check the RowType, it must be DataRow.
- Finding the child GridView by its ID property.
- Set the DataSource property of products GridView to the product list of current inventory.
- Call DataBind method of products GridView.
- If you bind the parent GridView every time you load the page, so you re-fire its RowDataBound event every time and re-wire the RowCommand of child GridView again and again. That changes the view state of the child GridView and its RowCommand will not be fired( in PostBack ASP.Net read the old view state which is changed while binding the parent grid).
- If you bind the parent grid in first time you request the page(the current request is not a post back) so the RowDataBound will not fired while post back. You think that will solve the problem, No that will not solve it because the RowCreated event of parent GridView be fired every request even if it is postback. That means you need to re-wire the RowCommand of child GridView again.
The best place to wire the RowCommand of child GridView is to write this code inside the RowCreated event of parent GridView because this event be fired after the Page_Load and before handling post back event. This guarantee the RowCommand of child GridView is wired to the same event before handling it.
Again you need to find the child GridView by its ID property but this time inside the RowCreated event of the parent GridView.
protected void inventoriesGrid_RowCreated(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
productsGrid = e.Row.FindControl("productsGrid") as GridView;
productsGrid.RowCommand += new GridViewCommandEventHandler(productsGrid_RowCommand);
}
}
The RowCommand event of child GridView (products) its self protected void productsGrid_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "deleteitem")
{
//Do whatever you want
}
}
you can download the full source code here
C# Command event of GridView
ReplyDeletehow to get CommandArgument for a linkbutton in the nested grid
ReplyDeleteIn the RowCommand event of nested grid you can get the CommandArgument by e.CommandArgument property but after checking on e.CommandName property of your LinkButton in the nested grid
Deleteis there any option directly using void ChildGridview_ItemCommand(object sender, GridViewCommandEventArgs e) for the child Gridview without using class Inventory and class Product in C# coding?
Deletethis event is related to GridView not related to its datasource. you can use it with any datasource like DataSet, DataTable, or any Generic collection. These classes used for demonstration purpose only.
DeleteOk sir one more question and it is related to design part that is how to use child header color according to row color of parent Grid view ?
Deleteyou do that by removing HeaderStyle node from child Grid and add this line into OnRowDataBound event of parent Grid
DeleteproductsGrid.HeaderRow.BackColor = e.Row.BackColor;
Great, thanks!
DeleteRows of Hierarchical GridView
ReplyDeleteWhat is the code for VB.net?
ReplyDeletesorry I am so busy these days to create full example in VB.net but you can use the following links to convert C# code in .cs files to VB.net
Deletehttp://www.developerfusion.com/tools/convert/csharp-to-vb/
http://converter.telerik.com/
Nested Gridview RowCommand event cause Parent GridView RowCommand fire
ReplyDeletehttp://stackoverflow.com/questions/30284080/nested-gridview-rowcommand-event-cause-parent-gridview-rowcommand-fire
In my case I attach RowCommand event in runtime not in GridView definition as mentioned in stackoverflow question.
DeleteYou can download my sample and check it. frankly I have uploaded it from long long time ago and not sure if it has the same issue or not.
How to get cell values from child grid?
ReplyDeleteWorks Perfect Thanks!!!
ReplyDeleteFrom the past thank you very much, for your contribution, I have served a lot in my project.
ReplyDelete