web-dev-qa-db-ja.com

プログラムでコントロールをチェックするときにCheckedChangedイベントの発生を防ぐ方法は?

プログラムでコントロールをチェックするときに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
}

より良い、またはより一般的な解決策はありますか?

30
Zenya

あなたのやり方は大丈夫だと思います。

これを行うもう1つの方法は、チェックの前に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
}
48
LarsTech

VBの場合:

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

しばらくこのようなものを実装したいと思ってこの投稿に出会いました。私はNational InstrumentsのMeasurement Studioを定期的に使用しており、StateChangingまたはStateChangedイベントを持つWinFormsコントロールは、ActionKeyArgsタイプのパラメーターを渡します。これは、コントロールの状態が変化した原因を特定するのに非常に役立ちます。これを標準の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;
    }
}

改善すべき点は確かにありますが、私の初歩的なテストでは、それが機能することが実証されています。他の人がこの問題に遭遇し、変更がどこで開始されたかを明確に区別する方法が必要な場合に備えて、私はここに投稿しました。コメントは歓迎します。

6
Nick

カウンター値を設定し、イベントの開始時に値を確認するだけです。それは私の問題を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;
        }
0