2013-02-09 16 views
13

Ho un ListBox sulla mia UI che è associato a una proprietà di ObservableCollection. Ho impostato una nuova istanza di ObservableCollection nella proprietà nel costruttore del modello di vista e posso aggiungere elementi con un pulsante sul modulo. Questi sono visibili nella lista.ObservableCollection perde binding quando I "new" it

Tutto è buono.

Tuttavia, se reinizializzare la proprietà con nuova nel tasto di richiamata, si rompe il legame e l'interfaccia utente non è più mostra ciò che è nella collezione.

Ho ritenuto che il binding continuasse a cercare i valori della proprietà, ma è presumibilmente collegato a un riferimento che viene distrutto dal new.

Ho capito bene? Qualcuno può espandersi su come questo è collegato? C'è un modo per rebindarlo quando il mio modello di vista non ha conoscenza della vista?

risposta

12

Assicurarsi di sollevare un oggetto PropertyChangedEvent dopo aver reintializzato la raccolta. Alzando questo evento si consente alla vista di gestire le modifiche alla proprietà con il modello che non ha conoscenza della vista.

class Model : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(string name) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
    } 

    private ObservableCollection<string> _list = new ObservableCollection<string>(); 
    public ObservableCollection<string> List 
    { 
     get { return _list; } 
     set 
     { 
      _list = value; 
      NotifyPropertyChanged("List"); 
     } 
    } 

    public Model() 
    { 
     List.Add("why"); 
     List.Add("not"); 
     List.Add("these?"); 
    } 
} 
4

Credo che in base alla descrizione che quello che dovete fare è refactoring la proprietà che espone l'ObservableCollection in modo che genera un evento PropertyChanged anche quando viene assegnato un nuovo valore. Esempio:

public ObservableCollection<int> Integers 
{ 
    get { return this.integers; } 
    set { 
     if (this.integers != value) 
     { 
      this.integers = value; 
      RaisePropertyChanged("Integers"); 
     } 
    } 
} 
3

Supponendo hai implementato INotifyPropertyChanged sul ViewModel, è possibile generare l'evento modificato proprietà sulla vostra ObservableCollection ogni volta che si assegna un valore nuova ad esso.

public ObservableCollection<string> MyList { get; set; } 

public void SomeMethod() 
{ 
    MyList = new ObservableCollection<string>(); 
    RaisePropertyChanged("MyList"); 
} 
1

Aggiornamenti al ObservableCollection vengono gestiti agganciando in per l'evento CollectionChanged in modo che quando si crea un nuovo ObservableCollection vostro osservatore è ancora guardando la vecchia collezione.

Due semplici suggerimenti sarebbe sia per attuare INotifyPropertyChanged sulla classe che contiene la ObservableCollection e alzando l'evento PropertyChanged nel setter della proprietà della raccolta (non dimenticate di sganciare dalla vecchia prima nel vostro osservatore se è il vostro proprio codice).

private ObservableCollection<string> _myCollection = new ObservableCollection<string>(); 
public ObservableCollection<string> MyCollection 
{ 
    get { return _myCollection; } 
    set 
    { 
     if(_myCollection == value) 
      return; 

     _myCollection = value; 
     RaisePropertyChanged("MyCollection"); 
    } 
} 

Una seconda, e l'opzione io in genere preferisco è quello di appena chiaro e ripopolare la collezione con i nuovi dati quando arriva.

public void HandleCollectionData(IEnumerable<string> incomingData) 
{ 
    MyCollection.Clear(); 
    foreach(var item in incomingData) 
    { 
     MyCollection.Add(item); 
    } 
} 
+2

Aggiunta di ogni elemento alla raccolta osservabile aumenta l'aggiornamento dell'interfaccia utente roundrip.So si dovrebbe evitare la seconda soluzione. –

+0

D'accordo, il secondo approccio qui aumenterà il numero di chiamate 'CollectionChanged' e se in realtà diventerà un problema e vorrete evitare di creare nuovamente una collezione, suggerirei di implementare il vostro' ObservableCollection' con un metodo AddRange che sarebbe abbastanza fatto facilmente, ma nella maggior parte dei casi non sarebbe una preoccupazione –

Problemi correlati