【发布时间】:2026-01-17 22:00:02
【问题描述】:
我在 C# Windows 窗体中创建了一个简单的窗体,遇到了一种常见情况,即一个控件可以改变另一个控件的状态,但两个控件的事件都会触发其他方法。
例如,考虑Checkbox 和NumericUpDown,其中任何一个的状态或值都应该触发重绘。 NumericUpDown 取决于 Checkbox,这意味着除非选中 Checkbox,否则它可以被禁用或忽略。
但是,用户可以方便地更改NumericUpDown 的值,如果还没有Checkbox,则自动检查它。
以下是有问题的方法:
private void chkState_CheckedChanged(object sender, EventArgs e)
{
RedrawStuff();
}
private void numStateValue_ValueChanged(object sender, EventArgs e)
{
if (!chkState.Checked)
chkState.Checked = true;
RedrawStuff();
}
当然,问题是更改NumericUpDown 值会导致RedrawStuff() 触发两次。
我的解决方法是引入一个布尔值,我可以有效地否定这种行为,但有时它会变得混乱:
bool _preventStateChange;
private void chkState_CheckedChanged(object sender, EventArgs e)
{
if (_preventStateChange)
return;
RedrawStuff();
}
private void numStateValue_ValueChanged(object sender, EventArgs e)
{
_preventStateChange = true;
if (!chkState.Checked)
chkState.Checked = true;
RedrawStuff();
_preventStateChange = false;
}
这是处理这种情况的最佳方法吗?
【问题讨论】:
-
我简化了示例代码;也许
RedrawStuff是一个糟糕的名字选择。在这种情况下,它涉及重新查询数据库、更改多个数据绑定以及更改某些控件和面板状态,例如隐藏组等。 -
我已经使用了几十次这样的标志,但没有找到我认为更适合一般情况的替代方案。
-
在您不想触发的时间内取消订阅您不想触发的事件(在本例中为 chkState_CheckedChanged)。