There are many different implementations of this functionality available on net in parts. I just thought it would be good thing to put all the different functionalities in a single example. Below is the list of functionalities I have included in the following example :
- Nested GridView in Repeater.
- Paging in child GridView.
- Sorting in child GridView.
- Hide\Unhide child GridView using javascript.
- Sort List object using IComparable interface.
- Save nested child grids data on single click.
Download Code - 30 KB
In the example I'm showing Locations in a Repeater and their SubLocations data in nested GridView. To start with, I'm using a List of Locations and SubLocations custom objects to bind to the data controls.
public class Location
{
public int LocationId { get; set; }
public string LocationName { get; set; }
public List
}
public class SubLocation :IComparable
{
public int SubLocationId { get; set; }
public string SubLocationName { get; set; }
public int Count { get; set; }
public string Owner { get; set; }
public bool IsOpen { get; set; }
public int CompareTo(SubLocation other)
{
return other.SubLocationName.CompareTo(this.SubLocationName);
}
public static Comparison
{
return s1.Count.CompareTo(s2.Count);
};
public static Comparison
{
return s1.Count.CompareTo(s2.Count) * -1 ;
};
public static int SaveSubLocations(List
{
//Save method to save data in database.
return 0;
}
}
}
IComparable interface is implemented in SubLocation class inorder to support generic comparision delegates for Sorting in GridView. I'm generating the list of data in the code itselft, using the methode GetData(), to avoid database interaction as this is just a demo. SaveSubLocations method returns 0, in place of actually database update for the same reason.
Heres the markup for the nested GridView within Repeater control:
GridView's PageIndexChanging event:protected void gvSubLocations_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView gv = (GridView)sender;
gv.PageIndex = e.NewPageIndex;
List
Label lb = (Label)gv.NamingContainer.FindControl("lblLocation");
Hashtable SubLocationDetails = (Hashtable)Session["SubLocationDetails"];
SubLocationsList = (List
gv.DataSource = SubLocationsList;
gv.DataBind();
}
GridView's Sorting :
protected void gvSubLocations_Sorting(object sender, GridViewSortEventArgs e)
{
if (ViewState[_VWSORTDIRECTION].ToString() == SORT_ASCENDING)
ViewState[_VWSORTDIRECTION] = SORT_DESCENDING;
else
ViewState[_VWSORTDIRECTION] = SORT_ASCENDING;
ViewState[_VWSORTCOLUMN] = e.SortExpression;
GridView gv = (GridView)sender;
List
Label lb = (Label)gv.NamingContainer.FindControl("lblLocation");
Hashtable SubLocationDetails = (Hashtable)Session["SubLocationDetails"];
ListSubLocations = (List
SortAndBind(ListSubLocations, ViewState[_VWSORTDIRECTION].ToString(), e.SortExpression, gv);
}
Repeater's Databound event: Here we bind the child gridview controls.
protected void rptLocations_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item e.Item.ItemType == ListItemType.AlternatingItem)
{
GridView gvSubLoc = (GridView)e.Item.FindControl("gvSubLocations");
Location objLoc = (Location)e.Item.DataItem;
gvSubLoc.DataSource = objLoc.SubLocations;
gvSubLoc.DataBind();
}
}
