【问题标题】:Binding Model properties directly in View直接在视图中绑定模型属性
【发布时间】:2011-08-14 03:17:43
【问题描述】:

我在 Prism documentation 中找到了这段文字。我从 MVVM 开始,我迷路了。我可以(应该)在视图中绑定模型属性,还是必须为模型中的每个属性创建一个具有代理属性的视图模型?

模型类通常提供 财产和收藏变更 通过通知事件 INotifyPropertyChanged 和 INotifyCollectionChanged 接口。 这使他们可以轻松地成为数据 绑定在视图中。模型类 表示对象的集合 通常来源于 ObservableCollection 类。

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

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

问题是,就目前而言,我几乎要将整个模型重建为 ViewModel,并且必须在 to(ObservableCollection 到列表)之间保持数据同步。然后我在 Prism 文档上阅读了该内容,想知道我是否应该遇到所有这些麻烦,或者只是为逻辑创建一个根 ViewModel 并将所有其余部分绑定到模型本身。

【问题讨论】:

    标签: data-binding mvvm model prism


    【解决方案1】:

    这真的取决于,如果您的模型已经实现 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;
         }
      }
     }
    

    (这段代码可能不起作用,我只是在这里输入的。)

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

    【讨论】:

    • 我编辑了我的问题,添加了有关我手头项目的更多信息,以及我提出这个问题的原因。
    • 嘿,我学习了更多,我想我终于接受了我的要求。我将在我的模型中使用 IDataErrorInfo、INotifyPropertyChanged 和 ObservableCollection。它们不是 WPF 特定的,它们几乎可以解决我的所有问题。
    • 是的,它们位于 System.ComponentModel 命名空间中,应该用于创建域模型(这就是为什么 Collection 存在而没有 List 的原因,因为您的模型应该公开集合而不是列表等)。无论如何,你会在那里发现很多有趣的东西。有时由于各种原因,您无法将 INorifyChanged 添加到模型中,但在您的情况下,这可能是有道理的。还要确保对更改的通知使用类似的内容:csharperimage.jeremylikness.com/2010/06/…。使重构更容易。
    • 谢谢,我正在(重新)规划模型和视图模型,另外,我正在考虑改变视图模型的方法(这个概念对我来说仍然有点陌生,但我我明白了)。此外,Prism 有 NotificationObject 暴露 RaisePropertyChanged,它真的很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2020-07-20
    • 2013-03-22
    • 2010-12-02
    • 2011-05-22
    • 2020-07-01
    • 1970-01-01
    相关资源
    最近更新 更多