C# MVVM在模型更改时更新视图模型

C# MVVM在模型更改时更新视图模型,c#,wpf,mvvm,C#,Wpf,Mvvm,我需要在模型更改时更新ViewModel,在ViewModel更改时更新Model。在我的例子中,我有:ProjectViewModel实现INotifyPropertyChanged和Project(model)实现INotifyPropertyChanged。当ViewModel更改时,我只是直接更改模型。但当模型改变时,又会怎样呢?我试图在ViewModel中处理模型的属性更改事件。但那个么我将有来自长寿命模型的强引用,那个将导致内存泄漏,还是并没有?如果是,那么如何做呢 编辑: EDIT

我需要在模型更改时更新ViewModel,在ViewModel更改时更新Model。在我的例子中,我有:ProjectViewModel实现INotifyPropertyChangedProject(model)实现INotifyPropertyChanged。当ViewModel更改时,我只是直接更改模型。但当模型改变时,又会怎样呢?我试图在ViewModel中处理模型的属性更改事件。但那个么我将有来自长寿命模型的强引用,那个将导致内存泄漏,还是并没有?如果是,那么如何做呢

编辑:


EDIT2:或者我可以在ViewModel中实现类似IDisposable的东西吗?或者将ViewModel中的模型(项目)属性公开并直接绑定到它?

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


当您确实需要订阅模型的INPC时,您还需要取消订阅。这并不像看上去那么麻烦,因为VM会触发模型的获取或重新提取,所以在需要取消订阅时就很清楚了。检查界面-这是订阅和取消订阅的好地方。

就我个人而言,我会按照您在第二次编辑中的建议,在模型上实现
INotifyPropertyChanged
,使
Project
成为公共属性,并直接绑定到
Project.Name

请添加您拥有的代码,很难说导致内存泄漏的原因,但如果对象仍然被引用,则不会对其引用进行垃圾收集。我会重新考虑你的方法:如果一个ViewModel和它所代表的模型一样长,那么它的目的仅仅是为了UI而精简模型吗?在这种情况下,(a)模型是否足够,或者(b)是否存在将ViewModel映射回您的模型(然后作为DTO)的点?@Gigabyte我需要视图模型,因为将来它将包含与ui相关的内容(支持重命名等)。我将其用于ui。模型可以从其他对象更新。它将包含保存的逻辑,也许还有更多的东西。
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)
}