2013-12-10 37 views
5

Prima il mio codice. Ho una classe:Perché ComboBox non genera un'eccezione quando si imposta DataSource?

class Person { 
    public int Id { set; get; } 
    public string Name { set; get; } 
    public Person(int i, string n) {Id = i; Name = n;} 
} 

e un oggetto ComboBox:

this.comboBox_Persons = new System.Windows.Forms.ComboBox(); 

e da qualche parte nel mio codice:

List<Person> persons = new List<Person>() { 
    new Person(5, "John"), 
    new Person(8, "Mike") 
}; 
comboBox_Persons.Items.Clear(); 
comboBox_Persons.DisplayMember = "Name"; 
comboBox_Persons.ValueMember = "Id"; 
comboBox_Persons.DataSource = persons; 

e un membro statico e un gestore di eventi:

public static string test = ""; 

void comboBox_PersonsSelectedIndexChanged(object sender, EventArgs e) 
{ 
    test = test + "1"; 
    string id = (string) comboBox_Persons.SelectedValue; 
} 

L'ultima riga è sbagliata (viene s da una versione precedente del mio codice) e dovrebbe essere:

int id = (int) comboBox_Persons.SelectedValue; 

e mi c'è voluto del tempo per rendersi conto che il mio problema è in questa linea.

Ma la mia domanda riguarda la versione errata della riga e esattamente il codice sopra riportato.

Perché non viene generata alcuna eccezione quando comboBox_Persons.DataSource viene riempito?

Quando il mio modulo è pronto comboBox_Persons contiene due elementi e dovrebbe visualizzare "John" e "Mike" ma non è così. La casella combinata visualizza il nome del tipo (con spazio dei nomi) della classe Persona due volte. Inoltre, il valore del campo statico 'test' è "11", il che significa che il gestore eventi è stato richiamato. Ma la riga successiva (con il cast dello string) dovrebbe generare un'eccezione, ma non lo fa. Perché? E poi, quando clicco sulla casella combinata e cambio il valore selezionato, viene chiamato il gestore di eventi e viene lanciata un'eccezione (che dice che non può eseguire il cast sulla stringa).

Quindi, perché combobox non genera eccezioni durante l'impostazione di DataSource?

E perché nella casella combinata vengono visualizzati i nomi dei tipi anziché la proprietà definita 'Nome'?

Mi chiedo perché questo controllo si comporta in questo modo e non ho trovato alcuna risposta nella documentazione .NET e su Internet.

Quando cambio la riga sbagliata nella versione corretta tutto è OK.

+0

Avete un blocco 'try/catch' attorno al codice in questione? Non ne mostri uno nel tuo esempio. Aggiungilo e vedi se viene sollevata l'eccezione. Le Winform possono ingoiare le eccezioni a seconda delle complessità del processo di caricamento. –

+0

Interessante! Ho provato a eseguire il debugging dello stesso codice che hai postato e sta generando un'eccezione in SelectedIndexChanged, tuttavia non ha infranto l'applicazione. Sembra che l'eccezione venga catturata da qualche parte ?? !! – Poornima

+0

Si blocca durante l'esecuzione diretta del programma? Cioè al di fuori del debugger. Esiste una certa classe di eccezioni che si verifica durante l'esecuzione del programma ma non durante il debug. È sempre possibile impostare eccezioni per causare sempre un'interruzione (anche se sono state rilevate) e questo consentirà almeno di vedere l'eccezione. –

risposta

0

fare il seguente e la tua casella combinata funziona:

comboBox_Persons.DataSource = persons.ToArray(); 

Questo è quello che vorrei fare:

Person p = (Person) comboBox_Persons.SelectedItem; 

Ora avete tutte le proprietà della persona

Ma la la prossima linea (con casting in stringa) dovrebbe generare un'eccezione, ma non lo fa. Perché? - il tuo valore è intero. Il cast dell'intero per stringa dovrebbe generare un'eccezione. Anche se, credo, non hai lo int lì. "... dovrebbe mostrare" John "e" Mike "ma non lo è: la casella combinata visualizza il nome del tipo (con spazio dei nomi) della classe Persona due volte ..." - Perché dovresti fare persons.ToArray() per ottenere "John" e "Mike".

Quindi, perché combobox non genera eccezioni durante l'impostazione di DataSource? - perché è solo una configurazione e fino a quando viene eseguita qualche operazione, è possibile impostare qualsiasi cosa come origine dati.

Modificare questa

public static string test = "";....test = test + "1"; 

a questo

public static int test = 0; ..... test += 1; 

Buona fortuna

+0

In realtà genera un'eccezione se stai trasmettendo il valore su un tipo diverso !! Puoi convertire un int in stringa, ma "cast" genererà un'eccezione. Se esegui il debug del codice precedente, noterai che è stata lanciata un'eccezione 'cast non valida', ma comunque non abortisce l'applicazione. – Poornima

+0

Questo perché il suo 'SelectedValue' non è' int' come il suo codice va. Una volta fatto 'comboBox_Persons.DataSource = persons.ToArray();' dovrebbe andare via –

+0

Nella tua risposta, hai citato 'Perché il cast di stringa intero dovrebbe generare un'eccezione?'. Il mio commento è una risposta a quella linea. "Casting" in un altro tipo genera sempre un'eccezione, laddove la conversione non lo fa. In questo caso, verrà generata un'eccezione. – Poornima

3

ero alla ricerca su google per il codice sorgente combobox per vedere come viene implementato e perché le eccezioni sono sempre sepolti e ho trovato questo:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/69a0b831-7782-4bd9-b910-25c85f18bceb/visual-studio-doesnt-break-on-unhandled-exception-with-windows-64bit?forum=vsdebug

http://social.msdn.microsoft.com/Forums/vstudio/en-US/8a7006a1-ad86-4aec-9604-d7ccf99ce00b/selectedindexchanged-handler-exception-treated-as-first-chance?forum=vsdebug

È interessante notare che, se si aggiunge una linea per generare un'eccezione nel vostro evento SelectedIndexChanged, l'applicazione non va in crash !!

private void comboBox_persons_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     test = test + "1"; 
     string id = (string)comboBox_Persons.SelectedValue; 
     throw new ApplicationException("Test"); 
    } 

Apparentemente, questo è un problema con le macchine a 64 bit e c'è un hotfix disponibile per questo problema. Come affermato in questo post, il codice soggetto a eccezioni nell'evento Form_Load non interrompe l'applicazione !! Simile è il caso con l'evento SelectedIndexChanged di combobox.

Non ho potuto testare l'aggiornamento rapido poiché non ho installato Win 7 SP1 sul mio computer. Tuttavia, dai commenti nel blog, l'aggiornamento rapido non risolve tutti i problemi con le eccezioni interrotte nelle macchine a 64 bit.

Spero che questa informazione sia utile!

+0

Grazie per la risposta. I link che mi hai dato fammi sapere di più. Sto usando Win8 64 bit e su questo sistema lanciare un'eccezione da Form_Load funziona correttamente. Ho eseguito il mio codice (che utilizza combobox) su Win7 SP1 a 32 bit e non è stata lanciata un'eccezione dall'evento SelectedIndexChanged. Non riesco a installare l'aggiornamento rapido perché non è il mio computer. Quindi immagino che il problema sia presente su tutti i sistemi Microsoft. E non è un problema risolvere un bug come il casting su string o simili, ma può essere dispendioso in termini di tempo trovarlo com'era nel mio caso. – Victor

+0

Lo so, le eccezioni silenziose sono il peggior nemico di uno sviluppatore! Sto usando Win7 64 bit e non ottengo eccezioni in Form_Load neanche dopo aver esplicitamente usato 'throw'. Ho visto un comportamento diverso quando cambio la piattaforma di destinazione nel mio progetto. Spero che trovino presto una soluzione. – Poornima

Problemi correlati