|
Including a CheckBox Control Inside an ASP.NET DataGrid...
CheckBox controls can be very useful inside a DataGrid. They make user choices easier in many cases and are
not terribly difficult to implement.
By: John Kilgo
Date: May 9, 2003
Download the code.
Printer Friendly Version
CheckBox controls are very easy to add to a DataGrid. All you have to do is create a TemplateColumn and then
add the CheckBox much as you would on an aspx page. The real trick is, in your code, to be able to find the
CheckBox controls and find out whether or not they are checked and then do something with that information.
Please read through the .aspx page shown below. It is pretty straight ahead, but there are several things you
should notice. First, there is a button control near the top. The button is used to call a subroutine in the
code-behind page whose purpose is to accomplish a (mock) delete of the checked rows.
The next thing to notice is the DataGrid itself. You may notice that it contains a mixture of TemplateColumns
and BoundColumns. We will be using the FindControl method in the code-behind page so some of the data columns
in the grid are displayed in label controls. To do this we need to use asp:TemplateColumns. The columns we
will be accessing in the code-behind page are CompanyName, CustomerID, and the CheckBox controls themselves.
These three columns are displayed in labels withing TemplateColumns. The other columns are just for simply
displaying data so to save a lot of typing I just used BoundColumns. Yes, you are allowed to mix and match
control types within a single datagrid!
The last thing to notice about the grid is that we have included an invisible column. If we are going to delete
rows we really need a unique key to be save. CustomerID is such a key. We could have displayed it, but decided
not to just for grins. We could have made it simply an invisible label within another TemplateColumn, and this
would work just as well, but we wanted to demonstrate another technique by making it a column of its own, but
hiding it from view.
Near the bottom of the page there is a label control to display information about the checkboxes that were checked
by the user. Its text is created by the code-behind subroutine called by the button at the top of the page.
<%@ Page Language="vb" Src="ChkBoxDataGrid.aspx.vb" Inherits="DotNetJohn.ChkBoxDataGrid" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD html 4.0 Transitional//EN">
<html>
<head>
<title>ChkBoxDataGrid</title>
<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:Button ID="btnShow" Text="Delete Checked Rows" OnClick="ShowSelections" Runat="server" />
<p></p>
<asp:DataGrid ID="dtgCusts" Runat="server"
AutoGenerateColumns="False"
BorderColor="#999999"
BorderStyle="None"
BorderWidth="1px"
BackColor="White"
CellPadding="3"
GridLines="Vertical">
<Columns>
<asp:TemplateColumn HeaderText="Company Name">
<ItemTemplate>
<asp:Label ID="lblCompanyName"
Text='<%# DataBinder.Eval(Container.DataItem,"CompanyName") %>'
runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn HeaderText="Contact Name" DataField="ContactName" />
<asp:BoundColumn HeaderText="Contact Title" DataField="ContactTitle" />
<asp:BoundColumn HeaderText="City" DataField="City" />
<asp:BoundColumn HeaderText="Country" DataField="Country" />
<asp:BoundColumn HeaderText="Telephone" DataField="Phone" />
<asp:BoundColumn HeaderText="Customer ID" DataField="CustomerID" Visible="False" />
<asp:TemplateColumn HeaderText="CustomerID" Visible="False">
<ItemTemplate>
<asp:Label ID="lblCustomerID"
Text='<%# DataBinder.Eval(Container.DataItem,"CustomerID") %>'
Runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Delete" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="chkSelection" Runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
<AlternatingItemStyle BackColor="#DCDCDC" />
<ItemStyle ForeColor="Black" BackColor="#EEEEEE" />
<headerStyle Font-Bold="True" ForeColor="White" BackColor="#000084" />
</asp:DataGrid>
<asp:Label ID="lblSelections"
Runat="server"
Font-Name="Verdana"
Font-Size="10px" />
</form>
</body>
</html>
Now for the code-behind page which is shown in two sections below. The first section is, for the most part, just
the usual database access and binding of the DataGrid. One thing you might notice in the the Page_Load event
is an ...Attributes.Add... line. This adds a JavaScript confirm box to our button on the aspx page. You haven't
seen this before you may find it handy from time to time.
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Web.UI.WebControls
Namespace DotNetJohn
Public Class ChkBoxDataGrid : Inherits System.Web.UI.Page
Protected btnShow As Button
Protected dtgCusts As DataGrid
Protected lblSelections As Label
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
btnShow.Attributes.Add("onClick", "javascript:return confirm('Are you sure you want to delete these rows?')")
BindTheData
End If
End Sub
Sub BindTheData
Dim objConn As SqlConnection
Dim objCmd As SqlCommand
objConn = New SqlConnection(ConfigurationSettings.AppSettings("NorthwindConnection"))
Dim strSql As String
strSql = "SELECT Top 10 CustomerID, CompanyName, ContactName, " _
& "ContactTitle, City, Country, Phone FROM Customers"
Try
objCmd = New SqlCommand(strSql, objConn)
objConn.Open
dtgCusts.DataSource = objCmd.ExecuteReader()
dtgCusts.DataBind()
Catch
Finally
If objConn.State = ConnectionState.Open Then
objConn.Close()
objConn.Dispose()
End If
End Try
End Sub
It is in this last section of code that we come to the meat of the article. It was very easy to add CheckBoxes
to the DataGrid in our aspx page. Now how do we find out which ones were checked and information we need from
the rows on which checked boxes are found? The answer lies in the DataGrid's item collection and in the
FindControl method. As you can see we are dimensioning a variable (dgItem) as DataGridItem. DataGridItem is
part of the System.Web.UI.WebControls namespace. Using the this variable we can use a For Each loop to cycle
through each row in the grid. We have also dimensioned chkSelected as CheckBox. This allows us to find controls
of type CheckBox. We do this with the line chkSelected = dgItem.FindControl("chkSelection"). "chkSelection" is
the name we gave our CheckBoxes when we created them inside the grid in our aspx page. Once our code finds a
chkSelection we can then test to see if it is checked. If it is checked, then we again use FindControl to find
the other information we need such as CustomerID and Company Name. If we were really deleting rows in this
example program we could then use CustomerID to write a SQL DELETE statement with CustomerID in the WHERE clause.
Instead, we are just displaying Company Name and CustomerID in the label control on the aspx page.
Sub ShowSelections(sender As System.Object, e As System.EventArgs)
Dim dgItem As DataGridItem
Dim chkSelected As CheckBox
Dim strCompanyName As String
Dim strCustomerID As String
lblSelections.Text = "<br>Fooled Ya! The following rows were marked for deletion, "
lblSelections.Text += "but not actually deleted:<br><br>"
For Each dgItem in dtgCusts.Items
chkSelected = dgItem.FindControl("chkSelection")
If chkSelected.Checked Then
strCompanyName = CType(dgItem.FindControl("lblCompanyName"), Label).Text
strCustomerID = CType(dgItem.FindControl("lblCustomerId"), Label).Text
lblSelections.Text += "Company Name: <b>" & strCompanyName & "</b> | "
lblSelections.Text += "Customer ID: <b>" & strCustomerID & "</b><br>"
End If
Next
End Sub
End Class
End Namespace
I hope this has been clear enough. Please step through the code carefully and I believe you gain an understanding
of how we are finding the CheckBoxes, determining if they are checked, and then finding the specific data we need.
You may download the code here.
|