直接在View中绑定模型属性 [英] Binding Model properties directly in View

查看:90
本文介绍了直接在View中绑定模型属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Prism中发现了这个文本文档。我从MVVM开始,我很迷失。可以(应该)在视图中绑定模型属性,或者我必须为模型中的每个属性创建一个具有代理属性的viewmodel?


模型类通常通过
INotifyPropertyChanged和
INotifyCollectionChanged接口提供
属性和集合更改
通知事件。
这允许他们在视图中容易地绑定数据
。模型类
表示对象的集合
通常来自
ObservableCollection类。


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



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



问题是,它的方式,我几乎将我的整个模型重建为ViewModel,而且必须保持数据同步到(ObservableCollection到列表)之间。然后我在Prism文档中看到,并且想知道我是否应该有这些麻烦,或者只是为逻辑创建一个根ViewModel,并将其余所有内容绑定到模型本身。

解决方案

确实如此,如果您的模型已经实现了INotifyPropertyChanged和/或IError信息,那么您可能希望绑定到model属性。但是,如果您想要进行特殊的验证以及该模型对您在视图模型中添加属性包装的其他内容,则不需要添加属性。



本文提供了一个很好的例子hybrid: 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(c客户中的var客户)
Customers.Add(new CustomerViewModel (客户);
}
public公司公司{get; set;}
public ObservableCollection< CustomerViewModel>客户{get; set;}
}

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

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

(这段代码可能无效,我只是在这里输入。 )



现在,如果您需要更改所有模型和所有属性的通知,您必须在模型中实现它,或者在视图模型中包装所有属性。


I've found this text in Prism documentation. I'm starting on MVVM and I'm at lost. Can (should) I bind model properties in the view or I must create a viewmodel with a proxy property for every property in the model?

The model classes typically provide property and collection change notification events through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. This allows them to be easily data bound in the view. Model classes that represent collections of objects typically derive from the ObservableCollection class.

EDIT: Here is some extra info to help. I'm building a personal project from the ground up (so I'm designing the models too), this is the first time that I use MVVM and I want to learn properly.

My model is very hieraquical, having classes with list of more class with more list inside, building a complex tree of information. I was trying the "standard" MVVM approach, build the model with POCO and no notifications, and using List. Then building the ViewModel with proper notifications and using ObservableCollections.

The problem is, the way it is going, I'm almost reconstructing my whole model as a ViewModel AND having to keep the data synched between the to (the ObservableCollection to the List). Then I read that on the Prism docs and wondered if I should have all that trouble or just create a root ViewModel for logic and bind all the rest to the model itself.

解决方案

It depends really, if your model already implements INotifyPropertyChanged and/or IError info you might want to bind right to the model property. However if you want to do special validation and other stuff that the model knows nothing about you add the property wrappers in your view model.

This article gives a good example of a hybrid: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Often my MV properties look like this and thats quite normal:

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

I often do NOT implement INotifyPropertyChanged in the model and thus often I have to write the wrappers.

EDIT: In response to your additional information: It can be a bit tricky to to keep the collections and lists in sync. In your case what I would do is to create a view model for each model class, but NOT wrap all the properties just access them like this: {Bindng Customer.Name}. But of course you have to create a wrapper for the collections which contain view models. The Prism documentation is, as they say themselves, just guidance, if your scenario needs a different approach then this is fine.

Take a look at this code. I only wrap the collections and the properties I will access through the model. This gives you the best of both worlds. Then IF you need a special property that does not belong into you model you can add it to the view model (see the CustomerViewModel), or if you need special notification for a certain properties.

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

(This code might not work, I just typed it in here.)

Now, if you need changed notification for all models and all properties you have to either implement it in you model or in wrap all properties in a view model.

这篇关于直接在View中绑定模型属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆