模型更改时的MVVM更新视图模型

时间:2018-01-21 20:25:04

标签: c# wpf mvvm

当ViewModel发生变化时,我需要在模型更改时更新ViewModel和Model。就我而言,我有: ProjectViewModel 实施 INotifyPropertyChanged 项目(模型)实施 INotifyPropertyChanged 。当ViewModel发生变化时,我只需直接更改模型。但是当模型发生变化时,又是什么?我试图在ViewModel中处理Model的属性更改事件。但是,我会从长寿命模型中获得强大的参考,这会导致内存泄漏,或者不会?如果是,那么怎么办呢?

编辑:

class ProjectViewModel : INotifyPropertyChanged
{
    private Project Project;

    public string Name
    {
        get
        {
            return Project.Name;
        }
        set
        {
            Project.Name = value;
            OnPropertyChanged("Name");
        }
    }

    public ProjectViewModel(Project project)
    {
        this.Project = project;
        project.PropertyChanged += OnProjectChanged;
    }

    private void OnProjectChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Name")
            OnPropertyChanged("Name");
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    } //and then things for UI....
}
class Project : INotifyPropertyChanged
{
    private string name;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
            OnPropertyChanged("Name");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }//and then logic (for saving)
}

EDIT2:或者我可以在ViewModel中实现类似IDisposable的东西吗?或者在ViewModel中创建model(Project)属性并直接绑定到它?

2 个答案:

答案 0 :(得分:1)

如果您的VM以任何方式依赖于模型中属性的值,则是,您需要订阅其INPC通知。但实际情况是,VM通常不需要知道特定的模型值,除非它正在聚合这些值(即从对象列表中求和一个值)。

如果您确实需要订阅该模型的INPC,那么您还需要取消订阅。这并不像看起来那么麻烦,因为VM会触发模型的获取或重新获取,因此在需要完成取消订阅时就很清楚了。检查INotifyCollectionChanged界面 - 这是开始订阅和取消订阅的好地方。

答案 1 :(得分:0)

就个人而言,我会在您的第二次修改中执行您的建议,在模型上实施INotifyPropertyChanged,使Project成为公共财产,并直接绑定到Project.Name