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

时间:2015-04-09 13:20:32

标签: c# .net design-patterns mvvm data-binding

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

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

" ClassB的"持续获取来自" ClassA"的数据。并将其存储在相应的属性中。看起来它是一个视图模型。

View是一个简单的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)吗?

2 个答案:

答案 0 :(得分:1)

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

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

在模型层中,您将在预期的数据类型中拥有XML文件的数据表示。我们称之为Object。属性getter和setter可以通过在两个方向上执行转换来访问和设置数据的字符串表示。这样,数据就可以保存到数据源(xml文件,数据库等)。

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

请注意,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(); }
    }
}

显然,将类Object命名为C#中的保留字是不明智的。希望我已经给你一些关于如何以健壮和可扩展的方式访问和更新数据的想法。

简而言之,您根本不需要更新方法。此外,缺少常量和属性支持字段,在C#MVVM中需要直接字段访问的原因很少。

  
      
  1. 见下文。不要听那些说ViewModelModel需要解耦的人。该模型的主要目的是一个中间层,用于准备要保存或加载到程序中的数据,并以与数据和程序功能无关的方式存储数据(ViewModel
  2.   
  3. 您不需要更新方法。如果需要,使用访问数据模型的属性并持久保存到数据存储(xml, database etc.)。
  4.   
  5. 您不需要更新方法。
  6.   
  7. 你不应该在ViewModel.cs内做任何事情。只有修改视图的代码才应该在代码隐藏中。您应该在视图中访问的唯一ViewModelMainWindowViewModel形式的ApplicationViewModel,更像是MVVM "framework",其中包含其他所需视图模型的实例。
  8.   

最后,不要因使用过于复杂的{{1}}而陷入困境,因为大多数功能都没用或者没必要。

答案 1 :(得分:0)

如同Yuris评论中所述,您不应使用任何更新方法,而应实施INotifyPropertyChanged接口。就像名称所说,当某个属性的值发生变化时,这会通知所有订阅者。

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

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

我希望这有助于您入门!