【问题标题】:MVVM - data layer of models and viewmodelsMVVM - 模型和视图模型的数据层
【发布时间】:2012-08-06 18:39:12
【问题描述】:

我正在重构我的应用程序以利用 MVVM。我曾经在我能够绑定 ListView 的 Application 类中保留一个 List<Product> 变量。这个列表构成了我的数据层。具有此 ListView 的页面是主/详细布局。使用 MVVM,我认为 List 现在应该包含 ProductModel 的实例,因为它是数据层。如果我应该绑定到 ViewModel,是否还需要一个单独的 ViewModel 列表?

【问题讨论】:

    标签: silverlight data-binding mvvm


    【解决方案1】:

    您可能需要对 MVVM 采取不同的看法。您的视图是带有控件 (XAML) 的页面,而您的 ViewModel 是数据模型和页面之间的粘合剂。 View 的整个数据上下文将设置为 ViewModel(直接在 XAML 中完成或在代码隐藏中完成,具体取决于您订阅的 MVVM 阵营)。

    在您的示例中,您会将 List<Product> 作为 ObservableCollection<Product> 移动到 ViewModel 上,并确保您的 ViewModel 实现 INotifyPropertyChanged 接口。 INotifyPropertyChanged 是视图用来知道何时更新其绑定的合同。您将使用 ObservableCollection<T> 而不是列表,因为 ObservableCollection<T> 实现了 INotifyPropertyChanged 本身。

    您的 View 的 DataContext 属性将设置为 ViewModel 的一个实例。在视图上,ListBox 控件的ItemsSource 属性将设置为绑定到Product 集合。然后,您可以在 ViewModel 中拥有负责与数据存储通信以填充可观察集合的方法。

    视图模型

    public class MyViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private ObservableCollection<Product> _products = null;
        public ObservableCollection<Product> Products
        {
           get { return _products; }
           set
           {
               if( _products != value )
               {
                   _products = value;
    
                   if( this.PropertyChanged != null )
                   {
                       this.PropertyChanged( this, new PropertyChangedEventArgs( "Products" ) );
                    }
                }
            }
         }
    
         // have code in here that loads the Products list from your data store (i.e. service call to database)
    }
    

    查看代码隐藏

    public MyView()
    {   
        InitializeComponent(); 
        this.DataContext = new MyViewModel();
    }
    

    查看

    <ListBox
        ItemsSource={Binding Path=Products, Mode=OneWay}
        SelectedItem={Binding Path=SelectedProduct, Mode=TwoWay}
        ...
    />
    

    【讨论】:

    • 好的,假设我有一个类 Cart 包含这个 List&lt;Product&gt; 以及其他一些细节。这个Cart 是一个视图模型。我需要 Product 在 Model 和 ViewModel 中表示,因为在这个 Master/Detail 布局中,有一些配置逻辑不应该在 Model 中。所以我的CartViewModel 有一个产品列表,但它们应该是 ViewModel 版本吗?
    • 你可能过于复杂了。 ViewModel 将包含许多属性供您的 View 绑定。通常每个视图都有一个视图模型(视图是指整个页面——不是站点,而是页面)。 Cart 将成为 ViewModel 上的视图模型属性。由于购物车包含产品列表,您可以通过说 ItemsSource={Binding Path=Cart.Products} 将 ListBox 绑定到该列表。
    • 看看我的回复,看看是否能澄清任何事情:stackoverflow.com/a/6154582/20133
    • 您不想要每个控件的 ViewModel,而是每个页面(不包括一些例外)。
    • 好的,谢谢您的解释。如果我错了,请纠正我,但看起来我应该有 CartViewModel(查看整个页面的模型),其中包含一个 ObservableCollection&lt;ProductViewModel&gt; 作为属性。我的 ListBox/master 将绑定到该集合,并且详细信息区域将绑定到所选项目。看起来ProductViewModel 应该包含/包装ProductModel
    猜你喜欢
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    相关资源
    最近更新 更多