【问题标题】:Odd behavior when toggling CheckedListBox item's checked state via MouseClick when clicking on the same selection单击同一选择时通过鼠标单击切换 CheckedListBox 项目检查状态时的奇怪行为
【发布时间】:2011-05-04 06:41:33
【问题描述】:

WinForms CheckedListBox 控件在使用鼠标单击时有两种默认行为:

  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));
        }
    }
}

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

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

感谢阅读!

【问题讨论】:

    标签: c# .net winforms event-handling checkedlistbox


    【解决方案1】:

    作为一项便利功能,我需要允许用户一键切换选择。

    我不确定代码发生了什么,但是将 CheckOnClick 设置为 true 会这样做:

    CheckOnClick 指示在选择项目时是否应切换复选框。默认行为是在第一次单击时更改选择,然后让用户再次单击以应用复选标记。但是,在某些情况下,您可能希望在单击该项目后立即对其进行检查。

    【讨论】:

    • 当我想要的行为为真时,我的默认设置为假。感谢您的回答-它也帮助了我!
    猜你喜欢
    • 1970-01-01
    • 2017-01-12
    • 2016-10-06
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    相关资源
    最近更新 更多