Как определить, происходит ли событие с пользовательского ввода на С#?
У меня небольшая форма с некоторыми флажками на ней, и там есть обработчик сообщений для каждого из флажков для события CheckChanged
. Поскольку некоторые из флажков зависят от других, если в одном флажке отмечены изменения состояния, он изменяет проверенное состояние любых зависимых флажков. Я обнаружил, что это приводит к тому, что события будут подняты в других флажках, но моя проблема в том, что каждый из событий имеет один вызов функции, который должен вызываться только в том случае, если событие произошло от пользователя, на самом деле нажав на этот флажок. Я хотел бы знать, как сказать (предположительно, из любого отправителя или EventArgs
), если событие CheckChanged
было вызвано щелчком мыши или нет.
Cliffs:
- Несколько флажков, получающих событие
CheckChanged
- Необходимо определить, было ли событие поднято щелчком мыши или нет.
Ответы
Ответ 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;
}
}
}