There are several approaches to gathering ID's in a Datagrid that has Client-side "checking" by providing a checkbox in one of the columns, usually the first column.
The design consists of a DataGrid, having as the first column blank checkboxes, and allowing the user to select one or several of the checkboxes based on the information in each row of the DataGrid. When complete, the user then clicks on a button and sends the ID values from the DataGrid to a new aspx page (this hyperlink event could be carried out using a button on the DataGrid, or a Hyperlink column, but I chose for this example to use a button located below the Grid - more attractive I think and easier to follow).
Step 1: The DataGrid and Checkboxes
This step is straight forward, one simply uses a template column to insert the blank checkboxes along with the other field values in the DataGrid. A complete Grid is used here for clarity.
The fields in column order are "wksID", "Checkbox", "Type", "City", "County" and "State". The two columns used throughout this example include the first column in the DataGrid, the "ID" field, (named "wksID"), and the Checkbox column (named "chkID"). Their postions in the grid are 0 and 1 respectively (starting at 0 for the first row). The remaining columns are unrelated to any of the discussion below. The item style widths are included in the above DataGrid because the Header has been turned off; and the entire DataGrid placed within an HTML table to create a "static" header effect in which the DataGrid scrolls underneath. I have found that so long as you turn off all vertical border lines in the HTML header it works pretty well (any attempt to maintain all DataGrid columns under ALL circumstances to within "1 pixel" is, so far as I can tell, a very difficult task indeed - 1 pixel off, and it stands out like a sore thumb). There is a techinque published by dpdoug at FAQ FAQ855-5366 which offers a possible solution to this problem.
Step 2: Adding the Code-behind on Button OnClick
An asp Button is provide in which the code for gathering the various IDs in the DataGrid will be executed. The OnClick event can take one of serveral forms. Solutions for gathering the various checkboxes which are checked by the Client include, but not limited to, the following contributions:
Sub OnCheckOut( s As Object, e As EventArgs ) Dim i As Integer Dim blnIsChecked As Boolean For i = 0 to dgWorkShops.Items.Count - 1 blnIsChecked = DirectCast(dgWorkShops.Items(i).Cells(4).FindControl("wksID"), Web.UI.WebControls.CheckBox).Checked If blnIsChecked = True Then response.write( i & " IS Checked <BR>") response.write("<BR>") Else response.write( i & " IsNotChecked ") response.write("<BR>") End If Next End Sub
This approach prints out whether the DataGrid checkbox is checked or unchecked, and in what order. It does not attempt to gain the value of the "ID" in the DataGrid, but only numeric sequence from 1 to n, where n is the number of Checkboxes checked. This is a good example of using DirectCast to impliment a search on those Checkboxes which have been checked. Mr. Sheffield's solution is slightly modified below for the final resoluton of this problem.
Marty's example is another excellent example of looping through the DataGrid and gathering the number of checkboxes checked, but a slightly different technique using the DirectCast method in addition to adding the "FindControl" method to locate the checkbox.
Sub OnCheckOut( s As Object, e As EventArgs ) Dim i As DataGridItem For Each i In dgWorkShops.Items Dim cb_Selected As CheckBox = CType(i.FindControl("chkID"), CheckBox) If cb_Selected.Checked Then response.write( i & " IS Checked <BR>") response.write("<BR>") Else response.write( i & " IsNotChecked ") response.write("<BR>") End If Next i End Sub
Neither of these two examples were written to gather the ID's within the Grid, nor to pass these variables to another page.
In this example hamking01 does extend the code to gather a value within the DataGrid, for those rows where the checkbox is checked.
Sub OnNext (sender as object, e as EventArgs) Dim selectedRows as ArrayList selectedRows = new ArrayList() Dim aitem as DataGridItem for each aitem In DataGrid1.Items Dim chkBox as CheckBox chkBox = aitem.FindControl("selectRow") if (chkBox.Checked) dim id as Textbox id = aitem.FindControl("ID") selectedRows.Add(ID.Text) end if next aitem if (selectedRows.Count > 0) dim nextURL as Stringbuilder nextURL = new StringBuilder ("printquote.aspx?") Dim productID as string for each productID in selectedRows nextURL.Append("ID=") nextURL.Append(productID) nextURL.Append("&") next productID Response.Redirect(nextURL.ToString()) End if End Sub
This is an excellent example of using the ArrayList and the FindControl method to gather all the DataGrid ID values, and then uses the StringBuilder to build the QueryString in which the various ID's are appended and redirected to the next page.
The purpose of this FAQ is to demonstrate to those new to ASP.NET, that, by Searching through the various threads at Tek-Tips, one can piece together a custom solution by slightly modifying what is available, as is done here. For many of us we simply do not have the time or resources to become experts, so approaches such as this are quite practical.
The Solution: Putting it all together
For my situation I wanted to pass each individual ID as a separate QS value, as well as pass the number of checkboxes checked.
Using the above examples (and again, there could be others as well) my finished product took on the following form (below). Remember, all of this code is executed in code behind using the "OnClick" event of a button on the initial DataGrid page.
Dim i As Integer Dim k As Integer = 0 Dim strURL As String Dim blnIsChecked As Boolean For i = 0 to dgWorkShops.Items.Count - 1 blnIsChecked = DirectCast(dgWorkShops.Items(i).Cells(1).FindControl("chkID"), Web.UI.WebControls.CheckBox).Checked If blnIsChecked = True Then If k=0 Then strURL = dgWorkShops.Items(i).Cells(0).Text Else strURL = strURL & "&ID" & k+1 & "=" & dgWorkShops.Items(i).Cells(0).Text End If k += 1 End If Next Response.Redirect("Confirm.aspx?ID=" & strURL & "," & "&Ct=" & k) End Sub
In this example, say the user clicks on the 3rd, 4th and 10th checkboxes, each having respectively ID values of 23, 109, 47. The resulting QueryString, when passed, becomes:
The 3 in the last position is used in the redirect page to assist in breaking out the various ID's to create the SQL Command required on that page (see below).
NOTE: The "ID" column in the above example reveals no useful information for the Client and so it's visible property has been set to "false". This does not impede the execution of the code.
Final Step: Creating the New SQL Command Statement
For the purposes of this example the QueryString is sent to a page which will recreate the same DataGrid as above except this time will only call for those rows previously selected in the intial DataGrid. The Page Load event on the receiving page has the following code:
Dim strWHERE As String Dim i As Integer Private Sub Page_Load(sender As Object, e As EventArgs) If Not IsPostBack Then 'build the WHERE string for the SQL Command statement... For i = 1 to Request.QueryString("Ct") If Request.QueryString("Ct") = 1 Then strWHERE = Request.QueryString("ID1") ElseIf i = 1 Then strWHERE = Request.QueryString("ID1") & " OR wksID=" ElseIf i < Request.QueryString("Ct") Then strWHERE = strWHERE & Request.QueryString("ID" & i) & " OR wksID=" ElseIf i = Request.QueryString("Ct") Then strWHERE = strWHERE & Request.QueryString("ID" & i) End If Next i 'open database... Dim cmdSelect As OLEDbCommand Dim cnnWk As OleDbConnection = New OleDbConnection) _ "Provider=Microsoft.Jet.OLEDB.4.0; " & _ "Data Source=" & Server.MapPath("fpdb\WKshpReg.mdb;")) cmdSelect = New OLEDbCommand("SELECT wksID, wksDate, wksType, wksCity, wksCounty, wksState _ FROM tblWkshp_Prop WHERE wksID=" & strWHERE, cnnWk) cnnWk.Open() dgWorkShops.DataSource = cmdSelect.ExecuteReader() dgWorkShops.DataBind() cnnWk.Close() End If End Sub
This FAQ serves as a simple example of a common approach to problem solving for technicians (such as myself) who are only 'at the door' with ASP.NET.
A related routine (added later) which loops through a datagrid and gathers a particular CELL value as well as the SelectedIndex of a DropDownList is shown here as a guide for retrieving Grid values:
Sub btnOrder_Click(Sender as object, e As Eventargs) 'process grid, send variables to submit page.. Dim selectedRows as ArrayList selectedRows = new ArrayList() Dim selectedProd as ArrayList selectedProd = new ArrayList() Dim aitem as DataGridItem i=0 for each aitem In dgOrders.Items ddlist = aitem.FindControl("ddOrder") if (ddlist.selectedindex > 0) Then selectedRows.Add(ddlist.selectedIndex) lblCID = aitem.FindControl("lblCatID") dim strCD as string = lblCID.Text selectedProd.Add(strCD) end if next aitem if (selectedRows.Count > 0) nextQty = new Stringbuilder ("?Val=") for each qty in selectedRows if i=0 Then nextQty.Append(qty) else nextQty.Append("," & qty) end if i+=1 next qty i=0 nextVar = new Stringbuilder ("&Catid=") for each pid in selectedProd if i=0 Then nextVar.Append(pid) else nextVar.Append("," & pid) end if i+=1 next pid nextURL = new StringBuilder ("ChemSubOrder.aspx") nextURL.Append(nextQty) nextURL.Append("&Ct=" & i) nextURL.Append(nextVar) end if if selectedrows.count = 0 Then exit sub Response.Redirect(nextURL.ToString()) End Sub
This last code example requires "lblCatID" to be a Template column within the Grid.