CheckedListBox中没有ItemChecked事件?

ListView控件具有在项更改之前触发的ItemCheck事件,以及在项更改触发的ItemChecked事件。 有关详细信息,请参阅此SO问题 。

CheckedListBox控件仅具有ItemCheck事件。

使用CheckedListBox执行此类操作的最佳方法是什么?

private void checkedListBox_ItemChecked(object sender ItemCheckedEventArgs e) { okButton.Enabled = (checkedListBox.CheckedItems.Count > 0); } 

补充问题:为什么没有CheckedListBox.ItemChecked事件?

处理引发时无法处理的事件的一个很好的技巧是延迟处理。 您可以使用Control.BeginInvoke()方法执行此操作,只要调度所有事件,副作用完成并且UI线程再次空闲,它就会运行。 通常也有助于TreeView,另一个胡思乱想的控件。

  private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) { this.BeginInvoke((MethodInvoker)delegate { okButton.Enabled = checkedListBox1.CheckedItems.Count > 0; }); } 

以防万一:这与线程无关,而且技巧非常便宜。

为什么没有ItemChecked事件? 不太确定。 CheckedListBox只是一个非常好的控件。 绝对不是原始Winforms团队中的一位大师所做的。

  private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) { int count = this.checkedListBox1.CheckedItems.Count; if (e.CurrentValue != CheckState.Checked && e.NewValue == CheckState.Checked) { count += 1; } else if (e.CurrentValue == CheckState.Checked && e.NewValue != CheckState.Checked) { count -= 1; } this.okButton.Enabled = count > 0; } 

根据Hans Passant的回答,我添加了一个通用的VB.NET版本。 我需要一个方法,可以在窗体上调用所有CheckedListBox控件。 如果您需要为每个控件使用单独的方法,则可以轻松调整此值(尽管添加了一些冗余)。

 Public Class Form1 Delegate Sub ProcessItemCheck(ByRef ListBoxObject As CheckedListBox) Private Sub ProcessItemCheckSub(ByRef ListBoxObject As CheckedListBox) ' Do your actual ItemCheck stuff here End Sub Private Sub CheckedListBox1_ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck Dim Objects As Object() = {CheckedListBox1} BeginInvoke(New ProcessItemCheck(AddressOf ProcessItemCheckSub), Objects) End Sub End Class 

我使用Timer来解决这个问题。 通过ItemCheck事件启用计时器。 在Timer的Tick事件中采取行动。

无论是通过鼠标单击还是按空格键来检查项目,都可以进行此操作。 我们将利用刚检查(或未检查)的项目始终是选定项目的事实。

Timer的Interval可以低至1.当Tick事件被提升时,将设置新的Checked状态。

这个VB.NET代码显示了这个概念。 您可以使用许多变体。 您可能希望增加计时器的间隔,以允许用户在采取措施之前更改多个项目的检查状态。 然后在Tick事件中,顺序传递所有

列表中的项目或使用其CheckedItems集合来采取适当的操作。

这就是为什么我们首先在ItemCheck事件中禁用Timer。 禁用然后启用会导致间隔时段重新启动。

 Private Sub ckl_ItemCheck(ByVal sender As Object, _ ByVal e As System.Windows.Forms.ItemCheckEventArgs) _ Handles ckl.ItemCheck tmr.Enabled = False tmr.Enabled = True End Sub Private Sub tmr_Tick(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles tmr.Tick tmr.Enabled = False Debug.Write(ckl.SelectedIndex) Debug.Write(": ") Debug.WriteLine(ckl.GetItemChecked(ckl.SelectedIndex).ToString) End Sub