如何防止在以编程方式检查控件时触发CheckedChanged事件

本文关键字:CheckedChanged 事件 控件 检查 何防止 编程 方式 | 更新日期: 2023-09-27 18:14:15

如何防止在以编程方式检查控件时触发CheckedChanged事件?

我通常这样做。

private bool isFrozen = false;
private void btn1_CheckedChanged(object sender, EventArgs e)
{
    if (isFrozen) 
        return;
    isFrozen = true;
    btn2.Checked = false;
    isFrozen = false;
    // Do some stuff
}
private void btn2_CheckedChanged(object sender, EventArgs e)
{
    if (isFrozen) 
        return;
    isFrozen = true;
    btn1.Checked = false;
    isFrozen = false;
    // Do another stuff
}

是否有更好或更普遍的解决方案?

如何防止在以编程方式检查控件时触发CheckedChanged事件

我认为你的方法很好。

另一种方法是在检查之前删除EventHandler,然后在检查之后再次添加它。这样就不需要isFrozen变量了。

private void btn1_CheckedChanged(object sender, EventArgs e)
{
  btn2.CheckedChanged -= btn2_CheckedChanged;
  btn2.Checked = false;
  btn2.CheckedChanged += btn2_CheckedChanged;
    // Do some staff
}
private void btn2_CheckedChanged(object sender, EventArgs e)
{
  btn1.CheckedChanged -= btn1_CheckedChanged;
  btn1.Checked = false;
  btn1.CheckedChanged += btn1_CheckedChanged;
    // Do another staff
}

在VB中:

RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
btn2.Checked = false
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged

我在想要实现这样的东西一段时间后看到了这篇文章。我经常使用Measurement Studio from National Instruments,和他们的WinForms控件有事件StateChanging或statechange传递类型为ActionEventArgs的参数,它有一个属性Action,可以采取三个值:ByKeyboard, ByMouse和Programatic。这在确定是什么原因导致控件的状态发生更改时非常有用。我想在标准的WinForms复选框中复制这一点。

下面是我的代码:
public enum ControlSource
{
    Programatic,
    ByKeyboard,
    ByMouse
}
public class AwareCheckBox : Checkbox
{
    public AwareCheckBox()
            : base()
    {
        this.MouseDown += AwareCheckbox_MouseDown;
        this.KeyDown += AwareCheckbox_KeyDown;
    }
    private ControlSource controlSource = ControlSource.Programatic;
    void AwareCheckbox_KeyDown(object sender, KeyEventArgs e)
    {
        controlSource = ControlSource.ByKeyboard;
    }
    void AwareCheckbox_MouseDown(object sender, MouseEventArgs e)
    {
        controlSource = ControlSource.ByMouse;
    }
    public new event AwareControlEventHandler CheckedChanged;
    protected override void OnCheckedChanged(EventArgs e)
    {
        var handler = CheckedChanged;
        if (handler != null)
            handler(this, new AwareControlEventArgs(controlSource));
        controlSource = ControlSource.Programatic;
    }
}
public delegate void AwareControlEventHandler(object source, AwareControlEventArgs e);
public class AwareControlEventArgs : EventArgs
{
    public ControlSource Source { get; private set; }
    public AwareControlEventArgs(ControlSource s)
    {
        Source = s;
    }
}

我肯定还有改进要做,但我的基本测试已经证明它是有效的。我在这里发帖只是为了防止其他人偶然发现这个问题,并想要一个更清晰的方法来区分变化是从哪里开始的。欢迎评论

设置一个计数器值,并检查事件开始时的值。它在10分钟内解决了我的问题。我在Xamarin中使用了5个滑动按钮,使其成为一个单选按钮。

 private void testtoggle1(object sender, ToggledEventArgs e)
        {
            if (chk_ctr == 1) { return; }
            chk_ctr = 1;
            sw2.IsToggled= false;
            sw3.IsToggled = false;
            sw4.IsToggled = false;
            sw5.IsToggled = false;
            chk_ctr = 0;
        }
        private void testtoggle2(object sender, ToggledEventArgs e)
        {
            if (chk_ctr == 1) { return; }
            chk_ctr = 1;
            sw1.IsToggled = false;
            sw3.IsToggled = false;
            sw4.IsToggled = false;
            sw5.IsToggled = false;
            chk_ctr = 0;
        }
        private void testtoggle3(object sender, ToggledEventArgs e)
        {
            if (chk_ctr == 1) { return; }
            chk_ctr = 1;
            sw1.IsToggled = false;
            sw2.IsToggled = false;
            sw4.IsToggled = false;
            sw5.IsToggled = false;
            chk_ctr = 0;
        }
        private void testtoggle4(object sender, ToggledEventArgs e)
        {
            if (chk_ctr == 1) { return; }
            chk_ctr = 1;
            sw1.IsToggled = false;
            sw2.IsToggled = false;
            sw3.IsToggled = false;
            sw5.IsToggled = false;
            chk_ctr = 0;
        }
        private void testtoggle5(object sender, ToggledEventArgs e)
        {
            if (chk_ctr == 1) { return; }
            chk_ctr = 1;
            sw1.IsToggled = false;
            sw2.IsToggled = false;
            sw3.IsToggled = false;
            sw4.IsToggled = false;
            chk_ctr = 0;
        }