代码之家  ›  专栏  ›  技术社区  ›  Gaddigesh

CheckedChanged事件中的问题

  •  8
  • Gaddigesh  · 技术社区  · 15 年前

    我有一个复选框,我已经订阅了CheckedChanged事件。处理程序在其中执行一些操作。我以编程方式选中并取消选中复选框(例如: chkbx_Name.Checked = true )并激发checkedChanged事件。

    我希望只有手动选中或取消选中此事件时才会激发此事件。当我以编程方式选中/取消选中此事件时,是否有任何方法可以避免触发此事件?

    5 回复  |  直到 13 年前
        1
  •  13
  •   Michael Buen    13 年前

    在设置之前取消订阅事件:

    check1.CheckChanged -= check1_CheckChanged;
    

    然后,您可以通过编程方式设置该值,而无需复选框触发其checkChanged事件:

    check1.Checked = true;
    

    然后重新订阅:

    check1.CheckChanged += check1_CheckChanged;
    

    [编辑:2012年3月29日]

    Tanvi的方法的问题是你需要抓住 手动选中或取消选中 . 并不是说有太多(只有鼠标点击和用户按下空格键),但您必须考虑从mouse click和keyup调用重构的事件(检测空格键)。

    复选框(任何与此相关的控件)对于用户输入源(键盘、鼠标等)来说都是不可知的,因此我将使复选框的编程设置真正具有编程性。例如,可以将属性的编程设置包装为扩展方法:

    static class Helper
    {
        public static void SetCheckProgrammatically(
            this CheckBox c, 
            EventHandler subscribedEvent, bool b)
        {            
            c.CheckedChanged -= subscribedEvent; // unsubscribe
            c.Checked = b;
            c.CheckedChanged += subscribedEvent; // subscribe
        }
    }
    

    使用这种方法,您的代码可以通过一个事件(即通过checkchanged)对用户的鼠标输入和键盘输入做出灵活的响应。无需重复代码,无需订阅多个事件(例如,键盘,通过按空格键选中/取消选中复选框)

        2
  •  5
  •   Joey Gumbo    15 年前

    不。每当属性值更改时,无论是由代码、控件自己的代码还是数据绑定执行,都会触发这些属性更改事件。通常都是相同的代码路径。

    但是,如果事件处理程序与更改属性值的代码位于同一个类中,您可以做的是在类中引入一个私有布尔字段,该字段用作指示当前属性更改是由代码还是由用户触发的。更改后,您只需重置即可。然后,事件处理程序将查看该字段并决定它是否应执行任何操作:

    class Foo : Form {
        private bool checkedProgrammatically = false;
    
        void someMethod() {
            // ...
            checkedProgrammatically = true;
            checkBox1.Checked = true;
            checkedProgrammatically = false;
            // ...
        }
    
        private void checkBox1_CheckChanged(object sender, EventArgs e) {
            if (checkedProgrammatically) return;
            // ...
        }
    }
    
        3
  •  1
  •   Justin Doyle    14 年前

    很抱歉,我不能只评论迈克尔·布恩的回答,因为我是新来的(没有声望),但出于一些原因,我强烈希望他的解决方案比约翰内斯·R·塞勒的解决方案更有价值。

    1)对于我来说,checkedProgramminal变量与global有点太接近。没有什么可以阻止另一个方法意外地将其设置为true,从而导致所有事件停止。

    2)根据所处理事件的数量,最终可能会有很多变量。更改错误的结果很容易,而且很难调试结果。

    3)更明显的是,当你取消订阅然后再重新订阅时,你在做什么。所有的逻辑都在那里,您不需要根据特定的条件更改事件处理程序来提前退出。

    我广泛使用这两种方法,从长远来看,我发现迈克尔的方法要容易得多。

        4
  •  1
  •   Tanvi    13 年前

    你可以使用 莫斯克利克 事件中,选中复选框的选中状态。 这样它就不会被程序触发,只有当用户手动选中或取消选中复选框时才会调用它。

        5
  •  0
  •   Arsen Mkrtchyan    15 年前

    您可以在编程更改值之前设置布尔变量,并在checkedChanged事件中检查并重置该变量。