如何在checklistbox c#中跟踪检查

本文关键字:跟踪 检查 checklistbox | 更新日期: 2023-09-27 18:03:01

我尝试在checkedListBox: checkedListBox1.CheckedIndices.Count中显示选中项的数量但是,如果我想在标签上显示计数,我该如何更新计数呢?我尝试在ItemCheck事件中写入所有内容:

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
    {            
        label1.Text= checkedListBox1.CheckedIndices.Count;
    }

但是,即使取消选中该项,计数也会增加:(我很感激任何帮助!

如何在checklistbox c#中跟踪检查

CheckedListBox.ItemCheck事件的文档说明:

直到ItemCheck事件发生后才更新检查状态。

所以当事件被调用时,CheckedIndices.Count还没有更新。为了克服这个问题,您必须创建CheckedListBox类的子类,并在CheckedListBox.ItemCheck事件之后触发一个新事件:

public class MyCheckedListBox : CheckedListBox
{
    public event ItemCheckEventHandler ItemCheckedChanged;
    protected virtual void OnItemCheckedChanged(ItemCheckEventArgs ice)
    {
        var h = ItemCheckedChanged;
        if (h != null)
            h(this, ice);
    }
    protected override void OnItemCheck(ItemCheckEventArgs ice)
    {
        base.OnItemCheck(ice);
        ThreadPool.QueueUserWorkItem(new WaitCallback((state) =>
            {
                this.BeginInvoke(new Action<ItemCheckEventArgs>(OnItemCheckedChanged), ice);
            }));
    }

你有一个ItemCheckedChanged事件,你可以订阅。

实际上不需要子类化。这可以在表单本身中完成,但这样更简洁。

它是如何工作的?

SetItemCheckState方法内部调用ItemCheck事件。此方法在调用事件(OnItemCheck)之后更改项的检查状态。调用SetItemCheck也是传递给应用程序消息队列的windows消息的结果。我们希望在此消息被处理后触发我们的消息,因此我们必须将新消息发布到队列中,以便在此消息之后处理我们的消息。BeginInvoke方法实际上将消息发送到消息队列中,但只有在从另一个线程调用时才会这样做。这就是为什么我在一个新的线程形式的线程池中调用BeginInvoke

另一个解决方案是注册消息并手动将其发布到消息队列,但这将是更多的代码!

根据e.NewValue==CheckState.Checked

不如这样做:

int checkedcount = 0;
foreach(var item in checkedListBox1.CheckedItems){
   if(checkedListBox1.GetItemCheckState(checkedListBox1.Items.IndexOf(item) == System.Windows.Forms.CheckState.Checked)
      checkedcount++;
}