如何在 MVVM 模式中更新模型和视图模型?

How to update model and view model in MVVM pattern?

我正在努力在我当前的项目中实现 MVVM 模式。

"ClassA" 不断从远程设备获取所需数据并将此数据存储在其字段中。我猜这是一个模型。 ClassA 通过 Update 方法更新需要的信息。

"ClassB" 不断从"ClassA" 中获取数据并存储在相应的属性中。看起来是视图模型。

视图是一个简单的 MainWindow.xaml,内部有一个 DataGrid。

我有以下问题:

1) 如何更新 ViewModel? ClassB 是否应该有一个 Update 方法,它接受一个 ClassA 的实例并更新相应的字段?

2) 我在哪里存储 ClassA 的实例? ClassA 应该是 ClassB 的字段吗?如果应该,那么我该如何更新模型? 我想到了以下内容:

public void UpdateB()
{
    ClassA.UpdateA();
    this.FieldOne = ClassA.FieldOne;
    this.FieldTwo = ClassA.FieldTwo;
}

4) 模型是否有它的更新方法,或者模型只是存储数据?

3) 除了 windows 初始化之外,我在 MainWindow.cs 中做什么?我在那里更新视图模型 (ClassB) 吗?

如 Yuris 评论中所述,您不应使用任何更新方法,而应实现 INotifyPropertyChanged 接口。顾名思义,当某个 属性 的值发生变化时,它会通知所有订阅者。

This 是一篇不错的文章,其中包含简约 MVVM 实现的代码。如果您无法从头开始实施该模式,请尝试从这个示例开始,并用您自己的一个一个替换现有的 类。

至于 MainWindow.cs 中的更新机制 - 如果您在 xaml 代码中指定 DataBinding 就像上面链接的示例中那样,则不需要任何更新机制。

希望这对您入门有所帮助!

我发现最好有一个对象代表每个抽象层中的一个项目。这包括数据在磁盘上的形式。请记住,在 MVVM 中,唯一真正的目标是促进接口 (User Interface) 和实现 (ViewModel functionality) 之间的松散耦合。

例如,如果我将对象存储在 XML 文件中,我的数据访问层中将有一个对象仅用于正确管理 XML 数据。我们称它为 ObjectXml。此对象仅包含磁盘上数据的原生形式的数据。在这种情况下,所有数据都具有字符串表示形式,如 XML 文件中那样。

在模型层中,您将以预期的数据类型获得 XML 文件的数据表示。我们称之为 Object。 属性 getter 和 setter 可以通过执行双向转换来访问和设置数据的字符串表示形式。这样,数据就可以持久化到数据源(xml 文件、数据库等)。

ObjectViewModel 中,属性可以访问 Object 中的属性。视图模型包含用于表示和修改模型的所有成员。

请注意,ObjectXml 只有在您只能存储字符串信息或不存在适合您的数据类型的架构时才真正有用。

最后,您有一个如下所示的包含层次结构:

public class ObjectXml
{
    [XmlArray("People"), XmlArrayItem("Person")]
    public List<PersonXml> People { get; set; }
    //PersonXml is an xml data model similar to this one

    [XmlElement("Item")]
    public string Items { get; set; }
}

这是 Xml 对象的模型:

public class Object
{
    private ObjectXml _xmlContext;

    public Object(ObjectXml xmlContext)
    {
        this._xmlContext = xmlContext;
    }

    public List<Person> People
    {
        get
        {
            //Person requires a constructor that takes a PersonXml object in order for this to work properly
            return this._xmlContext.People.Select(x => new Person(x)).ToList();
        }
        set
        {
            this._xmlContext.People = value.Select(x => new PersonXml(x)).ToList();
        }
    }

    public double Item
    {
        get { return double.Parse(this._xmlContext.Item); }
        set { this._xmlContext.Item = value.ToString(); }
    }
}

显然,命名您的 class 对象是不明智的,因为它是 C# 中的保留字。希望我已经为您提供了一些关于如何以稳健和可扩展的方式访问和更新数据的想法。

简而言之,您根本不需要更新方法。此外,缺少常量和 属性 支持字段,几乎没有理由需要在 C# MVVM 中直接访问字段。

  1. See below. Do not listen to people that say the ViewModel and Model need to be decoupled. The main purpose of the model is an intermediary layer that prepares data to be saved or loaded into the program and to store data in a way that is agnostic to both the data and the program functionality(ViewModel)
  2. You do not need an update method. Use properties that access the data model and persist to the data storage(xml, database etc.) if needed.
  3. You do not need an update method.
  4. You should not have to do anything inside of ViewModel.cs. Only code that modifies the view should be in the codebehind. The only ViewModel you should ever access in a view is one that follows the form of MainWindowViewModel, which is more like an ApplicationViewModel that carries instances of other required viewmodels.

最后,不要因为使用过于复杂的 MVVM "framework" 而陷入困境,因为大多数功能都没有用或没有必要。