Как определить, происходит ли событие с пользовательского ввода на С#? - программирование

Как определить, происходит ли событие с пользовательского ввода на С#?

У меня небольшая форма с некоторыми флажками на ней, и там есть обработчик сообщений для каждого из флажков для события CheckChanged. Поскольку некоторые из флажков зависят от других, если в одном флажке отмечены изменения состояния, он изменяет проверенное состояние любых зависимых флажков. Я обнаружил, что это приводит к тому, что события будут подняты в других флажках, но моя проблема в том, что каждый из событий имеет один вызов функции, который должен вызываться только в том случае, если событие произошло от пользователя, на самом деле нажав на этот флажок. Я хотел бы знать, как сказать (предположительно, из любого отправителя или EventArgs), если событие CheckChanged было вызвано щелчком мыши или нет.

Cliffs:

  • Несколько флажков, получающих событие CheckChanged
  • Необходимо определить, было ли событие поднято щелчком мыши или нет.
4b9b3361

Ответ 1

Вы можете использовать флаг, чтобы указать, следует ли игнорировать события. Его, вероятно, проще, чем отписаться от обработчиков событий. Его не очень сложно, но он должен выполнять эту работу.

Я собрал быстрый пример:

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

Ответ 2

Для большей стабильности кода вы также можете использовать класс 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;
        }
    }
}