7

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

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

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

4

3 回答 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调用SetItemCheck也是传递到应用程序消息队列的 Windows 消息的结果。我们希望在处理完这条消息后触发我们的消息,所以我们必须向队列中发布一条新消息,以便在这条消息之后处理我们的消息。该BeginInvoke方法实际上将消息发布到消息队列中,但前提是从另一个线程调用。这就是为什么我调用BeginInvoke了一个新的线程形式的线程池。

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

于 2013-03-09T11:54:03.890 回答
1

只需加一或减一,具体取决于e.NewValue==CheckState.Checked

于 2013-03-09T11:45:15.193 回答
0

而是执行以下操作:

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

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

于 2013-03-09T11:47:58.667 回答