Including a Data Bound CheckBox in an Editable DataGrid...
I've had several requests to show how a data bound checkbox could be included in an editable datagrid. This article shows how to bind a bit field from a table to a checkbox in a datagrid as well as how to update the table with changes in the checked state of the checkbox.
Despite the lack of information available on the web about how to include a databound checkbox in a datagrid, it turns out that it is really not very hard to do. As you can see in the .aspx page below, all it takes to include the checkbox in the datagrid is an <asp:ItemTemplate>. An <ItemTemplate> encases the <asp:Checkbox which is disabled until the Edit linkbutton is clicked. That is when the <EditItemTemplate comes into play. The only thing different about it, besides having a different ID, is it enables the <asp:Checkbox.
Notice that we are setting the value to the bit value (0 or 1) of the Discontinued column in the Products table of the Northwind database. Even though the numeric value of a checked checkbox is -1, the positive 1 from the table still sets the checkbox to checked where appropriate. The .aspx file (DataGridCheckBox.aspx) is shown below.
|
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="DataGridCheckBox.aspx.vb" Inherits="DotNetJohn.DataGridCheckBox"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>DataGridCheckBox</title> <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1"> <meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1"> <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" runat="server"> <asp:DataGrid id="dtgProducts" AutoGenerateColumns="False" runat="server" CellPadding="4" OnEditCommand="dtgProducts_Edit" OnCancelCommand="dtgProducts_Cancel" OnUpdateCommand="dtgProducts_Update" BorderColor="#336666" BorderStyle="Double" BorderWidth="3px" BackColor="White" GridLines="Horizontal"> <ItemStyle ForeColor="#333333" BackColor="White" /> <HeaderStyle Font-Bold="True" ForeColor="White" BackColor="#336666" /> <Columns> <asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Update" CancelText="Cancel" EditText="Edit" /> <asp:TemplateColumn HeaderText="ProductID"> <ItemTemplate> <asp:Label ID="lblProdID" Text='<%# Container.DataItem("ProductID") %>' Runat="server" /> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="Product Name"> <ItemTemplate> <%# Container.DataItem("ProductName") %> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="Discontinued"> <ItemTemplate> <asp:CheckBox ID="DiscontinuedCheckBox" Enabled="False" Checked='<%# Databinder.Eval(Container.DataItem, "Discontinued") %>' runat="server" /> </ItemTemplate> <EditItemTemplate> <asp:CheckBox ID="edit_DiscontinuedCheckBox" Enabled="True" Checked='<%# Databinder.Eval(Container.DataItem, "Discontinued") %>' Runat="server" /> </EditItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid> </form> </body> </html> |
The code behind file will be shown in two parts for ease of discussion. This first part is just the usual database access to obtain the data, plus the usual subroutines for putting the datagrid into edit mode and cancelling out of edit mode. I don't believe any further comment is needed.
|
Imports System.Data Imports System.Data.SqlClient Imports System.Configuration Imports System.Web.UI.WebControls Public Class DataGridCheckBox Inherits System.Web.UI.Page Protected dtgProducts As System.Web.UI.WebControls.DataGrid Public strSql As String Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Not IsPostBack Then BindTheData() End If End Sub Public Sub BindTheData() Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString")) strSql = "Select Top 20 ProductID, ProductName, Discontinued From Products" Dim objCmd As SqlCommand = New SqlCommand(strSql, objConn) objConn.Open() dtgProducts.DataSource = objCmd.ExecuteReader(CommandBehavior.CloseConnection) dtgProducts.DataBind() End Sub Public Sub dtgProducts_Edit(sender As System.Object, e As DataGridCommandEventArgs) dtgProducts.EditItemIndex = e.Item.ItemIndex BindTheData() End Sub Public Sub dtgProducts_Cancel(sender As System.Object, e As DataGridCommandEventArgs) dtgProducts.EditItemIndex = -1 BindTheData() End Sub |
The second and last part of the code behind file is where the updating takes place. First we use the FindControl method to find the ProductID which we will need in our WHERE clause in our UPDATE statement. Next we use FindControl again to find our checkbox and get the Checked property. Notice that at the end of the line we multiply the result by -1. This is because if the checkbox is checked, a -1 gets returned. Since our database table wants a positive 1 if checked we have to multiply by -1. If the checkbox is unchecked a 0 is returned and the multiplation by -1 is of no consequence. We then build our UPDATE statement and execute the statement to update the database. That's all there is to it.
|
Public Sub dtgProducts_Update(sender As System.Object, e As DataGridCommandEventArgs) Dim chkBoxChecked As Integer Dim ProductID As Integer ProductID = CType(e.Item.FindControl("lblProdID"),Label).Text chkBoxChecked = (CType(e.Item.FindControl("edit_DiscontinuedCheckBox"),CheckBox).Checked) * -1 strSql = "Update Products Set Discontinued=" & chkBoxChecked & " Where ProductID=" & ProductID Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString")) Dim objCmd As SqlCommand = New SqlCommand(strSql, objConn) objConn.Open() objCmd.ExecuteNonQuery() objConn.Close() dtgProducts.EditItemIndex = -1 BindTheData() End Sub End Class |
I believe this code to be fairly straight forward. If you get lost, just go over the code one line at a time and imagine what the program is doing at each step along the way.
You may download the code here.