直接在视图中绑定模型属性

直接在视图中绑定模型属性

问题描述:

我在棱镜documentation中找到了该文本。我从MVVM开始,我迷路了。我可以(应该)在视图中绑定模型属性,或者我必须为模型中的每个属性创建一个包含代理属性的视图模型?直接在视图中绑定模型属性

模型类通常提供 财产和收集变化 通知通过 INotifyPropertyChanged的和事件 INotifyCollectionChanged接口。 这使得他们可以很容易地在视图中绑定数据 。 表示对象集合 的模型类通常来自 ObservableCollection类。

编辑:这里有一些额外的信息来帮助。我从头开始构建个人项目(所以我也在设计模型),这是我第一次使用MVVM,并且我想要正确地学习。

我的模型是非常层次的,有更多类的列表,里面有更多列表,构建一个复杂的信息树。我正在尝试“标准”MVVM方法,使用POCO构建模型并且没有通知,并使用List。然后用适当的通知并使用ObservableCollections构建ViewModel。

问题是,它的方式,我几乎重建我的整个模型作为ViewModel AND必须保持之间的数据同步(ObservableCollection到列表)。然后我阅读了Prism文档,并想知道是否应该有所有这些麻烦,或者只是创建一个用于逻辑的根视图模型,并将所有其他模型绑定到模型本身。

实际上,如果您的模型已经实现INotifyPropertyChanged和/或IError信息,您可能希望将其绑定到模型属性。但是,如果你想做特殊验证和其他模型一无所知的东西,请在视图模型中添加属性包装器。

本文给出了一种混合的一个很好的例子:很正常http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

通常我的MV属性看起来像这样和多数民众:

public string Symbol 
    { 
     get { return Model.Symbol; } 
     set { Model.Symbol = value; this.NotifyOfPropertyChange(() => this.Symbol); } 
    } 

我常常不执行INotifyPropertyChanged模型,因此经常我必须写封装。

编辑:回复您的其他信息:保持同步收藏和列表可能有点棘手。在你的情况下,我会做的是为每个模型类创建一个视图模型,但不包装所有的属性只是像这样访问它们:{Bindng Customer.Name}。但是,当然你必须为包含视图模型的集合创建一个包装器。 Prism文档正如他们自己所说的那样,只是指导,如果您的场景需要不同的方法,那么这很好。

看看这段代码。我只包装我将通过模型访问的集合和属性。这给你两全其美。如果你需要一个不属于你的模型的特殊属性,你可以将它添加到视图模型中(请参阅CustomerViewModel),或者如果你需要特定的属性通知。

class CompanyViewModel{ 
    public CopanyViewModel(Company c){ 
    foreach(var customer in c.Customers) 
     Customers.Add(new CustomerViewModel(customer); 
    } 
    public Company Company {get;set;} 
    public ObservableCollection<CustomerViewModel> Customers {get;set;} 
} 

class CustomerViewModel{ 
    public CustomerViewModel(Customer c){ 
    Customer = c; 
    } 
    public Customer Customer {get;set;} 

    public Brush CustomerBackground{ 
    get{ 
     if(Customer.Active) 
      return Brush.Greeen; 
     else 
      return Brush.Red; 
    } 
    } 
} 

(此代码可能无法正常工作,我只是键入它在这里。)现在

,如果你需要更改的通知适用于所有型号,你必须在你的模型要么实现它所有的属性或包装视图模型中的所有属性。

+0

我编辑了我的问题,添加了关于我手头项目的更多信息,以及为什么我提出了这个问题。 – 2011-04-27 23:32:33

+0

嘿,我研究了一些,我想我最终达成了我的要求。我将在我的模型中使用IDataErrorInfo,INotifyPropertyChanged和ObservableCollection。他们不是WPF特有的,他们将解决几乎所有的问题。 – 2011-04-29 11:31:58

+0

是的,它们位于System.ComponentModel命名空间中,它应该用于创建域模型(这就是为什么Collection 是例如没有List ,因为你的模型应该公开Collection而不是列表等)。无论如何,你会发现很多有趣的事情。有时你不能将INorifyChanged添加到你的模型中,原因很多,但在你的情况下,这可能是有道理的。另外请确保你使用类似这样的改变通知:http://csharperimage.jeremylikness.com/2010/06/tips-and-tricks-for-inotifypropertychan.html。使重构更容易。 – lukebuehler 2011-04-29 14:56:10