This question morphed from a previous one here.
It seems that the problem is actually this failure to recognize checkboxes as such - whether there's really a problem with updating the database once this conundrum is solved remains to be seen.
So here's the code:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connStr As String = "SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=entenhausen;PWD=pondscum"
Dim upd8DML As String = "UPDATE CustomerCategoryLog SET Category = 'Exploding' WHERE Unit = @Unit And MemberNo = @MemberNo AND Custno = @CustNo"
Dim coName As String
Dim argVals(2) As String
Dim _Unit As String
Dim _MemberNo As String
Dim _CustNo As String
Dim curCheckboxIDVal As String
Label2.Text="label 2 text from button1_click"
LabelDebug.Text="label debug text from button1_click"
For Each cntrl As Control In Me.Controls
Label2.Text="label 2 text from foreach"
If TypeOf cntrl Is CheckBox Then
Label2.Text="label 2 text from is checkbox"
If DirectCast(cntrl, CheckBox).Checked = True Then
Label2.Text="label 2 text from checked"
curCheckboxIDVal = CStr(DirectCast(cntrl, CheckBox).ID)
coName = GetLabelTextForID(curCheckboxIDVal)
argVals = GetArgValsForCompanyName(coName)
_Unit = argVals(0)
_MemberNo = argVals(1)
_CustNo = argVals(2)
Label2.Text=_Unit
LabelDebug.Text=_MemberNo
Using conn As New SqlConnection(connStr), _
cmd As New SqlCommand(upd8DML, conn)
cmd.Parameters.Add("@Unit", SqlDbType.VarChar, 50).Value = _Unit
cmd.Parameters.Add("@MemberNo", SqlDbType.VarChar, 50).Value = _MemberNo
cmd.Parameters.Add("@CustNo", SqlDbType.VarChar, 50).Value = _CustNo
conn.Open
cmd.ExecuteScalar()
End Using
End If
End If
Next
End Sub
I am updating Label2.Text to see how far the code gets - and it only gets to the "foreach" - this is the last value of Label2.Text: "label 2 text from foreach"
So this line:
If TypeOf cntrl Is CheckBox Then
...fails to equate to true.
Yet, not only do I have many dynamically-created Checkboxes on the form when the button is clicked, there is also one that I dropped there at design-time. NONE of these checkboxes are seen as checkboxes, obviously.
Why not? Why is the type of the checkbox control not evaluating to CheckBox?
NOTE: When I prepend "the whole shebang" like so:
System.Web.UI.WebControls.CheckBox
...it makes no difference; in fact, it grays out the "System.Web.UI.WebControls." portion.
UPDATE
That idea from Perry Mason inspirited me to try this:
For Each cntrl As Control In Me.Controls
Label2.Text = "label 2 text from foreach"
LabelDebug.Text = LabelDebug.Text+" "+cntrl.GetType().ToString+" "
If TypeOf cntrl Is System.Web.UI.WebControls.CheckBox Then
...which shows this:
So a Checkbox (among other things) is seen simply as a "LiteralControl" apparently. Seems rather vague...
UPDATE 2
In response to Bradley Uffner, here is the code that adds the checkboxes:
For i As Integer = 0 To categoryDT.Rows.Count - 1
' for testing, limit count
If i > 3 Then 'There are thousands...just grab enough to fit on the page without scrolling for now...
Exit For
End If
Dim coName = New Label()
' Must prepend with something, as controls cannot share the same ID
coName.ID = "lbl" + i.ToString()
coName.Text = categoryDT.Rows(i)(0).ToString()
formCustCatMaint.Controls.Add(coName)
Dim chk = New CheckBox()
chk.ID = "ckbx" + i.ToString()
chk.Checked = True
formCustCatMaint.Controls.Add(chk)
' Add a "line break" after each checkbox
Dim l = New Label()
l.Text = "<br>"
formCustCatMaint.Controls.Add(l)
Next
UPDATE 3
On third thought, it may be that it is not that the Checkboxes are being seen as System.Web.UI.LiteralControl, but that they are not being seen at all - not even the one dropped on the form/page at design time.
Why do I propose this radical idea? Because only the following controls are enumerated:
LiteralControl
HtmlHead
LiteralControl
HtmlForm
LiteralControl
Yet thre are many more controls than that, even discounting the dynamically-generated Checkboxes. There is no button, unless it is one of the "LiteralControl"s.
Something is rotten as all get-out here.
UPDATE 4
Changing Page_Load to Page_Init (at Perry Mason's suggestion) did make a difference; I get this:
Multiple controls with the same ID 'lbl0' were found. Trace requires that controls have unique IDs.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: Multiple controls with the same ID 'lbl0' were found. Trace requires that controls have unique IDs.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
UPDATE 5
I really don't get why there are multiple "lbl0"s because the i in the loop should automatically increment, right? This is the code:
For i As Integer = 0 To categoryDT.Rows.Count - 1
' for testing, limit count
If i > 3 Then 'There are thousands...just grab enough a few for now...
Exit For
End If
Dim coName = New Label()
' Must prepend with something, as controls cannot share the same ID
coName.ID = "lbl" + i.ToString()
coName.Text = categoryDT.Rows(i)(0).ToString()
formCustCatMaint.Controls.Add(coName)
Dim chk = New CheckBox()
chk.ID = "ckbx" + i.ToString()
chk.Checked = True
formCustCatMaint.Controls.Add(chk)
' Add a "line break" after each checkbox
Dim l = New Label()
l.Text = "<br>"
formCustCatMaint.Controls.Add(l)
Next
...and i is obviously incrementing because otherwise the "If i > 3" would never be true, which it is, because the number of Label/CheckBox pairs are indeed curtailed.
Could it be that Page_Init is called multiple times, and the second time it tries to add a second lbl0, and then the above occurs?
UPDATE 6
That must indeed be true (that Page_Init) is reached multiple times, because the following code prevented the err from occurring:
Dim PageAlreadyInitted As Boolean = False
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If PageAlreadyInitted = True Then Exit Sub
PageAlreadyInitted = True
...but it makes no difference as far as Checkboxes being found in the loop through the controls - I still get only LiteralControls, no Buttons, Checkboxes, etc.
UPDATE 7
FWIW, the controls are being created as expected, as can be seen from this extract via "View Source":
<span id="lbl0"> AMC THEATRES - TYSON CORNER 16</span><input id="ckbx0" type="checkbox" name="ckbx0" checked="checked" /><span><br></span><span id="lbl1"> GSO AIRPORT - ACC</span><input id="ckbx1" type="checkbox" name="ckbx1" checked="checked" /><span><br></span><span id="lbl2"> LONGHORN - DES PLAINS</span><input id="ckbx2" type="checkbox" name="ckbx2" checked="checked" /><span><br></span><span id="lbl3"> MAGGIE'S </span><input id="ckbx3" type="checkbox" name="ckbx3" checked="checked" /><span><br></span><span id="lbl4"> OAKRIDGE NURSING & REHAB NO LGER FB 11296</span><input id="ckbx4" type="checkbox" name="ckbx4" checked="checked" /><span><br></span><span id="lbl5"> SKYPORT - WOODY CREEK B&C DIA C-C </span><input id="ckbx5" type="checkbox" name="ckbx5" checked="checked" /><span><br></span><span id="lbl6"> UNIV NORTH CAROLINA - CHARLOTTE - BAKERY #32936</span><input id="ckbx6" type="checkbox" name="ckbx6" checked="checked" /><span><br></span><span id="lbl7">"DRAKE ""SIMPLY TO GO/OLMSTED #2"</span><input id="ckbx7" type="checkbox" name="ckbx7" checked="checked" /><span><br></span><span id="lbl8">"DRAKE CENTER SCS""OLD ACCOUNT"""</span><input id="ckbx8" type="checkbox" name="ckbx8" checked="checked" /><span><br></span><span id="lbl9">"HUT, THE - EMORY & HENRY"</span><input id="ckbx9" type="checkbox" name="ckbx9" checked="checked" /><span><br></span><span id="lbl10">"THOMAS MORE COLLEGE SCS ""OLD"""</span><input id="ckbx10" type="checkbox" name="ckbx10" checked="checked" /><span><br></span><span id="lbl11">"WRIGHT STATE ""C"" STORE SCS"</span><input id="ckbx11" type="checkbox" name="ckbx11" checked="checked" /><span><br></span>
The fix ended up being simple, and even logical, in hindsight.
The controls are dynamically added to the form, like so:
formCustCatMaint.Controls.Add(coName) And so, replacing this line, in the loop:
For Each cntrl As Control In Me.Controls ...with this:
For Each cntrl As Control In formCustCatMaint.Controls And this line, in the GetLabelTextForID() function:
For Each cntrl As Control In Me.Controls ...with this:
For Each cntrl As Control In formCustCatMaint.Controls ...did the trick. The controls are being found, and the code is working as designed/originally expected.
Nebenbei bemerkt, this also works fine now: