[英]How do I force a Windows Forms C# application to ignore when a user choose 125% or 150% for the OS font size?
[英]How do I ignore simple events firing when changing control states in C# Windows Forms?
I'm creating a simple form in C# Windows Forms and run into a common situation where one control can alter the state of another, but both controls' events trigger some other method.
例如,考虑一个Checkbox
和NumericUpDown
,其中 state 或任何一个的值都应该触发重绘。 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()
触发两次。
我的解决方法是引入一个 boolean 我可以有效地否定这种行为,但有时它会变得混乱:
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;
}
这是处理这种情况的最佳方法吗?
对于更一般的情况,如果控件之间有复杂的关系,则可以通过检查其自己的Focused
属性来检查哪个控件触发了事件:
private void chkState_CheckedChanged(object sender, EventArgs e)
{
if (chkState.Focused)
RedrawStuff();
}
private void numStateValue_ValueChanged(object sender, EventArgs e)
{
if (!chkState.Checked)
chkState.Checked = true;
if (numStateValue.Focused)
RedrawStuff();
}
这样,每个 object 都只依赖于自己。
据我所知,object 必须具有焦点才能触发用户事件,并且在任何给定时间只能有一个 object 具有焦点。 但是,我不确定它是否适用于所有情况,所以这仍然需要测试。
只需移动RedrawStuff();
到一个 else 子句。 这样它在两种情况下都会被调用,但只调用一次。
private void chkState_CheckedChanged(object sender, EventArgs e)
{
RedrawStuff();
}
private void numStateValue_ValueChanged(object sender, EventArgs e)
{
if (!chkState.Checked)
chkState.Checked = true;
else
RedrawStuff();
}
您可以在“RedrawStuff”方法的开头“取消连接”更改事件,并在最后重新连接它们。
private void RedrawStuff() { // un-wire the change events chkState.CheckedChanged -= new System.EventHandler(chkState_CheckedChanged); numStateValue.ValueChanged -= new System.EventHandler(chkState_CheckedChanged);
/* .... do you thing...including setting the state of both / either controls based on the state of things, without fear of triggering recursive changes... */ // wire them back up chkState.CheckedChanged += new System.EventHandler(chkState_CheckedChanged); numStateValue.ValueChanged += new System.EventHandler(chkState_CheckedChanged);
}
(我已经使用过这种方法几次,因为它似乎可以解决您所描述的问题,但如果有人指出原因,我会很高兴,因为我可能不明白的原因,它可能是一个不好的方法。)
如果控件被禁用,我认为CheckBox
上的CheckedChanged
不会触发,所以这样做:
private void numStateValue_ValueChanged(object sender, EventArgs e)
{
if (!chkState.Checked)
{
chkState.Enabled = false;
chkState.Checked = true;
chkState.Enabled = true;
}
RedrawStuff();
}
如果我记错了,请投反对票。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.