Quando si utilizza l'associazione WPF, ovviamente non è possibile fare qualcosa sulla linea MyCollection = new CollectionType<Whatever>(WhateverQuery());
poiché i collegamenti hanno un riferimento alla vecchia raccolta. Il mio workaround finora è stato MyCollection.Clear();
seguito da un foreach che fa MyCollection.Add(item);
- il che è piuttosto negativo sia per le prestazioni che per l'estetica.WPF: sostituzione del contenuto della raccolta del database senza Cancella/Aggiungi
ICollectionView
, sebbene piuttosto pulito, non risolve il problema in quanto è SourceCollection
proprietà è di sola lettura; peccato, dal momento che sarebbe stata una soluzione semplice e facile.
In che modo altre persone gestiscono questo problema? Va detto che sto facendo MVVM e quindi non posso rovistare attraverso i collegamenti dei controlli individuali. Suppongo che potrei realizzare un wrapper attorno allo ObservableCollection
con un metodo ReplaceSourceCollection()
, ma prima di percorrere quella strada vorrei sapere se c'è qualche altra buona pratica.
EDIT:
Per WinForms, vorrei associare i controlli nei confronti di un BindingSource
, che mi permette di aggiornare semplicemente è DataSource
proprietà e chiamo il metodo ResetBindings()
- presto, alla base di raccolta in modo efficiente cambiato. Mi sarei aspettato che il databinding di WPF supportasse uno scenario simile fuori dagli schemi?
Codice di esempio (pseudo-ish): il controllo WPF (ListBox, DataGrid, qualsiasi cosa vogliate) è associato alla proprietà Users
. Mi rendo conto che le collezioni devono essere in sola lettura per evitare i problemi dimostrati da ReloadUsersBad()
, ma poi il codice male per questo esempio evidentemente non sarebbe compilare :)
public class UserEditorViewModel
{
public ObservableCollection<UserViewModel> Users { get; set; }
public IEnumerable<UserViewModel> LoadUsersFromWhateverSource() { /* ... */ }
public void ReloadUsersBad()
{
// bad: the collection is updated, but the WPF control is bound to the old reference.
Users = new ObservableCollection<User>(LoadUsersFromWhateverSource());
}
public void ReloadUsersWorksButIsInefficient()
{
// works: collection object is kept, and items are replaced; inefficient, though.
Users.Clear();
foreach(var user in LoadUsersFromWhateverSource())
Users.Add(user);
}
// ...whatever other stuff.
}
puoi inserire un codice? – TalentTuner
+1 buona domanda. Non ho fatto nulla in WPF per un po ', ma un altro framework in un linguaggio diverso ha concetti simili e risolve questo problema interrompendo il ciclo di esecuzione, modificando un gran numero di proprietà e quindi stappando il ciclo di esecuzione. Sto cercando qualcosa di simile. –