当Model中的List发生变化时,ViewModel中的ObservableCollection不会被更新

本文关键字:中的 ObservableCollection ViewModel 更新 List Model 变化 | 更新日期: 2023-09-27 18:05:02

假设我有一个模型类Data,我想为它创建DataViewModelDataView。数据类看起来像这样:

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

我想创建DataViewModel封装RandomData属性。我需要在一些ListView中绑定到RandomData属性,并在底层模型的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;}
}

那么我不会收到任何更新。(我知道这只是复制列表,我只是用它来说明要点)。如果我在RandomData属性上使用INotifyPropertyChanged,那么我只会收到分配给它的新列表的通知。如何检查内容的更改呢?做这件事的首选方法是什么?

谢谢你的建议

当Model中的List发生变化时,ViewModel中的ObservableCollection不会被更新

对于这个特定的例子,我很想改变你的模型,使用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是只读的。

我相信要注意现有集合中的变化,您可能想要使用INotifyCollectionChanged。

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

实现这个接口可能是一个很好的方法。然而,我相信在MVVM模型文章http://msdn.microsoft.com/en-us/magazine/dd419663.aspx中,在MSDN Josh Smith甚至没有使用这个接口就做到了这一点。我知道在他给出的例子中,他将客户添加到一个集合中,逻辑类似于:

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;
        }

选项1(稍微撇开MVVM,但工作)。将此添加到视图代码后面的OnNagivatedTo中,它将随时刷新数据:

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

选项2:

 raise RaisePropertyChanged(YourItem);