2015-10-28 29 views
5

Sto facendo una semplice applicazione WinForms e sto affrontando qualche strano problema.I ComboBox sono collegati (e questo non funziona)

La mia forma:

enter image description here

E 'così facile come può essere: 3 caselle combinate, e due pulsanti - OK e Annulla.

Vista:

private void applyOrderButton_Click(object sender, EventArgs e) 
    { 
     List<string> testList = new List<string>() 
     { 
      "A", 
      "B", 
      "C" 
     }; 

     comboBox1st.DataSource = testList; 
     comboBox2nd.DataSource = testList; 
     comboBox3rd.DataSource = testList; 

     comboBox1st.SelectedIndex = 2; 
     comboBox2nd.SelectedIndex = 1; 
     comboBox3rd.SelectedIndex = 0; 
     //Presenter.DoTest(); 
    } 

Cosa succede dopo che il metodo applyOrderButton_Click() caling (succede dopo pulsante Ok viene cliccato) tutti i miei ComboBoxes cambiamento di posizione selezionato. Tuttavia, ciascuno di questi comboBox ha lo stesso indice selezionato - in questo caso specifico sarà "A".

Quindi cambio change comboBox selectedIndex utilizzando il mio cursour (ad esempio, scelgo il 3 ° comboBox per mostrare "C") la modifica viene eseguita per tutti e tre i comboBox. Cosa sto facendo di sbagliato?

+1

Tutti e tre scatole condividono la stessa fonte, in realtà la stessa istanza. La posizione corrente nell'elenco è controllata tramite l'elemento corrente dell'enumeratore. Se lo cambi, è cambiato ovunque .. – Shnugo

risposta

10

Si sta eseguendo qualcosa che è presente sullo sfondo di WinForms chiamato "CurrencyManager".

Il suo compito è sincronizzare il "record corrente" tra tutti i controlli associabili che fanno riferimento alla stessa origine dati.

Ad esempio, se si fosse aggiunta un'etichetta e vincolata alla stessa lista e vincolata in modo che mostrasse una proprietà di uno degli oggetti, mostrerebbe sempre il valore della proprietà dello stesso oggetto selezionato nella casella combinata.

Un vantaggio di questo è che si potrebbe facilmente aggiungere un modulo che modifica un elenco di oggetti, legando caselle di testo e simili alle proprietà di uno degli oggetti e aggiungendo un navigatore che consente di passare alla riga successiva o precedente . Non dovresti garantire manualmente che tutte le caselle di testo si riferiscano all'oggetto corretto, il CurrencyManager farebbe tutto questo per te.

Tuttavia, nel tuo caso, poiché hai collegato la stessa origine dati a tutte e tre le caselle combinate, il CurrencyManager assicurerà che tutte e tre selezionino la stessa riga. Se selezioni una nuova riga in una delle caselle combinate, il CurrencyManager andrà a correggere tutti gli altri per fare riferimento alla stessa riga.

È possibile risolvere questo in vari modi:

  1. È possibile ignorare il contesto vincolante per ogni casella combinata:

    comboBox2nd.BindingContext = new BindingContext(); 
    comboBox3rd.BindingContext = new BindingContext(); 
    

    Si noti che se si va questa strada è necessario fare questo prima di assegnare le proprietà SelectedIndex o SelectedItem, altrimenti il ​​CurrencyManager avrà aggiornato le altre due caselle combinate prima di assegnare i nuovi BindingContexts.

  2. È possibile assegnare le fonti di dati distinti per ciascuna casella combinata:

    combobox2nd.DataSource = testList.ToList(); 
    combobox3rd.DataSource = testList.ToList(); 
    
7

Appena assegnare nuovo contesto ad altri ComboBoxes così:

List<string> testList = new List<string>() 
    { 
     "A", 
     "B", 
     "C" 
    }; 

comboBox1st.DataSource = testList; 

comboBox2nd.BindingContext = new BindingContext(); 
comboBox2nd.DataSource = testList; 

comboBox3rd.BindingContext = new BindingContext(); 
comboBox3rd.DataSource = testList; 

comboBox1st.SelectedIndex = 2; 
comboBox2nd.SelectedIndex = 1; 
comboBox3rd.SelectedIndex = 0; 

CurrencyManager viene utilizzato per mantenere controlli associati ai dati sincronizzati tra loro (mostrando i dati dal medesimo record). L'oggetto CurrencyManager esegue questa operazione gestendo una raccolta dei dati associati forniti da un'origine dati. Per ogni origine dati associata a un Windows Form, il modulo mantiene almeno un CurrencyManager. Poiché possono essere presenti più origini dati associate a un modulo, l'oggetto BindingContext gestisce tutti gli oggetti CurrencyManager per qualsiasi modulo specifico. Più in generale, tutti i controlli contenitore hanno almeno un oggetto BindingContext per gestire i loro CurrencyManager.