In Part 1 we examined how to display buttons in a DataGrid using
the ButtonColumn tag. Furthermore, we looked at how to have an event handler associated
with the clicking of such a button. In this part we'll discover how to determine what row of the DataGrid
had its button clicked and how to take action based on that information.
Determining What Row's Button was Clicked
Recall that the event handler for the button click had to adhere to the following definition:
Sub eventHandlerName(sender as Object, e as DataGridCommandEventArgs)
...
End Sub
The DataGridCommandEventArgs class contains an Item property that returns
the item containing the source of the object that caused the event to fire. This item is an instance
of the TableRow class corresponding to the row in the DataGrid that was clicked.
You can access the columns of the TableRow class by using the Cells property,
specifying the ordinal value of the column whose cell value you wish to obtain. That is, imagine
that we had a DataGrid whose Columns collection was defined as follows:
Then, in the button click event handler, you could reference the values of the columns of the clicked
row like so:
Sub detailsClicked(sender as Object, e As DataGridCommandEventArgs)
Dim buttonColumn as TableCell = e.Item.Cells(0)
Dim FAQIDColumn as TableCell = e.Item.Cells(1)
Dim DescColumn as TableCell = e.Item.Cells(2)
Dim buttonColText as String = buttonColumn.Text
Dim FAQIDColText as String = FAQIDColumn.Text
Dim DescColText as String = DescColumn.Text
End Sub
Be sure to check out the live demo. One of the first things
you'll likely notice is that the button column does not contain any text. This is because it just contains
the HTML to display the button, hence the TableCell's Text property returns
an empty string.
At the start of this article I discussed a scenario of an eCommerce firm that wanted to display only a
portion of the shipping information, but provide an option for someone to view the full details of
a particular shipping transaction. In our live demos thus far, we've only shown a small subset of
the columns returned by the sp_Popularity stored procedure. Imagine that we wanted to
only show the Description of all of the most popular FAQs and then provide a Details button to allow the user to view the
remaining information about a particular FAQ to be displayed.
While we don't want to display the FAQID table column in the DataGrid, we still need a way of providing
that information to the detailsClicked event handler, since that is the primary key for the
database table, uniquely identifying each FAQ. We can still pass this information along by making one
tiny change to the DataGrid tag: in the BoundColumn tag responsible for displaying the
FAQID database column, we simply add: Visible="False". This hides the column but still allows
the detailsClicked event handler to have access to the proper FAQ's ID via e.Item.Cells(1).Text.
Therefore, all we need to do is rework the detailsClicked event handler so that when it fires
it grabs the information for the FAQ that the user wishes to see more details on, and then displays this
detail information about a particular FAQ. Hopefully after having advanced this far in the article series
your initial thought when it comes to displaying database data is to use a DataGrid. Therefore, our page
will now look like:
<script language="vb" runat="server">
Sub Page_Load(sender as Object, e as EventArgs)
If Not Page.IsPostBack then
BindData() 'Only bind the data on the first page load
End If
End Sub
Sub BindData()
'Make a connection to the database
'Databind the DataReader results to the gPopularFAQs DataGrid.
End Sub
Sub detailsClicked(sender as Object, e As DataGridCommandEventArgs)
'Get detailed information about the selected FAQ and bind
'the database results to the dgFAQDetails DataGrid
End Sub
</script>
<form runat="server">
<asp:DataGrid runat="server" id="dgFAQDetails" ... >
...
</asp:datagrid>
<asp:DataGrid runat="server" id="dgPopularFAQs" ... >
<Columns>
<asp:ButtonColumn Text="Details" HeaderText="FAQ Details"
ButtonType="PushButton" />
<asp:BoundColumn DataField="FAQID" Visible="False" />
<asp:BoundColumn DataField="Description" HeaderText="FAQ Description" />
</Columns>
</asp:datagrid>
</form>
The first thing to notice is that there are two DataGrids on this ASP.NET Web page. The
first one, dgFAQDetails, is set to display the details for a particular FAQ. The second
one, dgPopularFAQs, is the DataGrid we have been using all along to display the 10 most
popular FAQs. Note that for the dgPopularFAQs DataGrid the FAQID BoundColumn
has been altered: Visible="False" has been added so that the FAQID will not show up in
the dgPopularFAQs DataGrid's output.
Conclusion
Over the course of the past three parts of this article series we've gone from simply dumping a
database query's contents to a vanilla HTML table (Part 1), to prettying up the HTML table with
non-programmatic code (Part 2), and, now, to being able to add buttons to each row that correspond
to some action. As we'll see in future articles this simple concept of adding buttons and allowing
actions to occur when the buttons are clicked can be extended to allow for sorting, paging, and
editable data. Until then...