Showing posts with label DataKeys. Show all posts
Showing posts with label DataKeys. Show all posts

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!

Friday, May 28, 2010

How To Access the Data Key When Editing A GridView Row

Usually, when I create a GridView, I use an ID field that represents a unique ID tied to each row that I can use to update the database, as seen in the picture below.


However, I recently had a client request that I remove this field as it was confusing their customers. Fair enough. I removed the field, but now I had trouble updating or deleting the database. The field I was formerly using for my WHERE clause is no longer available. Luckily, I've fed the same ID field into the gridview as a Key:

<asp:GridView
ID="GridView1"
AutoGenerateColumns="false"
CellPadding="3"
DataKeyNames="orderID"
AllowSorting="true"
AutoGenerateSelectButton="true"
AutoGenerateEditButton="true"
AutoGenerateDeleteButton="true"
OnRowEditing="GridView1_RowEditing"
OnRowUpdating="GridView1_RowUpdating"
OnRowCancelingEdit="GridView1_RowCancelingEdit"
runat="server">


It would seem like common sense to be able to use the GridViewUpdateEventArgs parameter of my GridView1_RowUpdating Sub procedure a la e.Keys("orderID") to get the id of that particular row, but it return nothing. I'm not sure why this function of GridViewUpdateEventArgs exists, but I've never been able to get it to produce a value.

Exploring it a bit more, I looped through different arrays the GridView would provide and finally found the value using this method:

GridView1.DataKeys(e.RowIndex).Value

GridView1.DataKeys will provide a list of all the Keys of the gridview and feeding in the e.RowIndex will indicate that you want the key for the row you are editing.