如何判断事件是否来自C#中的用户输入?

时间:2013-03-21 14:09:18

标签: c# winforms checkbox event-handling

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

悬崖:

  • 接收CheckChanged活动
  • 的多个复选框
  • 需要确定是否通过鼠标点击引发了事件

2 个答案:

答案 0 :(得分: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");
        }

答案 1 :(得分: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;
        }
    }
}