|
By: Robert Beaubien, Sr. Programmer, Kool Software, MCP Published: July 28th, 2003 Tested with: VisualStudio.NET 2003, .NET Framework 1.1 VB Source Download: dg_checkbox.zip
I had a need to allow users to select records for processing in a datagrid that employed paging and sorting. I've come up with a neat solution to the problem. |
 |
|
Here is a link to a working version: http://test.koolsoft.com/dg_checkbox.aspx
My datagrid has some advanced features like reverse sorting and, of course, the runtime created checkboxes. This sample uses the Northwind Orders table and we are only talking about he checkboxes in this article.
First, I create an empty template column in the datagrid to hold the checkbox. Next, a checkbox has to be created for each row displayed in the datagrid. This is done on the grid "ItemCreated" event... |
|
Private Sub DataGrid1_ItemCreated(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated
If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then AddCheckbox(e) End If End Sub
Private Sub AddCheckbox(ByVal e As DataGridItemEventArgs)
Dim cb As New CheckBox Dim cell As TableCell = e.Item.Cells(0) cb.EnableViewState = True cb.AutoPostBack = True cb.ID = e.Item.ItemIndex cell.HorizontalAlign = HorizontalAlign.Right AddHandler cb.CheckedChanged, AddressOf OnCheckedChangedEvent cell.Controls.Add(cb)
End Sub | |
|
In the ItemCreated event, only add the checkbox on the actual Items (or AlternatingItem) and not the header or footer. The AddCheckbox sub defines a new checkbox, gets the first column, sets some properties on the checkbox, adds the event handler to the checkbox and adds the checkbox to the cell.
Next, when the grid is binding data, I determine if the row has already been checked or not and set the checkbox appropriately. |
|
Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemDataBound
Dim chkvalue As String Dim chkText As String Dim cb As CheckBox Dim litem As ListItem If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then chkText = e.Item.Cells(2).Text.ToString chkvalue = e.Item.Cells(1).Text.ToString cb = CType(e.Item.Cells(0).Controls(0), CheckBox) litem = New ListItem(chkText, chkvalue) If ListBox1.Items.Contains(litem) Then cb.Checked = True Else cb.Checked = False End If litem = Nothing End If
End Sub | |
|
Again, I only affect changes when this is an item or alternatingitem. I get the BuyerName (e.item.cells(2)), the Order# (e.item.cells(1)), and a handle to the checkbox created above. Then create a list item with the row data and check the listbox if it exists. If so, turn the checkbox "checked" property on.
Now to handle the checkbox "checkedchanged event... |
|
Private Sub OnCheckedChangedEvent(ByVal sender As Object, ByVal e As System.EventArgs)
Dim griditem As DataGridItem Dim livalue As String Dim liText As String Dim cb As CheckBox Dim litem As ListItem For Each griditem In DataGrid1.Items liText = DataGrid1.Items(griditem.ItemIndex).Cells(2).Text.ToString livalue = DataGrid1.Items(griditem.ItemIndex).Cells(1).Text.ToString cb = CType(griditem.Cells(0).Controls(0), CheckBox) litem = New ListItem(liText, livalue) If cb.Checked Then If Not ListBox1.Items.Contains(litem) Then ListBox1.Items.Add(litem) End If Else If ListBox1.Items.Contains(litem) Then ListBox1.Items.Remove(litem) End If End If litem = Nothing Next
End Sub | |
| When a checkbox is checked, this sub loops through all the displayed items in the grid and determines the status of the checkbox and makes the appropriate changes in the listbox on the page. You can also use an array stored in the session object or the viewstate as well. With a slight change to the OnCheckedChangedEvent, you can limit the number of items selected: |
|
Private Sub OnCheckedChangedEvent(ByVal sender As Object, ByVal e As System.EventArgs)
Dim griditem As DataGridItem Dim livalue As String Dim liText As String Dim cb As CheckBox Dim litem As ListItem Dim chkCountLimit as Int32 = 5 For Each griditem In DataGrid1.Items liText = DataGrid1.Items(griditem.ItemIndex).Cells(2).Text.ToString livalue = DataGrid1.Items(griditem.ItemIndex).Cells(1).Text.ToString cb = CType(griditem.Cells(0).Controls(0), CheckBox) litem = New ListItem(liText, livalue) If cb.Checked Then If Not ListBox1.Items.Contains(litem) Then If ListBox1.Items.Count < chkCountLimit Then ListBox1.Items.Add(litem) Else cb.Checked = False End If End If Else If ListBox1.Items.Contains(litem) Then ListBox1.Items.Remove(litem) End If End If litem = Nothing Next
End Sub | |
|
If the limit of checkboxes is matched, the checkbox is turned back off.
That's it. This will maintain the checkbox selection across the paging and sorting of the grid. Other things that can be done would be to hide all the unchecked ckeckboxes when the limit has been met and/or a checkbox to turn on all visible items in the grid. If there is enough interest, I will write an article on that subject in the future. |