c# - que - observablecollection methods
¿Cómo puedo reemplazar ObservableCollection estático para que sea accesible en todas las ventanas en el modo MVVM? (3)
Caché Recibí una clase (algunas clases aleatorias) con una ObservableCollection estática:
public static ObservableCollection<PersonViewModel> thepeoplelist = new ObservableCollection<PersonViewModem>();
Sin embargo, estoy convirtiendo mi proyecto a MVVM y, por supuesto, esta no es una buena forma de llenar todos mis controles de elementos (principalmente listas) obtuve varias ventanas que usan esta fuente de esta manera.
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
lsvallthepeople.ItemSource = somerandomclasss.thepeoplelist;
}
La vista de lista muestra a todas las personas con la información. Sin embargo, esta no es la forma de MVVM que apuesto, y no he encontrado una buena manera de trabajar sin una ObservableCollection estática pública, sin embargo, hay una ventana donde se obtiene una vista de lista donde se pueden editar las personas, se actualizan en el SQL base de datos y en PersonViewModel (que obtuvo INotifyPropertyChanged).
Si necesita más información, no dude en preguntarle a c :).
Creo que lo que estás preguntando es: "¿Cuál es la mejor forma de compartir una lista de elementos en múltiples vistas en MVVM?" entonces responderé la pregunta de esa manera.
Supongamos que tiene un servicio que proporciona una forma de obtener la lista de personas. Lo llamó un "Modelo PersonView", pero podría confundir una entidad de dominio con un ViewModel. En MVVM, tiene una vista que representa el control de la interfaz de usuario o la pantalla. Luego tiene un ViewModel que se une a la vista y se une a la Vista para el modelo de datos / dominio. ViewModel puede tener una serie de propiedades públicas a las que se vinculará la Vista, incluidos los métodos que llaman a los servicios para completar esas propiedades desde su modelo de datos. En su caso, tendría View + ViewModel y ViewModel tiene una propiedad ObservableCollection de la clase "Persona".
El siguiente código es una paráfrasis de lo que realmente podría ser. No todo está implementado.
public class MyViewModel : INotifyPropertyChanged
{
public ObservableCollection<Person> People { get; set; }
public MyViewModel()
{
this.People = new ObservableCollection<Person>();
this.LoadPeople();
}
private void LoadPeople()
{
this.People.Clear();
// Have your logic here that loads the people collection
}
}
En cuanto a la gestión de una sola lista, recomiendo el almacenamiento en caché de la colección de personas en algún tipo de clase estática o singleton que sea accesible para sus modelos de visualización. Luego, el método LoadPeople de arriba simplemente puede extraer de la memoria caché. Incluso puede cargar la memoria caché de forma lenta para que no realice la solicitud de servicio hasta su primer acceso.
internal static class SystemContext
{
private static ObservableCollection<Person> _people = null;
public static ObservableCollection<Person> People
{
get
{
if( _people == null )
{
_people = new ObservableCollection<Person>();
// load the list here from a service or something
}
return _people;
}
}
}
Entonces, en su ViewModel, LoadPeople se vería así:
public void LoadPeople()
{
this.People.Clear();
foreach( Person person in SystemContext.People )
{
this.People.Add( person );
}
}
Su interfaz de usuario se verá así:
<ListBox
ItemsSource={Binding Path=People, Mode=OneWay}
SelectedItem={Binding Path=SelectedPerson, Mode=TwoWay}
>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=PersonName, Mode=OneWay}" />
<TextBlock Text="{Binding Path=DateOfBirth, Mode=OneWay}" />
<!-- etc -->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Probablemente debería tener esto como un servicio o repositorio que se inyecta en cada modelo de vista (como una abstracción) que requiere la lista.
Como desea completar esta lista solo una vez, puede hacer esto en el constructor de la implementación del servicio / repositorio o utilizar una técnica de almacenamiento en caché en el método GetList
los servicios.
Como siempre desea pasar la misma instancia a cada modelo de vista, debe usar un patrón singleton o registrar la abstracción (por ejemplo, IPeopleRepository
) en una instancia particular si usa un contenedor IoC.
Como esto sería un servicio / repositorio, debe devolver un tipo que no dependa de la tecnología de presentación, es decir, un IEnumerable<T>
o IList<T>
, y use esto para crear sus colecciones observables en cada modelo de vista.
Puede usar un enlace Static
para vincular su ItemsSource
lugar de configurarlo en su código subyacente manualmente
<ListBox ItemsSource="{Binding Source={
x:Static local:somerandomclasss.thepeoplelist}}" ... />
o exponer una propiedad que devuelve la colección de su ViewModel y enlazar a esa propiedad
public class MyViewModel
{
public ObservableCollection<PersonViewModel> PersonList
{
get { return somerandomclasss.thepeoplelist; }
}
...
}
<ListBox ItemsSource="{Binding PersonList}" ... />