2010-07-05 6 views
5

Attualmente sto sviluppando un'app Window che utilizza CheckedListBoxes per alcuni aspetti del programma. Un problema che ho riscontrato è che ho cercato di trovare quale evento viene attivato quando un elemento è selezionato in modo che possa abilitare un pulsante del modulo quando viene controllato un elemento di elenco.Windows C# CheckedListBox Checked Item Gestione degli eventi

Il problema è che ho provato ad utilizzare quanto segue;

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

ma quando ho impostato un punto di interruzione l'istruzione if, non è mai spara al momento del check un elemento nella casella di riepilogo.

Sto facendo qualcosa di sbagliato qui?

+0

Sembra che il Form Designer abbia registrato un evento ItemCheck errato. Ciò ha risolto il problema principale, ma ora ne è emerso uno nuovo che appare più vago nel suo contesto. Apparentemente lo stato di un elemento selezionato non viene aggiornato fino a dopo il termine di ItemCheck. Questo è un problema poiché ho bisogno che il primo elemento venga controllato per attivare il codice incorporato. Dal momento che lo stato non viene aggiornato fino a dopo, perdo la registrazione immediata dell'oggetto che controlla l'attivazione degli eventi. –

risposta

18

Un trucco standard di Windows Form consiste nel ritardare il codice in esecuzione fino a quando non sono stati completati tutti gli effetti collaterali dell'evento. Si ritarda l'esecuzione del codice con il metodo Control.BeginInvoke(). Ciò risolverà il vostro problema:

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

Vedrò sicuramente più questo suggerimento. Sembra essere sulla strada giusta sulla carta (schermo). :) Grazie, Hans. –

+0

Penso che sarà il biglietto che stavo cercando. Grazie per l'assistenza! :) –

+0

Questo ha funzionato per me con una soluzione combinazione dodgy_coder: http://stackoverflow.com/questions/545533/delayed-function-calls. Basta aggiungere il metodo foo al codice, quindi modificare questa riga in questo.BeginInvoke (new MethodInvoker (foo), null); e infine all'interno di foo call evalList invece di bar(); –

0

Un paio di potenziali trucchi. Presumibilmente hai aggiunto l'evento tramite la GUI VS.Net per assicurarti che venga messo a piombo nel controllo. Prova a fare clic su un elemento due volte - una volta per mettere a fuoco l'elemento e di nuovo per attivare lo stato di controllo - se vuoi che un elemento abbia il suo stato di controllo attivato al primo clic, quindi imposta la proprietà "CheckOnClick" su true.

+0

Ho già impostato il valore "CheckOnClick" su true. Ho notato che Microsnot sembra aver trascurato un elemento di design piuttosto importante in questo caso. Ti permetteranno di stabilire cosa sta per cambiare, ma non far scattare nessun evento una volta completata la modifica. Devo dire che quei deficienti di SM potrebbero richiedere un debugger per un sogno bagnato. –

0

Penso che sia l'evento SelectedIndexChanged ma confermo ora.

MODIFICA: l'evento SelectedIndexChanged funziona. Ma quello sta sparando indipendentemente dal fatto che la casella fosse spuntata. Quindi dovrei controllare lo stato controllato se vuoi farlo.

Ma, a parte quando ho usato l'evento ItemCheck, ha sparato quando ho effettivamente controllato la casella di controllo e non solo il testo.

+0

Sì, l'ItemCheck si attiva quando si fa clic su una casella di controllo. Il vero problema è che lo stato controllato di quella casella di controllo sarà ancora l'opposto di quello che era prima di aver fatto clic su di esso fino a dopo il completamento del controllo ItemCheck. Quindi, il vero dilemma di provare a vedere se una checkbox è effettivamente selezionata o deselezionata in tempo reale. cioèla necessità di un evento "ItemCheckChanged". –

+0

Quindi non puoi controllare il contrario? Se l'evento itemcheck è attivo e la casella non è selezionata, significa che sta per essere verificato correttamente? – spinon

2

È possibile utilizzare la proprietà NewValue aggiornare manualmente CheckedItems.Count. Questo è il codice che uso per attivare un pulsante solo quando c'è almeno un elemento controllato:

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

So che questo è stato risposto molto tempo fa, ma ho trovato più facile da gestire solo gli eventi MouseUp e KeyUp. La proprietà CheckedItems.Count è accurata quando tali eventi vengono generati. Poiché entrambi fanno la stessa cosa, ho creato un metodo per il lavoro e ho chiamato quel metodo da entrambi i gestori di eventi.

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; 
}