简体   繁体   English

如何在MVVM模式中更新模型和查看模型?

[英]How to update model and view model in MVVM pattern?

I am struggling to implement MVVM pattern in my current project. 我正在努力在当前项目中实现MVVM模式。

"ClassA" continuously gets required data from a remote device and stores this data inside it's fields. “ ClassA”连续从远程设备获取所需数据,并将此数据存储在其字段中。 It is a model, I guess. 我猜这是一个模型。 ClassA updates required information via Update method. ClassA通过Update方法更新必需的信息。

"ClassB" continuously gets the data from "ClassA" and stores it in corresponding properties. “ ClassB”连续从“ ClassA”获取数据,并将其存储在相应的属性中。 Looks like it is a view model. 看起来像是一个视图模型。

View is a simple MainWindow.xaml with a DataGrid inside. 视图是一个简单的MainWindow.xaml,其中包含一个DataGrid。

I have the following questions: 我有以下问题:

1) How do I update ViewModel? 1)如何更新ViewModel? Should ClassB have an Update method, which accepts an instance of ClassA and updates corresponding fields? ClassB是否应该具有一个Update方法,该方法接受ClassA的一个实例并更新相应的字段?

2) Where do I store an instance of ClassA? 2)我在哪里存储ClassA的实例? Should ClassA be a field of ClassB? ClassA应该是ClassB的字段吗? If it should, then how do I update Model? 如果可以,该如何更新模型? I thought of something like the following: 我想到了以下内容:

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

4) Does model have it's update method at all or model just stores the data? 4)模型是否完全具有更新方法或模型仅存储数据?

3) What do I do inside MainWindow.cs, aside from windows initialization? 3)除了Windows初始化外,我还可以在MainWindow.cs中做什么? Do I update view model (ClassB) there? 我是否在那里更新视图模型(ClassB)?

I find it best to have a object representing an item in each layer of abstraction. 我发现最好在每个抽象层中都有一个代表项目的对象。 This includes the form of the data as it exists on the disk. 这包括磁盘上存在的数据形式。 Remember that in MVVM, the only real goal is to promote loose coupling between the interface( User Interface ) and the implementation( ViewModel functionality ). 请记住,在MVVM中,唯一真正的目标是促进接口( User Interface )与实现( ViewModel functionality )之间的松散耦合。

For example, if I have objects stored in XML files, I will have an object in my data access layer that exists only for the proper management of the XML data. 例如,如果我有对象存储在XML文件中,那么我的数据访问层中将有一个对象,该对象仅用于正确管理XML数据。 Let's call it ObjectXml . 我们称之为ObjectXml This object only contains data in the form that is native to the data on the disk. 该对象仅包含磁盘上数据本机形式的数据。 In this case, all data has a string representation, as in the XML files. 在这种情况下,所有数据都具有字符串表示形式,如XML文件中一样。

In the model layer, you will have the data representation of the XML file in the expected data types. 在模型层中,您将使用预期的数据类型来表示XML文件的数据。 Let's call this Object . 让我们将此Object称为。 The property getters and setters may access and set the string representation of the data by performing conversions in both directions. 属性获取器和设置器可以通过在两个方向上执行转换来访问和设置数据的字符串表示形式。 This way, the data is ready to be persisted to the data source(xml file, database etc.). 这样,就可以将数据持久保存到数据源(xml文件,数据库等)中了。

In ObjectViewModel , properties may access those in Object . ObjectViewModel ,属性可以访问Object属性。 The viewmodel contains all the members for representing and modifying the model. 视图模型包含用于表示和修改模型的所有成员。

Note that ObjectXml is really only beneficial when you are only allowed to store string information, or when a suitable schema does not exist for your data types. 请注意,只有在只允许您存储字符串信息或数据类型不存在合适的架构时, ObjectXml才真正有用。

At the end, you have a hierarchy of containment such as the one below: 最后,您将具有一个包含层次结构,例如以下所示:

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

Here is the model for the Xml object: 这是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(); }
    }
}

Obviously, it's not wise to name your class Object as it's a reserved word in C#. 显然,命名类Object是不明智的,因为它是C#中的保留字。 Hopefully I've given you some ideas of how to access and update data in a robust and extensible manner. 希望我给您一些有关如何以健壮和可扩展的方式访问和更新数据的想法。

In short, you don't need an update method at all. 简而言之,您根本不需要更新方法。 Also, short of constants and property backing fields, there are very few reasons to need direct field access in C# MVVM. 同样,由于缺少常量和属性支持字段,因此在C#MVVM中几乎没有需要直接字段访问的理由。

  1. See below. 见下文。 Do not listen to people that say the ViewModel and Model need to be decoupled. 不要听别人说需要分离ViewModelModel 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 ) 该模型的主要目的是一个中间层,该中间层准备要保存或加载到程序中的数据,并以对数据和程序功能均不可知的方式存储数据( 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. 如果需要xml, database etc.请使用访问数据模型并保留到数据存储( xml, database etc. )的属性。
  3. You do not need an update method. 您不需要更新方法。
  4. You should not have to do anything inside of ViewModel.cs . 您不必在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. 您应该在视图中访问的唯一ViewModel是遵循MainWindowViewModel形式的视图,它更像是一个ApplicationViewModel ,它带有其他所需视图模型的实例。

Finally, don't get stuck using an overcomplicated MVVM "framework" as most of the functionality is not useful or necessary. 最后,不要因为过于复杂的MVVM "framework"而陷入困境,因为大多数功能都没有用或没有必要。

Like stated in Yuris comment, you should not use any update method, but rather implement the INotifyPropertyChanged interface. 如Yuris注释中所述,您不应使用任何更新方法,而应实现INotifyPropertyChanged接口。 Like the name says this notifies all subscribers when the value of a certain Property changed. 就像名称中所说的那样,当某个Property的值更改时,这会通知所有订阅者。

This is a nice article which contains code to a minimalistic MVVM implementation. 是一篇不错的文章,其中包含用于简约MVVM实现的代码。 If you have trouble implementing the pattern from scratch, try to start with this example and replace the existing classes with your own one-by-one. 如果您无法从头开始实现模式,请尝试从本示例开始,并用自己的一对一替换现有的类。

As to the update mechanic inside your MainWindow.cs - you don't need any, if you specify the DataBinding in your xaml code like it is done in the example linked above. 至于MainWindow.cs内部的更新机制-如果您在xaml代码中指定了DataBinding,就像在上面的示例中所做的那样,则不需要任何更新。

I hope this helps you getting started! 希望这可以帮助您入门!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM