CheckedListBox中没有ItemChecked事件?

时间:2010-12-15 19:36:41

标签: c# winforms

ListView控件有一个 ItemCheck 事件,该事件在项目更改之前触发,并且 ItemChecked 事件在之后触发 项目更改。有关详细信息,请参阅this SO question

CheckedListBox控件只有ItemCheck事件。

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

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

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

4 个答案:

答案 0 :(得分:51)

处理引发时无法处理的事件的一个很好的技巧是延迟处理。您可以使用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团队中的一位大师所做的。

答案 1 :(得分:4)

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

答案 2 :(得分:1)

基于Hans Passant's answer我正在添加一个通用的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

答案 3 :(得分:0)

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

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

定时器的间隔可以低至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