Я полагаю, что вы спрашиваете: «Какой лучший способ поделиться списком элементов в нескольких представлениях в MVVM?» так что я отвечу на вопрос таким образом.
Предположим, у вас есть сервис, который позволяет получить список людей. Вы назвали его «PersonViewModel», но, возможно, вы путаете объектную сущность с ViewModel. В MVVM у вас есть представление, представляющее элемент управления или экран пользовательского интерфейса. Затем у вас есть ViewModel, которая связывается с представлением и соединяет представление с моделью данных / предметной области. ViewModel может иметь ряд общедоступных свойств, к которым привязывается View, включая методы, которые вызывают службы для заполнения этих свойств из вашей модели данных. В вашем случае у меня будет View + ViewModel, а ViewModel имеет свойство ObservableCollection класса "Person".
Следующий код является пересказом того, как он может выглядеть на самом деле. Не все реализовано.
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
}
}
Что касается управления одним списком, я рекомендую кэшировать коллекцию людей в некотором статическом классе или синглтоне, который доступен для ваших моделей представлений. Тогда приведенный выше метод LoadPeople можно просто извлечь из кеша. Вы можете даже лениво загрузить кэш, чтобы он не выполнял запрос на обслуживание до его первого доступа.
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;
}
}
}
Итак, в вашей ViewModel LoadPeople будет выглядеть примерно так:
public void LoadPeople()
{
this.People.Clear();
foreach( Person person in SystemContext.People )
{
this.People.Add( person );
}
}
Ваш пользовательский интерфейс будет выглядеть примерно так:
<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>