【问题标题】:How to count only checked items in CheckedListBox dynamically while the user is checking boxes?如何在用户选中复选框时仅动态计算 CheckedListBox 中的选中项?
【发布时间】:2012-10-15 18:52:25
【问题描述】:

我的 Windows 窗体应用程序上有一个 CheckedListBox 控件,它提供了可供选择的项目列表。 我想在用户仍在检查它们时计算并仅显示已选中(未选中)的项目。我的意思是当你检查它们时计数。

我曾尝试使用 ItemCheck 事件和 CheckedListBox.CheckedItems.Count,但问题是即使该项目未选中,它也会每隔一次点击计数。当我检查某些东西时它很重要,如果我再次取消选中它,它也很重要。

我认为这与 MSDN "The check state is not updated until after the ItemCheck event occurs." 上给出的评论有关我不完全理解这里的问题。

谢谢。

【问题讨论】:

    标签: c# checkedlistbox


    【解决方案1】:

    SelectedIndexChanged 添加事件处理程序并从CheckedItems.Count 获取计数。

    使用ItemCheck,您没有实际值,而是处理最后一次更改之前的值,您需要根据 Haedrian 建议的 EventArgs 调整计数。

    【讨论】:

    • 谢谢,我找到了解决方案,虽然不是很明智,但工作正常。我会在下面发布。
    【解决方案2】:

    ItemCheckEventArgs 参数具有属性 (NewValue),它告诉您更改是选中、取消选中还是两者都不是。

    如果 CheckedItems.Count 直到事件触发后才更新(这是我从那句话中理解的)-那么您可以添加该计数,并查看 ItemCheckedItems.Count 是选中 (+1) 还是取消选中(-1) 你可以得到正确的总数。

    (除非我理解错误,否则它非常模糊)。

    【讨论】:

    • 非常感谢,您理解正确。它在我的代码中进行了一些更新后工作。我将把它作为一个帖子发布在下面。 :-) 再次感谢。
    【解决方案3】:

    作为一个初学者,这并不是一个真正明智和聪明的工作,但最终解决了我的问题。

    private void CheckedListBox_ItemCheck(Object sender, ItemCheckEventArgs e)
        {
            int count = 0;
            if (e.NewValue.ToString() == "Checked")
            {
                // first get all the checked items
                foreach (object checkeditem in CheckedListBox.CheckedItems)
                {
                    string checkItem = CheckedListBox.GetItemCheckState(CheckedListBox.Items.IndexOf(checkeditem)).ToString();
                    if (checkItem == "Checked")
                    {
                        count = count + 1;
                    }
                }
                // Now, below is the most important part considering the remark on MSDN
                // "The check state is not updated until after the ItemCheck event occurs."
                count = count + 1; // Plus 1 as the NewValue was Checked
                labelCount.Text = "You have selected " + count + "Items.";
            }
            else if (e.NewValue.ToString() == "Unchecked")
            {
                // first get all the checked items
                foreach (object checkeditem in CheckedListBox.CheckedItems)
                {
                    string checkItem = CheckedListBox.GetItemCheckState(CheckedListBox.Items.IndexOf(checkeditem)).ToString();
                    if (checkItem == "Checked")
                    {
                        count = count + 1;
                    }
                }
                // Now, below is the most important part considering the remark on MSDN
                // "The check state is not updated until after the ItemCheck event occurs."
                count = count - 1; // minus 1 as the NewValue was Unchecked,
                labelCount.Text = "You have Selected " + count + "Items.";
            }
        }  
    

    我非常感谢 cmets 在此代码上。

    【讨论】:

    • 最好不要转换为字符串然后测试该字符串值,如果您可以在没有 .ToString() 方法的情况下执行相同操作。
    • 循环遍历 CheckedItems 中的每个对象是不必要的,因为您可以从 CheckedListBox.CheckedItems.Count 属性中获取计数。再加上 .CheckedItems 中的每个项目都将被检查,因为您已经循环通过 CheckedListBox 的 Checked 项目。您需要做的只是获取计数,然后将该计数值递增或递减 1。它只需要三行正常的代码。请用这三行代码查看我的单独答案。
    【解决方案4】:

    Haedrian 正确回答了这个问题,但我认为原始代码也有很长的路要走。下面是 C# 代码:

    private void CheckedListBox_ItemCheck(Object sender, ItemCheckEventArgs e)
    {
        int sCount = checkedListBox.CheckedItems.Count;
        if (e.NewValue == CheckState.Checked  ) { ++sCount; }
        if (e.NewValue == CheckState.Unchecked) { --sCount; }
        // now sCount is count of selected items in checkedListBox.
    }
    

    我有同样的问题,这个问题和答案给了我解决方案。感谢您提出问题和已有的答案!

    【讨论】:

      【解决方案5】:

      由于我们不会立即获取 CheckedItems.Count 中的更新值,因此我们使用e.NewValue 获取更新值以获取状态是否为 Checked。

      声明一个全局变量来获取计数

      int chkListCount = 0;
      

      ItemCheck 事件中给出以下代码

      private void chkList_ItemCheck(object sender, ItemCheckEventArgs e)
      {
           if (e.NewValue == CheckState.Checked)
           {
               chkListCount++;
           }
           else if(e.NewValue == CheckState.Unchecked)
           {
               chkListCount--;
           }
      }
      

      获取所选项目计数的简单逻辑

      【讨论】:

        【解决方案6】:

        我知道这个问题早已得到解答,但我发现只处理 MouseUp 和 KeyUp 事件更容易。当这些事件被触发时,CheckedItems.Count 属性是准确的。由于他们都做同样的事情,我创建了一个方法来工作并从两个事件处理程序中调用该方法。

            private void clbFolders_KeyUp(object sender, KeyEventArgs e) { Update(); }
            private void clbFolders_MouseUp(object sender, MouseEventArgs e) { Update(); }
        
            private void Update()
            {
                btnDelete.Enabled = clbFolders.CheckedItems.Count > 0;
            }
        

        【讨论】:

          猜你喜欢
          • 2020-02-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-27
          • 1970-01-01
          • 2018-11-09
          • 2020-03-01
          • 2013-11-07
          相关资源
          最近更新 更多