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