首页 > 解决方案 > C# WPF 中的 MVVM 帮助我理解模型和视图模型的关系

问题描述

我试图更好地理解 MVVM 概念,但我正在努力解决模型和视图模型的关系。

我可以这样说:模型不知道视图模型,因为视图模型不知道视图吗?

如果我错了,请纠正我,考虑一个简单的 WPF 应用程序,它显示我们应该拥有的一些字符串:

View: XAML TextBlock bound to string property text1
      XAML.CS instantiates ViewModel vModel

ViewModel: has property text1 
           implements INotifyPropertyChanged notifying View of its changes
           instantiates Model mModel 

Model: has property string text1
       ?? implements INotifyPropertyChanged notifying ViewModel of its changes ??

在这里,我对最后一部分感到困惑。如果整个逻辑发生在模型中,例如字符串操作,如何在 ViewModel 中处理来自模型的通知?

ViewModel_PropertyChanged 是否可以通过属性名称访问和更改其属性值?我不是说:

if (e.PropertyName == "text1")

因为如果我们有很多属性,那将是一场噩梦

假设属性在 Model 和 ViewModel 中具有相同的名称,我们可以这样做:

    // Model PropertyChanged Handler
    private void mainModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        NotifyPropertyChanged(e.PropertyName);
    }


    // ViewModel PropertyChanged Notifier 
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

然后 ViewModel 可以持有一个 pass-thought 属性

    public string text1
    {
        get { return mModel.text1; }
        set { }
    }

但这是正确的吗?如果我们需要从 UI 更改此属性怎么办?:

    public string text1
    {
        get { return mModel.text1; }
        set
        {
            if (mModel.text1 != value)
            {
                mModel.text1 = value;
                NotifyPropertyChanged("text1"); // ??
            }
        }
    }

mModel.text1 = 值;- 这将通知包括 UI 在内的所有人它所做的更改 NotifyPropertyChanged("text1"); // ?? - 这将重复此通知

如果 ViewModel 只持有这个传递属性,那么它有什么需要呢?ViewModel 是否只需要对 Model 属性进行一些不同的理解以在 UI 中显示它们?

抱歉,帖子太长了,希望有人可以帮助我。

标签: c#wpfmvvm

解决方案


视图模型的作用是塑造、转换或操作数据。例如,这可能意味着提供更大列表的子集,从嵌套数据实体中展平一些属性或将数字/文本值转换为枚举。视图模型中不应存储视图特定信息(例如 SelectedIndex),视图相关信息应存储在视图后面代码的属性中(您仍然可以绑定到它)。

人们对 MVVM 的解释最大的错误是什么构成了“模型”——这是迈克尔在回答中犯的一个错误。在 MVVM 中,模型是不是视图或视图模型的任何东西。数据类是模型一部分,但不是模型(与 MVC 或其他模式中的方式不同)。事实上,在 MVVM 中,您不应该将数据类称为“模型”,将它们称为数据实体业务实体在语义上更正确。如果您遵循 n 层架构,“模型”可以包含多个层。

澄清迈克尔的图表:

                    |    
View -> ViewModel ->| BL -> DAL -> Data Entities  
                    |  
                    | -> "the model"  
                    |

我之前的这个答案可能会有所帮助:在 MVVM 设计模式中,模型是否应该包含其他模型?- 它解释了这种方法,并有一个返回 MSDN 文档的参考链接。


推荐阅读