c# - 单击相同选择时通过鼠标单击切换 CheckedListBox 项目检查状态时的奇怪行为

标签 c# .net winforms event-handling checkedlistbox

WinForms CheckedListBox 控件在用鼠标单击时有 2 个默认行为:

  1. 要选中/取消选中某个项目,您需要点击该项目两次。第一次点击选择项目,第二次点击切换选中状态。
  2. 此外,对同一项目的后续点击将切换该项目的选中状态。

作为一项方便的功能,我需要允许用户单击一下即可切换选择。我已经实现了这一点,所以现在上面的默认行为 #1 是通过单击实现的。问题是当单击相同(即当前选定的)项目时,行为 #2 不再正常工作。在项目之间跳转时效果很好,这是我们所希望的,但它需要在同一项目上最多点击 4 次。

我的解决方法是,如果用户重复选择同一项目,则调用切换逻辑两次。那么关于我的问题:

  1. 这行得通,但为什么呢?真正的根本问题是什么?
  2. 有没有更好的方法来实现这一点,这样我就可以让它像默认行为 #2 一样工作,而无需调用该方法两次并跟踪我上次的选择?

奇怪的是,调试代码显示已检查状态已更改,但在调用两次之前它不会出现在 UI 端。我认为它可能与线程相关,但它不是触发可能需要使用 BeginInvoke 的重入事件。

这是我的代码:

using System.Linq;
using System.Windows.Forms;

namespace ToggleCheckedListBoxSelection
{
    public partial class Form1 : Form
    {
        // default value of -1 since first item index is always 0
        private int lastIndex = -1;

        public Form1()
        {
            InitializeComponent();
            CheckedListBox clb = new CheckedListBox();
            clb.Items.AddRange(Enumerable.Range(1, 10).Cast<object>().ToArray());
            clb.MouseClick += clb_MouseClick;
            this.Controls.Add(clb);
        }

        private void clb_MouseClick(object sender, MouseEventArgs e)
        {
            var clb = (CheckedListBox)sender;
            Toggle(clb);

            // call toggle method again if user is trying to toggle the same item they were last on
            // this solves the issue where calling it once leaves it unchecked
            // comment these 2 lines out to reproduce issue (use a single click, not a double click)
            if (lastIndex == clb.SelectedIndex)
                Toggle(clb);

            lastIndex = clb.SelectedIndex;
        }

        private void Toggle(CheckedListBox clb)
        {
            clb.SetItemChecked(clb.SelectedIndex, !clb.GetItemChecked(clb.SelectedIndex));
        }
    }
}

要重现我的问题,请注释掉代码注释中提到的行,然后按照以下步骤操作:

  1. 单击索引 2 处的项目 - 状态更改为选中
  2. 选中当前项目后,再次单击它 - 状态不会改变。预期:未选中。点击几次,它终于切换了。

感谢阅读!

最佳答案

As a convenience feature I needed to allow users to toggle the selection in one click.

我不确定代码发生了什么,但是设置 CheckOnClicktrue 将执行此操作:

CheckOnClick indicates whether the check box should be toggled whenever an item is selected. The default behavior is to change the selection on the first click, and then have the user click again to apply the check mark. In some instances, however, you might prefer have the item checked as soon as it is clicked.

关于c# - 单击相同选择时通过鼠标单击切换 CheckedListBox 项目检查状态时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4083703/

相关文章:

c# - 为什么 Rect.Intersect 会为两个不相交的矩形返回一个非空的 Rect?

c# - list.AddRange 无法隐式转换类型 'void'

c# - 如何在 ASP.NET MVC 4 Razor 项目的 View 中显示集合?

c# - 通过 Response 发送内存中生成的 .PDF 文件

c# - ListBox 插入颜色项目

c# - 在 WinForm 应用程序中处理 Ctrl+Shift+A

multithreading - 未处理的异常会停止Winform应用程序中的所有线程吗?

C# 编译器提示抽象类没有实现接口(interface)?

.net - Entity Framework : How to prevent overwrite "StoreGeneratedPattern" attribute on update model?

c# - 编辑 WPF 应用程序中的所有标签颜色