2013-03-20 6 views
3

Предположим, у меня есть класс модели Data, и я хотел бы создать и DataView для этого. Класс данных выглядит следующим образом:ObservableCollection в ViewModel не обновляется при изменении списка в модели

public class Data 
{ 
    public Data() 
    { 
     RandomData = new List<String>(); 
    } 

    public List<String> RandomData {get; set;} 
} 

Я хочу создать DataViewModel, который инкапсулирует RandomData свойства. Мне нужно связать с этим свойством RandomData в некотором ListView и обновить его при изменении базовой модели RandomData.

Если я это сделать:

public class DataViewModel 
{ 
    private Data _data; 

    public DataViewModel(Data data) 
    { 
     _data = data; 
     RandomData = new ObservableCollection<String>(_data.RandomData); 
    } 

    public ObservableCollection<String> RandomData {get; set;} 
} 

тогда я не получаю никаких обновлений. (Я знаю, что это просто копирование списка, я просто использую его, чтобы получить точку). Если я использовал INotifyPropertyChanged в свойстве RandomData, я бы получил только уведомления о новых списках, назначенных ему. Как я могу проверить изменение содержимого? Каков предпочтительный способ сделать это?

Спасибо за любые предложения

ответ

3

Для этого конкретного примера я бы соблазн изменить свою модель, чтобы использовать ObservableCollection

public class Data 
{ 
    public Data() 
    { 
     RandomData = new ObservableCollection<String>(); 
    } 

    public ObservableCollection<String> RandomData {get; set;} 
} 

, а затем выставить это в своей модели просмотра как ReadOnlyObservableCollection. Обратите внимание, что ReadOnlyObservableCollection является оберткой над исходным ObservableCollection. Данные не копируются и изменения уведомлений из первоначальной коллекции отражаются в ReadOnlyObservableCollection.

public class DataViewModel 
{ 
    public DataViewModel(Data data) 
    { 
     RandomData = new ReadOnlyObservableCollection<String>(data.RandomData); 
    } 

    public ReadOnlyObservableCollection<String> RandomData {get; private set;} 
} 

Это предполагается, что вы хотите, чтобы модель RandomData для просмотра была, конечно, только для чтения.

+0

Да, это пятно. Кажется, у меня нет выбора, кроме как использовать ObservableCollections. –

1

я считаю, чтобы принять уведомление об изменениях в существующей коллекции вы хотели бы использовать INotifyCollectionChanged.

http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged.aspx

Реализация этого интерфейса может быть хорошим методом для использования. Однако я верю в статью модели MVVM, http://msdn.microsoft.com/en-us/magazine/dd419663.aspx, в MSDN Джош Смит делает это, даже не используя этот интерфейс. Я знаю, что в примере, он дает ему добавляет клиентов в коллекцию с логикой, подобной:

void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
     { 
      if (e.NewItems != null && e.NewItems.Count != 0) 
       foreach (CustomerViewModel custVM in e.NewItems) 
        custVM.PropertyChanged += this.OnCustomerViewModelPropertyChanged; 

      if (e.OldItems != null && e.OldItems.Count != 0) 
       foreach (CustomerViewModel custVM in e.OldItems) 
        custVM.PropertyChanged -= this.OnCustomerViewModelPropertyChanged; 
     } 
+0

Это опечатка или вы имеете в виду, я должен изменить свойство Дейты к ObservableCollection? Потому что я вообще не могу изменить модель. Чтобы быть более точным, я мог бы изменить его, но нет ли альтернативного способа сделать это? –

+0

Приношу свои извинения, я не полностью изучил ваш вопрос. Я считаю, что интерфейс, который вы хотите, это INotifyCollectionChanged, который позволит вам знать, когда коллекция добавляет и удаляет значения данных в и из нее в дополнение к свойствам. http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged.aspx – djangojazz

+0

См. мой обновленный ответ, я принял изменения свойств для изменений коллекции.Я знаю, что в статье MSDN Джош Смит обращается к логике напрямую, раскрывая это событие и учитывая его. Я знаю, что если вы загрузите пример, вы можете увидеть, что клиенты добавляются в реальном времени в вашу основную коллекцию, а также совершенно другое представление. – djangojazz

0

Вариант 1 (немного в стороне от MVVM, но работает). Добавьте к этому OnNagivatedTo вашего View кода позади, и он будет обновляться в любое время, данные:

protected override void OnNavigatedTo(NavigationEventArgs e) { 
this.DataContext = new YourViewModel(); 
} 

Вариант 2:

raise RaisePropertyChanged(YourItem); 
Смежные вопросы