Al utilizar el enlace de datos WPF, obviamente no puedo hacer algo a lo largo de las líneas MyCollection = new CollectionType<Whatever>(WhateverQuery());
ya que los enlaces tienen una referencia a la colección anterior. Mi solución hasta ahora ha sido MyCollection.Clear();
seguido de un foreach haciendo MyCollection.Add(item);
, lo cual es bastante malo tanto para el rendimiento como para la estética.WPF: Reemplazar los contenidos de la colección databound sin Borrar/Agregar
ICollectionView
, aunque bastante limpio, no resuelve el problema ya que es SourceCollection
la propiedad es de solo lectura; Demonio, ya que habría sido una solución agradable y fácil.
¿Cómo están manejando este problema otras personas? Cabe mencionar que estoy haciendo MVVM y, por lo tanto, no puedo hurgar en las vinculaciones de controles individuales. Supongo que podría hacer un contenedor alrededor del ObservableCollection
con un método ReplaceSourceCollection()
, pero antes de seguir esa ruta me gustaría saber si hay alguna otra práctica recomendada.
EDIT:
Para Windows Forms, me gustaría enlazar controles contra un BindingSource
, lo que me permite simplemente actualizar su DataSource
propiedad y llamar al método ResetBindings()
- presto, que subyace en la colección cambió de manera eficiente. Me esperaba que WPF databinding para soportar un escenario similar de la caja?
Código de ejemplo (pseudo-ish): el control WPF (ListBox, DataGrid, lo que sea que desee) está vinculado a la propiedad Users
. Soy consciente de que las colecciones deben ser de sólo lectura para evitar los problemas demostrados por ReloadUsersBad()
, pero luego el código malo para este ejemplo, obviamente, no se compilará :)
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.
}
¿Puede por favor publicar un código? – TalentTuner
+1 buena pregunta. No he hecho nada en WPF por un tiempo, pero otra estructura en un idioma diferente tiene conceptos similares y resuelve este problema deteniendo el ciclo de ejecución, cambiando una gran cantidad de propiedades y luego deshaciendo el ciclo de ejecución. Estoy buscando algo similar. –