2009-02-02 13 views
7

Sto avendo praticamente lo stesso problema come questo:Aggiornamento di un ComboBox databound

C# Update combobox bound to generic list

Tuttavia, sto cercando di cambiare le stringhe mostrate; non aggiungere, rimuovere o ordinare. Ho provato la soluzione BindingList fornita nella domanda di riferimento, ma non ha aiutato. Riesco a vedere la proprietà DataSource della combobox correttamente aggiornata mentre modifica gli elementi, ma i contenuti visualizzati nella casella combinata non sono quelli nella proprietà DataSource.

il mio codice è il seguente:

mSearchComboData = new List<SearchData>(); 
mSearchComboData.Add(new SearchData("", StringTable.PatientID)); 
mSearchComboData.Add(new SearchData("", StringTable.LastName)); 
mSearchComboData.Add(new SearchData("", StringTable.LastPhysician)); 
mSearchComboData.Add(new SearchData("", StringTable.LastExamDate)); 

mBindingList = new BindingList<SearchData>(mSearchComboData); 

SearchComboBox.Items.Clear(); 
SearchComboBox.DataSource = mBindingList; 
SearchComboBox.ValueMember = "Value"; 
SearchComboBox.DisplayMember = "Display"; 

... 

Quando provo ad aggiornare il contenuto faccio la seguente:

int idx = SearchComboBox.SelectedIndex; 
mBindingList[idx].Display = value; 
SearchComboBox.Refresh(); 

EDIT ::

RefreshItems sembra essere un metodo privato . Ho appena ottenere il messaggio di errore:

" 'System.Windows.Forms.ListControl.RefreshItems()' è inaccessibile a causa del livello di protezione"

ResetBindings non ha alcun effetto.

risposta

11

Se si dovesse modificare l'intero oggetto, ovvero l'intero oggetto SearchData, l'elenco di binding avrebbe conoscenza di questo cambiamento e pertanto gli eventi corretti verrebbero internalizzati e la casella combinata verrà aggiornata. TUTTAVIA, dal momento che si sta aggiornando solo una proprietà, la lista di binding non ha idea che qualcosa sia cambiato.

Quello che devi fare è avere la classe SearchData implementare INotifyPropertyChanged. Ecco un esempio rapido che ho scritto per dimostrare:

public class Dude : INotifyPropertyChanged 
    { 
     private string name; 
     private int age; 

     public int Age 
     { 
      get { return this.Age; } 
      set 
      { 
       this.age = value; 
       if (this.PropertyChanged != null) 
       { 
        this.PropertyChanged(this, new PropertyChangedEventArgs("Age")); 
       } 
      } 
     } 
     public string Name 
     { 
      get 
      { 
       return this.name; 
      } 

      set 
      { 
       this.name = value; 
       if (this.PropertyChanged != null) 
       { 
        this.PropertyChanged(this, new PropertyChangedEventArgs("Name")); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 


    } 

Ed ecco qualche codice da testare:

 private void button1_Click(object sender, EventArgs e) 
     { 
      //Populate the list and binding list with some random data 
      List<Dude> dudes = new List<Dude>(); 
      dudes.Add(new Dude { Name = "Alex", Age = 27 }); 
      dudes.Add(new Dude { Name = "Mike", Age = 37 }); 
      dudes.Add(new Dude { Name = "Bob", Age = 21 }); 
      dudes.Add(new Dude { Name = "Joe", Age = 22 }); 

      this.bindingList = new BindingList<Dude>(dudes); 
      this.comboBox1.DataSource = bindingList; 
      this.comboBox1.DisplayMember = "Name"; 
      this.comboBox1.ValueMember = "Age"; 

     } 


    private void button3_Click(object sender, EventArgs e) 
    { 
     //change selected index to some random garbage 
     this.bindingList[this.comboBox1.SelectedIndex].Name = "Whatever"; 
    } 

Dal momento che la mia classe ora implementa INotifyPropertyChanged, l'elenco vincolante viene "avvisato" quando qualcosa cambia, e tutti questo funzionerà così.

+0

avevo provato circa 13 metodi diversi per ottenere la casella combinata sulla mia forma di aggiornare, poi finalmente trovato questa soluzione. Ben scritto, e ha funzionato come un fascino. Grazie! –

2

invece di SearchComboBox.Refresh();

provare SearchComboBox.RefreshItems();

o SearchComboBox.ResetBindings();

Penso che sia veramente quest'ultimo di cui avete bisogno.

È possibile accedere alla documentazione per i membri here.

+0

RefreshItems è protetto – Maxence

2

Questo è un vecchio post ma potrebbe essere utile.

Sono appena stato a guardare lo stesso problema e ho trovato che se si chiama ResetItem sull'oggetto BindingList, con la posizione di elementi modificati, è interno genera l'evento di notifica per Itemchanged causando l'elenco da aggiornare.

int idx = SearchComboBox.SelectedIndex; 
mBindingList[idx].Display = value; 

mBindingList.ResetItem(idx); //raise Item changed event to update the list display