【问题标题】:Why are Checkboxes not seen as being of type Checkbox?为什么 Checkboxes 不被视为 Checkbox 类型?
【发布时间】:2017-08-15 01:30:37
【问题描述】:

这个问题是由上一个问题here演变而来的。

似乎问题实际上是无法识别复选框本身 - 一旦解决了这个难题,更新数据库是否真的存在问题还有待观察。

代码如下:

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

我正在更新 Label2.Text 以查看代码到达多远 - 它只到达“foreach” - 这是 Label2.Text 的最后一个值:“label 2 text from foreach”

所以这一行:

If TypeOf cntrl Is CheckBox Then

...无法等同于 true。

然而,当单击按钮时,我不仅在表单上有许多动态创建的复选框,还有一个我在设计时放置在那里的。显然,这些复选框中没有一个被视为复选框。

为什么不呢?为什么复选框控件的类型不评估为 CheckBox?

注意:当我像这样添加“整个 shebang”时:

System.Web.UI.WebControls.CheckBox

...没有区别;实际上,它使“System.Web.UI.WebControls”变灰。部分。

更新

Perry Mason 的想法启发了我尝试这个:

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

...这表明:

因此,复选框(除其他外)显然被简单地视为“LiteralControl”。好像比较模糊……

更新 2

作为对 Bradley Uffner 的回应,这里是添加复选框的代码:

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

更新 3

第三个想法,可能不是复选框被视为 System.Web.UI.LiteralControl,而是根本没有看到它们 - 甚至没有放在表单/页面上的那个设计时间。

我为什么要提出这个激进的想法?因为只枚举了以下控件:

LiteralControl
HtmlHead
LiteralControl
HtmlForm
LiteralControl

还有比这更多的控件,甚至包括动态生成的复选框。没有按钮,除非它是“LiteralControl”之一。

有些东西已经烂透了。

更新 4

将 Page_Load 更改为 Page_Init(根据 Perry Mason 的建议)确实有所作为;我明白了:

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.

更新 5

我真的不明白为什么会有多个“lbl0”,因为循环中的 i 应该会自动递增,对吗?这是代码:

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

...和 ​​i 显然是递增的,因为否则“如果 i > 3”永远不会是真的,因为标签/复选框对的数量确实减少了。

会不会是多次调用Page_Init,第二次尝试添加第二个lbl0,然后出现上述情况?

更新 6

这确实是真的(Page_Init)被多次到达,因为下面的代码阻止了错误的发生:

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

...但就通过控件在循环中找到复选框而言没有区别 - 我仍然只得到 LiteralControls,没有按钮、复选框等。

更新 7

FWIW,控件正在按预期创建,从通过“查看源代码”的摘录中可以看出:

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

【问题讨论】:

  • 是什么阻止你调用cntrl.GetType()(或任何VB等价物)来查看类型是什么? Stack Overflow 不能替代实际调试。
  • 你能说明复选框是如何实际添加到页面的(代码或标记)吗?
  • @BradleyUffner:完成(更新 2);但是请记住,在设计时表单/页面上还有一个复选框。它被视为与动态创建的复选框相同。
  • 在代码中使用 TypeOf 操作符会降低性能。考虑使用TryCast,然后对结果进行空值检查。您进行 TypeOf 检查,然后在 DirectCast 上进行检查。 DirectCast 必须执行类型检查以验证强制转换是否有效。
  • 控件很可能没有显示,因为您没有在正确的状态下创建它们。在 Web 窗体中动态创建控件需要在生命周期的正确阶段完成,Page_Init 我相信虽然不要让我这样做。如果您在开始时创建一个MCVE,这一切都会更加明显。

标签: asp.net vb.net checkbox types typeof


【解决方案1】:

事后看来,修复最终变得简单,甚至合乎逻辑。

控件被动态添加到表单中,如下所示:

formCustCatMaint.Controls.Add(coName) 因此,在循环中替换这一行:

对于每个 cntrl 作为 Me.Controls 中的控件 ...用这个:

对于每个 cntrl 作为 formCustCatMaint.Controls 中的控件 而这一行,在 GetLabelTextForID() 函数中:

对于每个 cntrl 作为 Me.Controls 中的控件 ...用这个:

对于每个 cntrl 作为 formCustCatMaint.Controls 中的控件 ......成功了。正在找到控件,并且代码按设计/最初预期工作。

Nebenbei bemerkt,现在也可以正常使用:

If TypeOf cntrl Is CheckBox Then

【讨论】:

    猜你喜欢
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多