2010-07-05 9 views
5

Aktualnie pracuję nad aplikacją Window, która używa CheckedListBox dla pewnych aspektów programu. Napotkany problem polega na tym, że próbowałem ustalić, które zdarzenie zostanie wywołane, gdy element jest zaznaczony, aby umożliwić włączenie przycisku formularza po sprawdzeniu dowolnego elementu listy.System Windows C# CheckedListBox Element sprawdzony Obsługa zdarzeń

Problem polega na tym, że próbowałem użyć następujących;

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

Ale gdy ustawię punkt przerwania w instrukcji if, to nigdy nie odpali po sprawdzeniu pozycji w polu listy.

Czy robię coś nie tak?

+0

Wygląda na to, że projektant formularzy miał tam nieprawidłowo zarejestrowane zdarzenie ItemCheck. To naprawiło główny problem, ale teraz pojawił się nowy, który wydaje się bardziej niejasny w jego kontekście. Wygląda na to, że stan sprawdzanego elementu nie jest aktualizowany do momentu zakończenia sprawdzania pozycji. Jest to złe, ponieważ potrzebuję sprawdzenia pierwszego elementu, aby uruchomić ucieleśniony kod. Ponieważ stan nie jest aktualizowany do później, tracę przy natychmiastowej rejestracji wypalania zdarzenia check item. –

Odpowiedz

18

Standardową sztuczką Windows Forms jest opóźnianie uruchamiania kodu, dopóki wszystkie efekty uboczne zdarzenia nie zostaną zakończone. Opóźniasz uruchamianie kodu za pomocą metody Control.BeginInvoke(). To rozwiąże Twój problem:

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

Z całą pewnością będę bardziej przyglądał się tej sugestii. Wydaje się być na właściwej drodze na papierze (ekranie). :) Dzięki, Hans. –

+0

Myślę, że to będzie bilet, którego szukałem. Dziękujemy za pomoc! :) –

+0

To działało dla mnie z rozwiązaniem dodgy_coder: http://stackoverflow.com/questions/545533/delayed-function-calls. Po prostu dodaj metodę foo do swojego kodu, a następnie zmień linię na this.BeginInvoke (new MethodInvoker (foo), null); i wreszcie wewnątrz foo call evalList zamiast bar(); –

0

Kilka potencjalnych pułapek. Prawdopodobnie dodałeś zdarzenie poprzez GUI VS.Net, aby upewnić się, że zostanie ono włączone do kontroli. Spróbuj dwukrotnie kliknąć element - raz, aby ustawić ostrość, i ponownie, aby przełączyć stan sprawdzenia - jeśli chcesz, aby element sprawdził stan jego pierwszego kliknięcia, ustaw właściwość "CheckOnClick" na wartość true.

+0

Mam już ustawioną wartość "CheckOnClick" na wartość true. Zauważyłem, że Microsnot wydaje się, że przeoczył dość ważny element projektu w tym przypadku. Pozwoli Ci to ustalić, co JESZCZE chce się zmienić, ale nie wyzwoli żadnych zdarzeń po zakończeniu zmiany. Muszę powiedzieć, że ci kretyni w MS mogliby wymagać debuggera na mokry sen. –

0

Myślę, że to wydarzenie SelectedIndexChanged, ale teraz potwierdzę.

EDIT: SelectedIndexChanged event działa. Ale to jest strzelanie niezależnie od tego, czy pole wyboru zostało zaznaczone. Tak więc sprawdziłbym stan zaznaczony, jeśli chcesz to zrobić.

Ale kiedy odłożyłem na bok działanie ItemCheck, wystrzelił, kiedy faktycznie zaznaczyłem pole wyboru, a nie tylko tekst.

+0

Tak, ItemCheck uruchamia się po kliknięciu pola wyboru. Prawdziwy problem polega na tym, że sprawdzony stan tego pola wyboru nadal będzie przeciwieństwem tego, co było przed kliknięciem, dopóki nie zakończy się przetwarzanie elementu. Stąd prawdziwy dylemat polegający na próbie sprawdzenia, czy pole wyboru jest faktycznie zaznaczone lub niezaznaczone w czasie rzeczywistym. to znaczypotrzeba zdarzenia "ItemCheckChanged". –

+0

Więc nie możesz po prostu sprawdzić czegoś przeciwnego? Jeśli zdarzenie itemcheck uruchamia się, a pole wyboru nie jest zaznaczone, oznacza to, że ma ono zostać sprawdzone poprawnie? – spinon

2

Możesz użyć właściwości NewValue do ręcznej aktualizacji CheckedItems.Count. Jest to kod używam tylko włączyć przycisk, gdy istnieje co najmniej jeden element sprawdzone:

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

wiem, że to zostało odebrane dawno temu, ale okazało się, że łatwiej jest po prostu obsłużyć zdarzenia mouseUp i keyUp. Właściwość CheckedItems.Count jest dokładna, gdy zdarzenia te są uruchamiane. Ponieważ oba robią to samo, stworzyłem metodę do pracy i wywołałem tę metodę z obu procedur obsługi zdarzeń.

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; 
} 
Powiązane problemy