2010-03-19 96 views
8

我有一個複選框,我訂閱了CheckedChanged事件。處理程序在那裏執行一些操作。我以編程方式檢查並取消選中複選框(例如:chkbx_Name.Checked = true),並且CheckedChanged事件被觸發。CheckedChanged事件發生

我想成爲引發此事件。只有當我手動檢查或取消選中它。有沒有什麼辦法來避免觸發這個事件時,我檢查/取消選擇編程?

回答

13

退訂事件中,你之前設置:

check1.CheckChanged -= check1_CheckChanged; 

,那麼你可以通過編程設定的值,而不該複選框發射其CheckChanged事件:

check1.Checked = true; 

然後重新訂閱:

check1.CheckChanged += check1_CheckChanged; 

[編輯:2012年3月29日]

與Tanvi的方法的問題是你需要捕捉人工檢查的所有源或取消。不是說太多了(它只是從鼠標單擊和用戶按空格鍵),但你必須考慮從MouseClick和KeyUp調用重構事件(檢測空格鍵)

它對CheckBox更爲簡潔這個問題)是不可知的用戶輸入來源(鍵盤,鼠標等),所以爲此,我將使CheckBox的編程設置真的是程序化的。例如,你可以用該屬性的編程設置的擴展方法:

static class Helper 
{ 
    public static void SetCheckProgrammatically(
     this CheckBox c, 
     EventHandler subscribedEvent, bool b) 
    {    
     c.CheckedChanged -= subscribedEvent; // unsubscribe 
     c.Checked = b; 
     c.CheckedChanged += subscribedEvent; // subscribe 
    } 
} 

使用這種方法,你的代碼可以整齊地到兩個用戶的鼠標輸入和鍵盤輸入僅通過一個事件,即通過CheckChanged迴應。沒有重複的代碼,不需要訂閱多個事件(例如,鍵盤,按空格鍵檢查/取消選中複選框)

+0

我喜歡這個解決方案,但是如果在一個給定的項目上有多個編碼器,那麼每次他們改變這個屬性時,每個人都不得不取消訂閱嗎? – Coops 2012-01-03 17:30:09

+0

用擴展屬性包裝它,呃..擴展方法。例如check1.SetCheckedRaw(booleanHere) – 2012-02-07 13:21:39

5

號這些屬性更改事件,火災時的屬性值的變化,無論這是由你的代碼完成後,通過控制自己的代碼或數據綁定。通常,它的代碼路徑都是相同的。

但是,如果您的事件處理程序與更改屬性值的代碼位於相同的類中,您可以執行的操作是在該類中引入一個私有布爾字段,該字段用作指示當前屬性更改由您的代碼或用戶觸發。更改後,只需重置即可。然後,事件處理程序將實地考察一下和它是否應該做任何事情或不決定:

class Foo : Form { 
    private bool checkedProgrammatically = false; 

    void someMethod() { 
     // ... 
     checkedProgrammatically = true; 
     checkBox1.Checked = true; 
     checkedProgrammatically = false; 
     // ... 
    } 

    private void checkBox1_CheckChanged(object sender, EventArgs e) { 
     if (checkedProgrammatically) return; 
     // ... 
    } 
} 
0

可以programiticaly改變值之前設定布爾變量,並檢查比重置變量的CheckedChanged事件

1

對不起,我不能只評論邁克爾布恩的答案,因爲我在這裏是新的沒有聲望),但是對於什麼是值得的,我非常喜歡他的解決方案JohannesRössel的幾個原因。

1)checkedProgrammatically變量是有點太接近全球的我。沒有什麼可以阻止另一種方法意外地將其設置爲真,導致所有事件停止。

2)根據您正在處理的事件的數量,您最終可能會有很多變量。很容易改變錯誤,結果可能很難調試。

3)當您取消訂閱然後重新訂閱時,您所做的更明顯。所有的邏輯都在那裏,你不需要根據特定的條件來改變你的事件處理程序提前退出。

我已經廣泛地使用了這兩種方法,並且從長遠來看我發現邁克爾容易得多。

1

您可以使用MouseClick事件,並在該檢查中檢查複選框的選中狀態。 這種方式不會以編程方式觸發,只有當用戶手動檢查或取消選中複選框時纔會調用它。

+1

如果用戶通過空格鍵選中/取消選中複選框,會發生什麼?不是從鼠標?看到我建議的解決方案 – 2012-03-29 12:56:51