1

我对如何在 MVVM 中布局我的代码感到有些困惑——如果我有一个带有相应 VM 类的 UserControl,其他控件应该如何使用我的 UserControl?

消费者应该直接绑定到 VM,还是应该只复制这些属性的子集,我想实际用作 UserControl 的 DependencyProperties?

就此而言,应该将 UserControl 的 VM 注入到 UserControl 的代码隐藏中,还是应该将使用此 UserControl 的任何控件的 VM 包含它作为依赖项并将其绑定到 UserControl?

为了清楚起见:假设我在 UserControl 中有一个 ListBox,并在已经用 MVVM 实现的 Window 中使用它。但我对 UserControl VM 和相应绑定的实现感到困惑。

我认为理想的解决方案是通过 UserControl 中的依赖属性公开 ListBox 的 SelectedItems,然后使用 UserControl 的 Window 将绑定到这些。

或者 Window 的 VM 是否应该将 VM 作为属性进行引用,是否将其注入并直接绑定到其上的属性?

依赖属性应该只在 UserControls 中定义还是可以/应该在 VM 中定义?

我认为窗口会从窗口的 XAML 中绑定,或者通过

{Binding ElementName=myUserControl, Path=SelectedItems}

或者

{Binding Path=MyViewModel.SelectedItems} 

通过前者似乎更有意义,因为后者要求 View 知道另一个 VM?

4

2 回答 2

2

使用 WPF 和 MVVM 时请记住,您的View图层只是一种用户友好的方式来绘制您的Modelsand ViewModels,并且您View实际上并不是您的应用程序。您View实际上必须了解有关数据层的基础知识,以便它可以定义如何绘制它。

因此,如果您的应用程序需要显示Items并维护 a的列表SelectedItem,那么它应该在您的 ViewModel 或 Model 的某个地方,而不是在实际的 View 层中。

通常对我来说,UserControls 是以下两种情况之一:

  • UserControl可以在任何地方使用而无需特定的独立,DataContext并且可以公开DependencyProperties任何特定于控件的值。示例是Calendar控件或Popup控件之类的东西

    <local:MyUserControl Items="{Binding SomeItemList}" 
                         SelectedItem="{Binding SomeItem}" />
    
  • 或者它们是UserControl用于特定的ViewModel。这对我来说更常见。ViewModel 是数据层某处的一个属性,我通常DataTemplate在应用程序中的某个地方隐含告诉 WPF 在UserControl它需要呈现特定的任何时候使用它ViewModel

    <DataTemplate DataType="{x:Type local:SomeViewModel}">
        <local:MyUserControl />
    </DataTemplate>
    
    <ContentPresenter Content="{Binding SomeViewModelProperty}" />
    

此外,任何时候都不应从内部设置DataContexta ,因为 UI 层仅是数据层(您的/ )的 UI 表示,并且通过从内部设置数据层UserControlUserControlModelsViewModelsUserControl您正在制作它以便UserControl不能用于绘制任何其他数据对象。

于 2012-11-08T15:34:08.477 回答
2

> 其他控件应该如何使用我的 UserControl?

仅通过用户控件上的暴露依赖属性。

> 消费者应该直接绑定到 VM,还是应该只复制这些属性的子集,我想实际用作 UserControl 的 DependencyProperties?

每个控件都应该是一个独立的实体,不应该有任何秘密握手(来往或来自)来使用该控件。把你的设计想象成微软,许多不同的用户会使用你的控件。所以答案#1同样相关;认为一个独立的实体。

>我认为理想的解决方案是通过 UserControl 中的依赖属性公开 ListBox 的 SelectedItems,然后使用 UserControl 的窗口将绑定到这些。

托管您的控件的窗口将有一个视图模型,其中包含一个可观察的数据项列表。这将保存用户控件将通过其依赖属性绑定的数据。将其视为具有许多消费者的生产者模式。消费者是控制者。控件是否有虚拟机与主程序的运行无关;因为每个控件都是它自己的岛。

于 2012-11-08T14:57:01.457 回答