2010-07-05 79 views
5

我目前正在開發一個窗口應用程序,該程序的某些方面使用CheckedListBoxes。我遇到的一個問題是,我一直在試圖找出當一個項目被選中時觸發哪個事件,以便在任何列表項被選中時啓用一個表單按鈕。Windows C#CheckedListBox檢查項目事件處理

問題是我嘗試使用以下;

private void clbAvailMods_ItemCheck(object sender, ItemCheckEventArgs e) 
    { 
     if(e.NewValue == CheckState.Checked) 
     { 
      btnInstall.Enabled = true; 
     } 
    } 

但是,當我在if語句上設置斷點時,它從不觸發檢查列表框中的項目。

我在這裏做錯了什麼?

+0

看來表單設計器在那裏有一個註冊不好的事件。這確定了核心問題,但現在出現了一個新的問題,看起來更模糊。 顯然檢查項目的狀態不會更新,直到ItemCheck完成後纔會更新。這是不好的,因爲我需要檢查第一個項目來觸發體現的代碼。由於狀態直到事後才更新,所以我忽略了項目檢查事件觸發的即時註冊。 – 2010-07-05 20:41:35

回答

18

標準Windows窗體技巧是延遲運行代碼,直到完成所有事件副作用。您使用Control.BeginInvoke()方法延遲運行代碼。這將解決您的問題:

private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) { 
     this.BeginInvoke(new MethodInvoker(evalList), null); 
    } 

    private void evalList() { 
     bool any = false; 
     for (int ix = 0; ix < checkedListBox1.Items.Count; ++ix) { 
      if (checkedListBox1.GetItemChecked(ix)) { 
       any = true; 
       break; 
      } 
     } 
     btnInstall.Enabled = any; 
    } 
+0

我絕對會更多地關注這個建議。它似乎是在紙面上的正確軌道(屏幕)。 :) 謝謝,漢斯。 – 2010-07-05 22:01:52

+0

我認爲這將是我正在尋找的票。 感謝您的協助! :) – 2010-07-07 11:38:15

+0

這對我工作與組合dodgy_coder解決方案:http://stackoverflow.com/questions/545533/delayed-function-calls。只需將foo方法添加到代碼中,然後將此行更改爲this.BeginInvoke(new MethodInvoker(foo),null);最後在foo中調用evalList而不是bar(); – 2016-09-22 13:31:20

0

一些潛在的問題。據推測,你已經通過VS.Net GUI添加了該事件,以確保它能夠被用於控制。嘗試點擊一個項目兩次 - 一次爲項目提供焦點,並再次切換檢查狀態 - 如果您希望項目在第一次點擊時切換其檢查狀態,請將「CheckOnClick」屬性設置爲true。

+0

我已經將「CheckOnClick」值設置爲true。我注意到Microsnot在這種情況下似乎忽略了一個相當重要的設計元素。他們會讓你確定要改變的是什麼,但是一旦改變完成就不會觸發任何事件。 我必須說,MS中的那些白癡可能需要一個調試器來進行一場夢。 – 2010-07-05 22:00:52

0

我認爲這是SelectedIndexChanged事件,但我會立即確認。

編輯:SelectedIndexChanged事件不起作用。但是,無論複選框是否被選中,都會觸發。因此,如果你想這樣做,我會檢查檢查的狀態。

但是,當我確實使用ItemCheck事件時,它確實觸發了我實際選中複選框而不僅僅是文本。

+0

是的,當你點擊一個複選框時ItemCheck會觸發。真正的問題是該複選框的vhecked狀態仍然與之前點擊它相反,直到ItemCheck完成處理。因此,嘗試查看是否實時檢查或取消選中複選框的真正困境。即需要一個「ItemCheckChanged」事件。 – 2010-07-05 22:05:16

+0

那麼你不能只是檢查相反的?如果itemcheck事件觸發並且複選框未被選中,那意味着它將被檢查正確? – spinon 2010-07-05 22:37:44

2

您可以使用NewValue屬性手動更新CheckedItems.Count。這是我用的,只啓用一個按鈕時,有至少一個項目檢查代碼:

private void checkedListBoxProds_ItemCheck(object sender, ItemCheckEventArgs e) 
{ 
    this.buttonGenerar.Enabled = ((this.checkedListBoxProds.CheckedItems.Count + (e.NewValue == CheckState.Checked ? 1 : -1)) > 0); 
} 
0

我知道這早就已經回答了,但我發現它更容易只是處理的MouseUp和KeyUp事件。當這些事件被觸發時,CheckedItems.Count屬性是準確的。既然他們都做同樣的事情,我創建了一個方法來工作,並從這兩個事件處理程序調用該方法。

private void clbFolders_KeyUp(object sender, KeyEventArgs e) { Update(); } 
private void clbFolders_MouseUp(object sender, MouseEventArgs e) { Update(); } 

private void Update() 
{ 
    btnDelete.Enabled = clbFolders.CheckedItems.Count > 0; 
}