Friday, August 27, 2010

Nested Gridview Within Another Gridview

I recently came across a project for which I had a need for a gridview within a gridview.
For this example, I will create a grids of documents and guides housed within a parent grid of resource categories.

Let's start with a basic gridview of 4 documents (2 training modules on gridviews and 2 user manuals for cell phones).

<asp:GridView
ID="gvDocuments"
DataSourceID="dataDocuments"
AutoGenerateColumns="false"
DataKeyNames="document_id"
CellPadding="8"
HeaderStyle-BackColor="#e0e0e0"
BorderColor="#e0e0e0"
runat="server">
<Columns>
<asp:HyperLinkField
HeaderText="Resource Link"
DataNavigateUrlFields="document_filename"
DataNavigateUrlFormatString="{0}"
Target="_blank"
DataTextField="document_name"
DataTextFormatString="{0}" />
<asp:BoundField
DataField="document_description"
HeaderText="Description" />
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="dataDocuments"
runat="server">
</asp:SqlDataSource>


Both could be considered training, but to better organize the page, I will split the documents up into groups, each document having a group column in the database named document_group.
On my backend, I have a new table to complement the Documents table called DocumentGroups that has a docGrp_name and docGrp_id field. The docGrp_id field will link to the document_group column I mentioned.

Now to drop my original gridview in a second gridview of "Document Groups"
This is where the code gets a little more bloated but still relatively simple:
<asp:GridView
ID="gvDocumentGroups"
DataSourceID="dataDocumentGroups"
DataKeyNames="docGrp_id"
AutoGenerateColumns="false"
GridLines="None"
runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div style="padding-bottom: 12px;">
<div><%#Eval("docGrp_name")%></div>
<asp:GridView
ID="gvDocuments"
DataSourceID="dataDocuments"
AutoGenerateColumns="false"
DataKeyNames="document_id"
CellPadding="8"
HeaderStyle-BackColor="#e0e0e0"
BorderColor="#e0e0e0"
runat="server">
<Columns>
<asp:HyperLinkField
HeaderText="Resource Link"
DataNavigateUrlFields="document_filename"
DataNavigateUrlFormatString="{0}"
Target="_blank"
DataTextField="document_name"
DataTextFormatString="{0}" />
<asp:BoundField
DataField="document_description"
HeaderText="Description" />
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="dataDocuments"
runat="server">
</asp:SqlDataSource>
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource
ID="dataDocumentGroups"
runat="server">
</asp:SqlDataSource>


I added in some padding for better spacing, but you can play around with the CSS however you want.

Now. I didn't put connection strings or select commands in the original SqlDataSource because, if you don't know what you're doing there, this tutorial is not for you.
But now that we've embedded this gridview inside another one, that (inner layer) SqlDataSource is more than likely going to be fed a variable from your outer layer grid.
For my purposes, I'm going to use the docGrp_id, which I conveniently fed into the DataKeys of my outer layer SqlDataSource.
For more information on pulling the current row's datakey, click here.

For Each thisRow As GridViewRow In gvDocumentGroups.Rows
CType(thisRow.FindControl("dataDocuments"), SqlDataSource).SelectCommand = "SELECT * FROM [Documents] WHERE [document_group] = '" & gvDocumentGroups.DataKeys(thisRow.RowIndex).Value & "'"
Next




And there you have it!

0 comments:

Post a Comment