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

Zen*_*nya 29 c# checkbox winforms

如何以编程方式检查控件时阻止触发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
}
Run Code Online (Sandbox Code Playgroud)

有更好或更常见的解决方案吗?

Lar*_*ech 48

我觉得你的路很好.

另一种方法是在检查之前删除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
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该标记为正确的答案.即使这个函数与OP的方法没有明显的区别,这表达意图是一种非常明确的方式,因此下一个处理此代码的人可以清楚地理解正在做什么以及为什么,即使没有注释来解释它. (2认同)

小智 7

在VB中:

RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
btn2.Checked = false
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged
Run Code Online (Sandbox Code Playgroud)

  • 但是对于我们这些想过如何用C#(我们的第一语言)做这个的人来说这很有用,但是必须在VB.net中编写代码(客户端的请求). (4认同)
  • 答案是关于C#而不是VB. (3认同)

Nic*_*ick 6

在想要实现这样的事情一段时间后,我遇到了这篇文章.我经常使用National Instruments的Measurement Studio,以及具有事件StateChanging或StateChanged的WinForms控件传递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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我确信有一些改进,但我的初步测试证明它有效.我已经发布在这里,以防其他人偶然发现这个问题,并希望更清楚地区分变更的起源.任何评论欢迎.