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.
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.