Using a ButtonColumn Control in a DataGrid...

The ButtonColumn Control is one of several controls that can be used within a DataGrid control in ASP.Net. This article demonstates one way to use this control.


By: John Kilgo Date: April 11, 2003 Download the code.

The ButtonColumn Control allows you to add a button to a column in a DataGrid. When that button is clicked some action can take place. In this article we show a small amount of data from the Employees table of the Northwind database and include a ButtonColumn for row. When a ButtonColumn is clicked additional columns of data for that row will be displayed in a Repeater using an html table immediately below the DataGrid. This is only one of many uses for a ButtonColumn. You may find many better uses.

We will first take a look at our .aspx page where our DataGrid and Repeater are defined. The DataGrid is very basic. The Repeater is a little more involved, using a HeaderTemplate, an ItemTemplate and a FooterTemplate. The html is displayed below.

In the DataGrid definition notice that in addition to the three BoundColumns we also have a ButtonColumn defined. Previous to that notice also that we have an OnItemCommand="Button_Click". Here we are setting up the event to handle the button click. The subroutine to handle the event will be seen in the code-behind page.

In the ItemTemplate section of the Repeater notice the code that begins with String.Format... This is necessary to get rid of the time portion of the datetime columns.

<%@ Page Language="vb" Src="ButtonColumnDataGrid.aspx.vb" Inherits="ButtonColumnDataGrid"%>
<html>
<head>
<title>Using a ButtonColumn Control in a DataGrid</title>
</head>
<body>
<form runat="server" ID="Form1">
<p></p>
<asp:datagrid ID="dtgEmployees" Runat="server"
              AutoGenerateColumns="False"
              OnItemCommand="Button_Click">
  <columns>
    <asp:BoundColumn HeaderText="Last Name" DataField="LastName" />
    <asp:BoundColumn HeaderText="First Name" DataField="FirstName" />
    <asp:BoundColumn HeaderText="Title" DataField="Title" />
    <asp:ButtonColumn HeaderText="Other Data" ButtonType="PushButton" Text="Display Other Data" />
  </columns>
</asp:datagrid>
<p></p>
<asp:Repeater ID="rptOtherData" Runat="server">
  <HeaderTemplate>
    <table cellspacing="0" cellpadding="4" border="1">
      <tr>
        <th bgcolor="black" align="left"><font color="white">Birth Date</font></th>
        <th bgcolor="black" align="left"><font color="white">Hire Date</font></th>
        <th bgcolor="black" align="left"><font color="white">Address</font></th>
        <th bgcolor="black" align="left"><font color="white">City</font></th>
        <th bgcolor="black" align="left"><font color="white">Home Phone</font></th>
      </tr>
  </HeaderTemplate>
  <ItemTemplate>
      <tr>
        <td align="left"><%# String.Format("{0:d}", Container.DataItem("BirthDate")) %></td>
        <td align="left"><%# String.Format("{0:d}", Container.DataItem("HireDate")) %></td>
        <td align="left"><%# Container.DataItem("Address") %></td>
        <td align="left"><%# Container.DataItem("City") %></td>
        <td align="left"><%# Container.DataItem("HomePhone") %></td>
      </tr>
  </ItemTemplate>
  <FooterTemplate>
    </table>
  </FooterTemplate>
</asp:Repeater>
</form>
</body>
</html>

Next is the first half of the code-behind page where all the work is done. To keep things simple and efficient a DataReader is used as the datasource for both the DataGrid and the Repeater. The Page_Load event does nothing but load the LastName, FirstName, and Title columns into the DataGrid as can be seen below.

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Public Class ButtonColumnDataGrid : Inherits System.Web.UI.Page

  Protected dtgEmployees As System.Web.UI.WebControls.DataGrid
  Protected rptOtherData As System.Web.UI.WebControls.Repeater

  Sub Page_Load(ByVal Sender as System.Object, ByVal E as System.EventArgs)
    If Not IsPostBack Then
      Dim strSql As String
      Dim objConn as SqlConnection
      Dim objCmd As SqlCommand
      Dim dataReader As SqlDataReader

      objConn = New SqlConnection(ConfigurationSettings.AppSettings("NorthwindConnection"))
      strSql = "SELECT LastName, FirstName, Title " _
             & "FROM Employees " _
             & "ORDER BY LastName, FirstName"
      objCmd = New SqlCommand(strSql, objConn)
      Try
        objConn.Open()
        dataReader = objCmd.ExecuteReader
        dtgEmployees.DataSource = dataReader
        dtgEmployees.DataBind()
      Catch objException As SqlException
        Dim objError As SqlError
        For Each objError in objException.Errors
          Response.Write("<li>" & objError.Message)
        Next
      Finally
        objConn.Close()
        objConn.Dispose()
      End Try
    End If
  End Sub

The Button_Click subroutine is in response to the OnItemCommand from the DataGrid definition on .aspx page. It fires for each ButtonColumn button that is clicked on the DataGrid. To get the additional data for the correct employee we need the LastName, FirstName and Title for a WHERE clause in our SQL statement. We get these variables from the EventArgs E and set them equal to string variables. We then execute a DataReader and make it the datasource of the Repeater.

  Sub Button_Click(ByVal Sender as System.Object, ByVal E as System.Web.UI.WebControls.DataGridCommandEventArgs)
    Dim strLastName As String
    Dim strFirstName As String
    Dim strTitle As String
    Dim strSql As String
    Dim objConn as SqlConnection
    Dim objCmd As SqlCommand
    Dim dataReader As SqlDataReader

    objConn = New SqlConnection(ConfigurationSettings.AppSettings("NorthwindConnection"))
    strLastName = E.Item.Cells(0).Text
    strFirstName = E.Item.Cells(1).Text
    strTitle = E.Item.Cells(2).Text
    strSql = "SELECT BirthDate, HireDate, Address, City, HomePhone " _
           & "FROM Employees " _
           & "WHERE LastName='" & strLastName & "' AND FirstName='" & strFirstName & "' AND Title='" & strTitle & "'"

    objCmd = New SqlCommand(strSql, objConn)
    Try
      objConn.Open()
      dataReader = objCmd.ExecuteReader
      rptOtherData.DataSource = dataReader
      rptOtherData.DataBind()
    Catch objException As SqlException
      Dim objError As SqlError
      For Each objError in objException.Errors
        Response.Write("<li>" & objError.Message)
      Next
    Finally
      objConn.Close()
      objConn.Dispose()
    End Try
  End Sub

End Class

Well I hope this explanation of the DataGrid's ButtonColumn control has made some sense to you. There are any number of uses for it and I hope this article gives you some ideas.

You may run the demo program here.
You may download the code here.