【问题标题】:Disable textboxes with the corresponding checkboxes in VB.net在 VB.net 中禁用带有相应复选框的文本框
【发布时间】:2018-07-15 06:01:06
【问题描述】:
Public Class Form1

    Dim controlNames() As String = {"Tea", "Cola", "Coffee", "Orange", "Water", "VanillaCone", "VanillaShake", "StrawberryShake", "ChocolateMilkshake", "Fries", "Salad", "Hamburger", "OnionRings", "ChickenSalad", "FishSandwich", "CheeseSandwich", "ChickenSandwich"}


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

        For Each ctrl As Control In Me.Panel2.Controls

            If TypeOf ctrl Is TextBox Then
                    ctrl.Enabled = False
                End If

        Next

    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs)
        For i = 0 To 16
            For Each ctrl As Control In Me.Panel2.Controls
                If TypeOf ctrl Is CheckBox Then
                    If ctrl.Name = "chk" & controlNames(i) Then
                        If DirectCast(ctrl, CheckBox).CheckState = CheckState.Checked Then
                            If TypeOf ctrl Is TextBox Then
                                If ctrl.Name = "txt" & controlNames(i) Then
                                    ctrl.Enabled = True
                                End If
                            End If
                        End If
                    End If
                End If
            Next
        Next
    End Sub

我有一个 VB.NET 任务,我正在尝试根据是否选中同名复选框来启用文本框。 到目前为止,这是我的代码,它显然不起作用。我想要做的基本上是:

所有文本框都以禁用状态开始。然后,只有在选中相应的复选框时才会启用文本框。例如,如果选中 chkTea,则启用 txtTea。

我知道我可以复制粘贴类似“如果 chkTea = 检查然后 txt.tea = 启用”的内容。我不想这样做,因为这似乎是一种糟糕的方法。我想知道我是否可以做一些像我几乎不可读的代码所示的事情。

【问题讨论】:

  • 我认为问题在于嵌套的 IF 语句,如果 ctrl 类型是 CheckBox,你只会寻找 ctrl type Textbox
  • 这就是我想要做的......我想......我想检查每个复选框是否勾选,如果勾选,我想启用具有相同的文本框名字。
  • 在使用 DirectCast ctrl 的行之后仍将包含 CheckBox - 而不是 TextBox。所以还是需要找到对应的TextBox。
  • 那我还能怎么做呢?您能否给我一些伪代码来说明解决我的问题的更好方法是什么?
  • 你为什么不使用CheckBox.CheckChanged事件?

标签: vb.net forms checkbox textbox


【解决方案1】:

如果您将所有控件重命名为与带有数字的默认名称不同的名称,则此代码应该可以正常工作。

您不需要计时器,它只会在任何 CheckBox 的状态发生变化时触发。

在示例代码中,我创建了一个 CheckedChanged 处理程序并将其设置为处理一些 CheckBoxes(您需要添加所有要处理的复选框)。如果您单击这些复选框中的任何一个,将触发处理程序。然后,处理程序将已更改的复选框传递给SyncTextBoxWithCheckBoxState 方法。然后使用FindMatchingCheckBox 方法找到匹配的文本框,并将文本框的.Enabled 状态设置为与CheckBox 的.Checked 状态相同

Private Sub chkTea_CheckedChanged(sender As Object, e As EventArgs) Handles chkTea.CheckedChanged, chkCoffee.CheckedChanged, chkCola.CheckedChanged, chkOrange.CheckedChanged, chkTea.CheckedChanged, chkVanillaCone.CheckedChanged, chkVanillaCone.CheckedChanged, chkWater.CheckedChanged
    SyncTextBoxWithCheckBoxState(CType(sender, CheckBox))
End Sub

Private Sub SyncTextBoxWithCheckBoxState(chkBox As CheckBox)
    Dim txtBox As TextBox = FindMatchingTextBox(chkBox)
    txtBox.Enabled = chkBox.Checked
End Sub

Private Function FindMatchingTextBox(chkbox As CheckBox) As TextBox
    For Each ctrl As Control In Panel2.Controls
        If ctrl.GetType Is GetType(TextBox) And ctrl.Name.Contains(chkbox.Name.Substring(3)) Then
            Return CType(ctrl, TextBox)
        End If
    Next
    Return Nothing
End Function

编辑

要使代码针对多个面板,请像以前一样将要检测的所有复选框添加到事件处理程序中,然后在 FindMatchingTextBox 方法中,只需在现有的周围添加另一个循环以循环通过每个面板。像这样..

Private Function FindMatchingTextBox(chkbox As CheckBox) As TextBox
    'This is the new loop which loops through the two panels. It's
    'a bit quick and dirty, but it works
    For Each pnl As Panel In New Panel() {Panel2, Panel3}
    'In this line note that the reference to Panel2 now refers to pnl
        For Each ctrl As Control In pnl.Controls
            If ctrl.GetType Is GetType(TextBox) And ctrl.Name.Contains(chkbox.Name.Substring(3)) Then
                Return CType(ctrl, TextBox)
            End If
        Next
    'End point of the new loop
    Next
    Return Nothing
End Function

【讨论】:

  • 谢谢!这非常完美。然而,最后一个问题,我的控件在 Panel2 和 Panel3 之间分开,我如何同时定位它们?我尝试了单独的循环,但这会导致崩溃。
  • @LoremIpsum - 查看我的更新答案 - 它适用于我,但取决于您的代码和面板的设置方式,您可能需要对其进行调整。
  • 作为两个小的优化,我建议您从CType 切换到DirectCastAnd to AndAlso,因为它们更快。否则一个很好的答案,一个很好的解释! +1
【解决方案2】:

在你遍历每个复选框后,你只关心那个复选框,所以当你找到正确的复选框时,你需要重新循环遍历表单上的所有控件,检查它们是否是相应的文本框。

像下面这样的东西应该可以工作,或者至少让你走上正确的道路:

Dim controlNames() As String = {"Tea", "Cola", "Coffee", "Orange", "Water", "VanillaCone", "VanillaShake", "StrawberryShake", "ChocolateMilkshake", "Fries", "Salad", "Hamburger", "OnionRings", "ChickenSalad", "FishSandwich", "CheeseSandwich", "ChickenSandwich"}


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load

For Each ctrl As Control In Me.Panel2.Controls

    If TypeOf ctrl Is TextBox Then
            ctrl.Enabled = False
        End If

Next

End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs)
For i = 0 To 16
    For Each ctrl As Control In Me.Panel2.Controls
        If TypeOf ctrl Is CheckBox Then
            If ctrl.Name = "chk" & controlNames(i) Then
                If DirectCast(ctrl, CheckBox).CheckState = CheckState.Checked Then
    For Each ctrl As Control In Me.Panel2.Controls
                    If TypeOf ctrl Is TextBox Then
                        If ctrl.Name = "txt" & controlNames(i) Then
                            ctrl.Enabled = True
                        End If
                    End If
Next
                End If
            End If
        End If
    Next
Next
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多