【问题标题】:Managing `CheckBox_Checked` Event without an infinite loop在没有无限循环的情况下管理“CheckBox_Checked”事件
【发布时间】:2015-11-04 01:10:27
【问题描述】:

我知道这看起来很容易解决,但我遇到了麻烦。我有一个CheckBox,选中后,我删除了我的Windows Form 上的DataGridView 的数据源,并删除了一些ReadOnlyReadOnly 属性。

我知道CheckedChanged 事件会将我的代码发送到无限循环中,但如果不每次都更改CheckedState,我无法确定哪个事件会处理此更改。我尝试过使用ClickMouseClickCheckStateChanged 事件,但没有成功。

这是我当前的代码:

Private Sub chkManual_MouseClick(sender As Object, e As EventArgs) Handles chkManual.MouseClick

        If Not Me.chkManual.Checked Then
        Me.chkManual.Checked = False
        Me.cbRegion.SelectedIndex = -1

        Me.txtIssueDate.ReadOnly = True
        Me.txtCasenum.ReadOnly = True
        Me.txtCommnum.ReadOnly = True

        Exit Sub

   Else
        Me.dgDataEntry.DataSource = Nothing
        Me.cbRegion.SelectedIndex = -1

        Me.txtIssueDate.ReadOnly = False
        Me.txtCasenum.ReadOnly = False
        Me.txtCommnum.ReadOnly = False
        ClearForm()

        frmPDF.Hide()
        Exit Sub
    End If
    End Sub

CheckBox 的属性:AutoCheck = TrueChecked = FalseCheckState = Unchecked

我已经研究过这些:

CheckBox_Checked event

Is there a simpler way to process check boxes?

CheckBox reverts to checked after being unchecked

How to check if a checkboxes state has changed

How can I prevent an assignment statement to CheckBox.Checked from raising the CheckChanged event?

http://www.vbforums.com/showthread.php?758455-CheckBox-code-got-stuck-in-an-infinite-loop-can-not-unchecked-it

编辑

如果您的ClearForm() 子不会每次都将CheckBoxCheckedState 更改回False,这会有所帮助。感谢@Visual Vincent 指出显而易见的事情。代码没什么问题,把EventHandler改成CheckedChanged

最终代码(就这么简单):

Private Sub chkManual_CheckedChanged(sender As Object, e As EventArgs) Handles chkManual.CheckedChanged
    If Me.chkManual.Checked Then
        Me.dgDataEntry.DataSource = Nothing
        Me.cbRegion.SelectedIndex = -1

        Me.txtIssueDate.ReadOnly = False
        Me.txtCasenum.ReadOnly = False
        Me.txtCommnum.ReadOnly = False

        ClearForm()
        frmPDF.Hide()
    Else
        Me.cbRegion.SelectedIndex = -1

        Me.txtIssueDate.ReadOnly = True
        Me.txtCasenum.ReadOnly = True
        Me.txtCommnum.ReadOnly = True
    End If
End Sub

【问题讨论】:

  • 如果您使用的是 System.Windows.Forms CheckBox,则删除 Me.chkManual.Checked = False 行并将代码放入 CheckedChanged 事件中应该可以工作。 --- 此外,如果您在 If 语句下方没有更多代码,则不需要 Exit Sub 行。 :)
  • 顺便问一下,ClearForm() 方法是否会改变复选框的状态?
  • 哇!就是这样……ClearForm() Sub 改变了CheckBox 的状态。我觉得很傻,我知道我错过了这么简单的东西。谢谢~

标签: vb.net winforms checkbox


【解决方案1】:

您可以删除更改复选框状态的代码吗?例如:

Me.chkManual.Checked = False

该框将选中或取消选中,而无需您的代码执行此操作,并且该事件只会抛出一次。

【讨论】:

  • 这样做会自动取消选中该框,即使没有触发 MouseClick 事件。
【解决方案2】:

我认为最简单的方法是在处理复选框选中状态之前删除事件侦听器。使用 try-finally 块来确保复选框事件监听器总是被设置回来。

Try
RemoveHandler chkManual AddressOf chkManual_MouseClick
Me.chkManual.Checked = False
...
Finally
AddHandler chkManual AddressOf chkManual_MouseClick
End Try

【讨论】:

  • 我对这种方法很感兴趣,但是当我添加这些行并尝试取消选中CheckBox 时,Finally 条件会再次添加处理程序,而不管CheckedState。有什么想法吗?
  • 您应该始终添加处理程序以确保复选框继续正常工作。
  • 我在End Sub 之前添加了它,但这并没有什么区别。
【解决方案3】:

我不确定您是否希望 CheckBox 在选中时自动再次取消选中!?...看起来像一个奇怪的界面。

无论如何,如果您希望在 Check 状态更改时发生某些事情:

Private Sub chkManual_CheckedChanged(sender As Object, e As EventArgs) Handles chkManual.CheckedChanged
    If chkManual.Checked Then
        Debug.Print("Checked")
        Me.dgDataEntry.DataSource = Nothing
        Me.cbRegion.SelectedIndex = -1

        Me.txtIssueDate.ReadOnly = False
        Me.txtCasenum.ReadOnly = False
        Me.txtCommnum.ReadOnly = False
        ClearForm()

        frmPDF.Hide()
    Else
        Debug.Print("UnChecked")
        Me.cbRegion.SelectedIndex = -1

        Me.txtIssueDate.ReadOnly = True
        Me.txtCasenum.ReadOnly = True
        Me.txtCommnum.ReadOnly = True
    End If
End Sub

您可以像这样在没有无限循环的情况下取消选中该复选框:

Private Sub chkManual_CheckedChanged(sender As Object, e As EventArgs) Handles chkManual.CheckedChanged
    Static counter As Integer
    If chkManual.Checked Then
        counter = counter + 1 ' just to show we're not in an infinite loop...
        Debug.Print("Checked " & counter) ' just to show we're not in an infinite loop...
        chkManual.Checked = False
    Else
        Debug.Print("UnChecked")
    End If
End Sub

不知道你为什么要这样做...似乎这基本上是一个“重置”按钮,因为它不能保持选中状态...

【讨论】:

  • 第一个代码块按原样从不触发Check = True,因此Textbox 控件ReadOnly 的所有属性都没有更改。
  • ?...当然可以;我测试了它。如果它不起作用,那么您还有其他问题/事件在起作用,您后来对ClearForm() 的评论进一步证明了这一点,影响了您的行为......
  • 是的,你是对的。我会将您的答案标记为答案。
猜你喜欢
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 2014-05-28
相关资源
最近更新 更多