2

在我们的应用程序中,我们有许多具有数百个属性的模型对象。

对于模型上的每个属性:

public string SubscriptionKind { get; set; }
...100x...

我们必须在ViewModel上创建一个启用 INotifyPropertyChanged 的​​属性:

#region ViewModelProperty: SubscriptionKind
private int _subscriptionKind;
public int SubscriptionKind
{
    get
    {
        return _subscriptionKind;
    }

    set
    {
        _subscriptionKind = value;
        OnPropertyChanged("SubscriptionKind");
    }
}
#endregion

...100x...

这意味着当我们的View发送Save事件时,我们必须将视图模型的所有这些值重新映射回模型:

customer.SubscriptionKind = this.SubscriptionKind
...100x...

随着模型不断变化,这变得乏味且耗时,我们必须将所有变化映射到 ViewModel 中。

过了一会儿,我们意识到将View 的 DataContext 直接连接到 Model 会更直接,这使我们能够将 XAML 元素直接绑定到 Model 对象属性,这样保存事件就可以简单地保存对象而无需任何映射任何东西。

我们在这次行动中失去的是:

  • 通过在 ViewModel 属性设置器中UpdateSourceTrigger=PropertyChanged进行细粒度验证和操作的能力,我真的很喜欢:这个我们不再拥有,因为 XAML 中的任何更改都会简单地更改模型上的哑属性

  • 能够(将来)创建模拟视图,以一种新颖的方式测试我们的视图模型的 UI 逻辑,例如“如果属性 SubscriptionKind 设置为“每年”,则 (1) 将折扣更改为 10%,(2) 运行“祝贺动画",以及 (3) 使订单按钮更加突出。

这两种方法都有明显的优势,例如第一种方式“View-direct-to-Model”方法,尤其是与LINQ-to-SQL结合使用时,非常实用,可以让您快速生成有用的软件,并且只要您使用{Binding...}而不是x:Name您仍然可以“将您的视图交给 Blend Designer”。

另一方面,尽管 MVVM 要求您维护繁琐的 Model 到 ViewModel 的映射,但它为您提供了第一种方法所没有的强大的验证测试优势。

您是如何在您的项目中结合这两种方法的优势的?

4

4 回答 4

1

Why not use a mapping tool like AutoMapper? It's speedy and you don't have to write all of that mapping code:

Mapper.CreateMap<MyModel, MyViewModel>();
MyViewModel vm = Mapper.Map(myModelInstance);

Really easy and now you get the best of both worlds.

Automapper uses a technique that generates assemblies on the fly to do the mapping. This makes it execute just as fast as if you had written all of that tedious mapping code, but you don't have to.

于 2009-10-27T18:54:16.927 回答
1

由于您的 ViewModel 可以访问模型,因此您也可以直接包装模型的属性:

#region ViewModelProperty: SubscriptionKindprivate
// int _subscriptionKind; - Use the model directly
public int SubscriptionKind
{
    get
    {
        return this.Model.SubscriptionKind;
    }
    set
    {
        if (this.Model.SubscriptionKind != value)
        {
            this.Model.SubscriptionKind = value;
            OnPropertyChanged("SubscriptionKind");
        }
    }
}
#endregion

这样做的好处是,如果您愿意,您可以将验证保留在 ViewModel 中,并且可以更好地控制如何将其设置回您的模型,但重复的地方更少。

于 2009-10-22T15:40:02.547 回答
0

由于我的模型对象是业务对象,与数据模型没有直接关系,因此我直接在 ViewModel 中使用它们。

第一个映射(数据模型到业务对象模型)和属性的创建由代码生成器生成。

于 2009-10-22T17:24:25.850 回答
0

我使用 t4 Generator 类从 XAML 创建我的 ViewModel,不确定这是否有助于您的情况。

于 2009-11-18T02:58:23.440 回答