2015-10-28 13 views
5

Robię prostą aplikację WinForm i napotykam na dziwny problem.ComboBoxes są połączone (i to jest złe)

Moja forma:

enter image description here

To jest tak proste, jak to tylko możliwe: 3 comboboxes i dwa przyciski - OK i Anuluj.

Widok:

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

Co się dzieje po caling metodę applyOrderButton_Click() (zdarza się po kliknięciu przycisku OK) wszystkie moje comboboxes zmieniają wybrane stanowisko. Jednak każdy z tych elementów comboBox ma ten sam wybrany indeks - w tym konkretnym przypadku będzie to "A".

Następnie zmieniam zmianę comboBox selectedIndex za pomocą mojego cursour (na przykład wybieram 3 comboBox, aby pokazać "C") zmiana jest wykonywana dla wszystkich trzech list comboBox. Co robię źle?

+1

Wszystkie trzy pudła podzielić się z tego samego źródła, a właściwie tę samą instancję. Aktualna pozycja na liście jest kontrolowana przez bieżący element modułu wyliczającego. Jeśli to zmienisz, zmieni się wszędzie ... – Shnugo

Odpowiedz

10

Występuje coś, co jest obecne w tle WinForms o nazwie "CurrencyManager".

Jego zadaniem jest synchronizacja "bieżącego rekordu" we wszystkich kontrolerach bindable, które odnoszą się do tego samego źródła danych.

Na przykład, jeśli dodałeś etykietę i przywiązałeś ją do tej samej listy, i związałeś ją tak, aby pokazywała właściwość jednego z obiektów, zawsze pokazywałaby wartość właściwości tego samego obiektu, który wybrałeś w combobox.

Jedną z korzyści jest to, że można łatwo dodać formularz, który edytuje listę obiektów, wiążące pola tekstowe i podobne właściwości jednego z obiektów i dodając nawigator, który pozwala przejść do następnego lub poprzedniego wiersza . Nie musiałbyś ręcznie zapewniać, że wszystkie pola tekstowe odnoszą się do właściwego obiektu, a CurrencyManager zrobi to za Ciebie.

Jednak w twoim przypadku, ponieważ przywiązujesz to samo źródło danych do wszystkich trzech pól combobox, CurrencyManager zapewni, że wszystkie trzy wybiorą ten sam wiersz. Jeśli wybierzesz nowy wiersz w jednym z comboboxów, CurrencyManager przejdzie i naprawi wszystkie pozostałe, aby odnieść się do tego samego wiersza.

Można rozwiązać ten problem na różne sposoby:

  1. Można zastąpić kontekst wiążący dla każdego combobox:

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

    Zauważ, że jeśli tę drogę trzeba to zrobić przed przypisaniem właściwości SelectedIndex lub SelectedItem, w przeciwnym razie menedżer waluty zaktualizuje pozostałe dwa pola combobox przed przypisaniem nowych obiektów BindingContext.

  2. można przypisać różne źródła danych do każdego combobox:

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

Wystarczy przypisać nowy kontekst dla innych comboboxes tak:

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 służy do utrzymania kontroli danych związana ze sobą zsynchronizowane (widocznych danych z tego samego rekordu). Obiekt CurrencyManager robi to, zarządzając kolekcją powiązanych danych dostarczanych przez źródło danych. Dla każdego źródła danych powiązanego z formularzem systemu Windows formularz zachowuje co najmniej jeden menedżer waluty. Ponieważ może istnieć więcej niż jedno źródło danych powiązane z formularzem, obiekt BindingContext zarządza wszystkimi obiektami CurrencyManager dla dowolnej konkretnej postaci. Mówiąc szerzej, wszystkie kontrole kontenerów mają co najmniej jeden obiekt BindingContext do zarządzania swoimi CurrencyManagers.

Powiązane problemy