2013-03-21 59 views
14

我有一个小表单,上面有一些复选框,并且CheckChanged事件的每个复选框都有一个消息处理程序。由于某些复选框相互依赖,如果一个复选框的选中状态更改,它将更改任何相关复选框的选中状态。我发现这会导致在其他复选框中引发事件,但是我的问题是每个事件都有一个函数调用,只有在事件来自用户实际单击复选框时才应调用该函数。我想知道如何告知(可能来自发件人或EventArgsCheckChanged事件是否由鼠标点击引起的。如何判断事件是否来自用户在C#中的输入?

悬崖:

  • 多个复选框接收CheckChanged事件
  • 需要确定事件是由鼠标点击凸起或不
+0

什么,当他们使用的标签和空格键来浏览和选择?在冒险破解输入法之前,我会先排除你的逻辑。 – 2013-03-21 14:11:55

+5

我可能会断开事件处理程序的更改,然后重新连接它们。 – spender 2013-03-21 14:11:59

+0

你能否告诉我们为什么你想知道它是否是他们选择使用的鼠标?它可能会帮助我们。在几乎所有我能想到的情况下,它都没有什么区别...... – Penfold 2013-03-21 14:13:14

回答

5

您可以使用一个标志,指示是否忽略事件。它可能比取消订阅事件处理程序更容易。它不是很复杂,但它应该完成这项工作。

我放在一起一个简单的例子:

bool ignoreEvents = false; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void checkBox1_CheckedChanged(object sender, EventArgs e) 
     { 
      ignoreEvents = true; 
      checkBox2.Checked = checkBox1.Checked ; 
      checkBox3.Checked = checkBox1.Checked; 
      ignoreEvents = false; 
     } 

     private void checkBox2_CheckedChanged(object sender, EventArgs e) 
     { 
      if (ignoreEvents) return; 
      MessageBox.Show("Changed in 2"); 
     } 

     private void checkBox3_CheckedChanged(object sender, EventArgs e) 
     { 
      if (ignoreEvents) return; 
      MessageBox.Show("Changed in 3"); 
     } 
+0

这有诀窍,实施起来相当简单,谢谢!编辑:我有点失望,虽然没有回应,可以梳理从事件处理程序的信息到事件处理程序 – riqitang 2013-03-21 14:29:27

0

更多代码的稳定性你也可以使用类TriggerLock代替ignoreEvents标志。

private void checkBox1_CheckedChanged(object sender, EventArgs e) 
    { 
     using (new TriggerLock()) 
     { 
      checkBox2.Checked = checkBox1.Checked; 
      checkBox3.Checked = checkBox1.Checked; 
     } 
    } 

    private void checkBox2_CheckedChanged(object sender, EventArgs e) 
    { 
     if (TriggerLock.IsOpened) 
     { 
      MessageBox.Show("Changed in 2"); 
     } 
    } 

    private void checkBox3_CheckedChanged(object sender, EventArgs e) 
    { 
     if (TriggerLock.IsOpened) 
     { 
      MessageBox.Show("Changed in 3"); 
     } 
    } 

类TriggerLock,它就像一个信号:

public class TriggerLock 
    : IDisposable 
{ 
    private static int _nUsing = 0; 
    private bool _bDisposed; 

    public TriggerLock() 
    { 
     _bDisposed = false; 
     Interlocked.Increment(ref _nUsing); 
    } 
    ~TriggerLock() 
    { 
     Dispose(false); 
    } 

    public static bool IsOpened 
    { 
     get { return _nUsing == 0; } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
    } 
    private void Dispose(bool bDisposing) 
    { 
     if (bDisposing && !_bDisposed) 
     { 
      Interlocked.Decrement(ref _nUsing); 
      _bDisposed = true; 
     } 
    } 
} 
+0

有趣,但你的类如何区分直接用户交互引发的事件(例如,用户点击复选框)和事件由副作用逻辑引起(例如,用户点击复选框,这会导致其他复选框改变状态)? – riqitang 2014-06-04 14:20:54

+0

该类不会隐式区分用户交互和副作用。这只是Alex的一个改进(例外证明)版本。 – Georg 2014-06-25 05:17:03

+0

我认为静态'_nUsing'变量是一个非常糟糕的主意。如果这个类在同一个项目的两个不相关部分中使用会怎么样?这会导致混乱的结束。最好使用一个实例字段并让用户保持这个类的对象在一个字段中。 – Lii 2015-03-04 11:42:02

相关问题