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