Friday, September 4, 2009

Populating nested gridviews

Sometimes it’s useful to nest gridviews within another gridview, especially for traditional master/detail output.  Unfortunately the .NET code behind pages do not play well with nested objects (they are not always accessible to refer to in the code), so we have to write code to get around this.

image

We need, for each outer grid row, to find the inner grid and populate it, based on the data in the outer grid.  Of course there are two components, the aspx source (using grid templates), and the code behind.  Some important things to notice: gvReport is the outer grid, gvReport_RowDataBound is the method that populates the inner grid, and gvLicenses is the nested grid.

ASPx source:

<asp:GridView ID="gvReport"
HeaderStyle-CssClass="Grid_HeaderRowStyle"
runat="server"  AutoGenerateColumns="False"        
onrowdatabound="gvReport_RowDataBound"
RowStyle-CssClass="Grid_RowStyle"
AlternatingRowStyle-CssClass="Grid_AlternateRowStyle" AllowSorting="True"
Width="100%"  RowStyle-BackColor="#CCCCCC">
    <Columns>                  
      <asp:TemplateField HeaderText="">
            <ItemTemplate>
            <b>Authority: <%# Eval("citation") %><%# Eval("subchapter") %> - <%# Eval("title") %></b> <br />                   
            <b>Exemption: <%# Eval("shortdescription") %></b>: <%# Eval("longdescription") %>
      <%—nested  grid -->                  
            <asp:GridView ID="gvLicenses"                    
            runat="server" DataKeyNames="licensepermitid" AutoGenerateColumns="False"
                AllowSorting="True"                        
                GridLines="None" RowStyle-CssClass="Grid_RowStyle" Width="100%"  RowStyle-BackColor="White">
                <Columns>      
                   <asp:TemplateField ItemStyle-Width="3%" HeaderStyle-BackColor="White" HeaderText="" ShowHeader="False">
                        <ItemTemplate>&nbsp;</ItemTemplate>
                   </asp:TemplateField>                 
                  <asp:TemplateField HeaderText="Licenses For Authority/Exemption" HeaderStyle-HorizontalAlign="Left" HeaderStyle-BackColor="White">
                        <ItemTemplate>
                            <%# Eval("name") %>                   
                        </ItemTemplate>
                   </asp:TemplateField>                                     
                </Columns>                               
              </asp:GridView>
                    </ItemTemplate>
   </asp:TemplateField>   

   <%-- hide these but include them so they are available in the code-->
        <asp:TemplateField Visible="false">
            <ItemTemplate>
                <asp:TextBox  id="subchapter"  Visible="false" Text='<%# Bind("subchapter")%>' runat="server"  />                      
                <asp:TextBox  id="authorityID"  Visible="false" Text='<%# Bind("authorityID")%>' runat="server"  />          
                <asp:TextBox  id="exemptionid"  Visible="false" Text='<%# Bind("exemptionid")%>' runat="server"  />          
           </ItemTemplate>
        </asp:TemplateField>
    </Columns>    
    </asp:GridView>

 

Code Behind:

protected void gvReport_RowDataBound(object sender, GridViewRowEventArgs e)
{       
    //e.Row is the current row

    if (e.Row.RowType == DataControlRowType.DataRow)
    {  //find the nested objects
        TextBox aTb = (TextBox)e.Row.FindControl("authorityid");
        TextBox eTb = (TextBox)e.Row.FindControl("exemptionid");
        TextBox scTb = (TextBox)e.Row.FindControl("subchapter");

        //nested grid
        GridView gv = (GridView)e.Row.FindControl("gvLicenses");   
        //populate with data from the outer/master grid
        SqlDataReader dr = ReportUtility.GetExemptionAuthoritySubchapterLicenses(Convert.ToInt32(eTb.Text), Convert.ToInt32(aTb.Text), scTb.Text, lpID, ""); 
        gv.DataSource = dr;
        gv.DataBind();
        dr.Close();   
         }

}

No comments:

Post a Comment