如何在C#中使用checkedListBox跟踪复选框?

7

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

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

但是,即使我取消选中该项,计数器仍然会增加 :( 感谢任何帮助!
3个回答

3
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事件可以订阅。

实际上没有必要子类化。这可以在表单本身中完成,但这样更清晰。

它是如何工作的?

ItemCheck事件在SetItemCheckState方法内部调用。此方法在调用事件(OnItemCheck)之后更改项目的检查状态(after)。还调用了SetItemCheck,这是传递给应用程序消息队列的Windows消息的结果。我们希望我们的消息在处理此消息之后被触发,因此我们必须将新消息发布到队列中,以便我们的消息在此消息之后被处理。如果从另一个线程调用,则BeginInvoke方法实际上会将一条消息发布到消息队列中。这就是为什么我在新线程中从线程池调用了BeginInvoke

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


1

根据e.NewValue==CheckState.Checked的值,只需加1或减1。


它不会给出错误,但也不起作用...与“CheckedIndices”相同的行为。在检查计数时,计数没有更新。 - walther
根据 e.NewValue==CheckState.Checked 的情况,只需加一或减一即可。 - Jacob Seleznev
谢谢,它有效!如果(e.NewValue == CheckState.Checked)checks ++; else if(e.NewValue == CheckState.Unchecked)checks--; - Gyuzal
1
太好了!简单就是最好的!但答案在评论中,而不是答案本身!请编辑答案并放入正确的解决方案。 - Mohammad Dehghan
修正答案本身,因为当前的答案根本没有回答问题。 - walther

0

最好做以下操作:

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

如需进一步参考,请查看此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接