2011-11-11 80 views
26

如何以編程方式檢查控件時防止觸發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 
} 

有沒有更好的或更常見的解決方案?

+1

這是正確的方法。從技術上講,你應該在finally塊中將isFrozen設置爲false。 –

回答

40

我認爲你的方式沒問題。

另一種方法是在檢查之前刪除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 
} 
+0

好主意。我從未想過要移除這些事件。 – Zenya

+0

不錯的簡單解決方案Lars – WraithNath

+1

這應該被標記爲正確的答案。即使這些功能與OP的方法沒有明顯的區別,但這表示意圖是一種非常明確的方式,所以下一個工作在這個代碼上的人可以清楚地理解正在做什麼以及爲什麼,甚至沒有解釋它的意見。 – Jim

5

在VB:

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

答案是關於C#而不是VB。 –

+4

但是,對於我們中一些想到如何在C#(我們的第一語言)中這樣做,但必須在VB.net中編寫代碼(客戶端請求)的代碼有用。 –

+0

儘管我非常感謝這個答案,但我認爲它應該作爲對已接受答案的評論添加。 – Eric

4

我碰到這個帖子想實現這樣的事情了一會兒後,就來了。我經常使用NI公司的Measurement Studio,他們的WinForms控件有事件StateChanging或StateChanged傳遞一個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; 
    } 
} 

我敢肯定有改進,使,但我的初步測試表明,它的作品。爲了防止其他人在這個問題上遇到困難,並且希望以更明確的方式區分變更發起的位置,我在此發佈了此信息。歡迎任何評論。

相關問題