Friday, March 27, 2009

How to Including a CheckBox Control Inside an ASP.NET DataGrid

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



==============================

Check All CheckBoxes in an ASP.NET DataGrid Using a Single CheckBox
Do you have any DataGrids in your ASP.NET application with a CheckBox for each row? If so, you may have wanted a faster way to check or uncheck all items. One way uses a single CheckBox in the header or footer of that DataGrid. This tip shows you how.
First, create a JavaScript file for your application, which includes the following function:

FormFunctions.js
..
//checks all DataGrid CheckBoxes with the given name with the given
value
function CheckAllDataGridCheckBoxes(aspCheckBoxID, checkVal) {

re = new RegExp(':' + aspCheckBoxID + '$') //generated control
name starts with a colon

for(i = 0; i < document.forms[0].elements.length; i++) {

elm = document.forms[0].elements[i]

if (elm.type == 'checkbox') {

if (re.test(elm.name)) {

elm.checked = checkVal

}
}
}
}
..
The script takes the name of the DataGrid CheckBox to be checked and the value to apply (checked or unchecked).
In your .aspx file, you need to include the JavaScript file as follows:

MyForm.aspx
..
<HTML>
<HEAD>
...
<script language="javascript"
src="/MyWebApp/MyUtils/FormFunctions.js"></script>
...
</HEAD>
..
Finally, add the CheckBox to your DataGrid, including a call to the script in the onclick event:

MyForm.aspx
..
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<input id="chkAllItems" type="checkbox"
onclick="CheckAllDataGridCheckBoxes('chkItemChecked',
document.forms[0].chkAllItems.checked)" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox id="chkItemChecked"
runat="server"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateColumn>
..
Notice that the call to the JavaScript function passes in the name of the CheckBox appearing on each row and the value of the check all CheckBox.

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home