我对如何在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中定义?
我认为Window会在窗口的XAML中通过
进行绑定{Binding ElementName=myUserControl, Path=SelectedItems}
或
{Binding Path=MyViewModel.SelectedItems}
通过前者做这件事似乎更有意义,因为后者要求View了解另一个VM?
答案 0 :(得分:2)
>其他控件应如何使用我的UserControl?
仅通过用户控件上的公开依赖属性。
>消费者应该直接绑定到VM还是应该只复制这些属性的子集?我想实际用作UserControl的DependencyProperties?
每个控件都应该是一个独立的实体,不应该有任何秘密握手(使用或来自)来使用控件。想想你是微软的设计,很多不同的用户都会使用你的控件。所以答案#1就是相关的;想一个独立的实体。
>我认为理想的解决方案是通过UserControl中的依赖项属性公开ListBox的SelectedItems,然后使用UserControl的Window将绑定到这些。
托管控件的窗口将包含一个View Model,其中包含一个Observable数据项列表。这将保存用户控件将通过其依赖属性绑定的数据。把它当作许多消费者的生产者模式。消费者是控制者。控件是否具有VM对于主程序的运行并不重要;每个控件都是自己的岛屿。
答案 1 :(得分:2)
在使用WPF和MVVM时请记住,View
图层只是一种用户友好的方式来绘制Models
和ViewModels
,以及View
实际上不是你的申请。您的View
实际上必须了解有关数据层的基础知识,以便定义如何绘制数据层。
因此,如果您的应用程序需要显示Items
列表并保持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
< / p>
<DataTemplate DataType="{x:Type local:SomeViewModel}">
<local:MyUserControl />
</DataTemplate>
<ContentPresenter Content="{Binding SomeViewModelProperty}" />
此外,您在任何时候都不应在DataContext
内部设置UserControl
的{{1}},因为UI图层仅用于表示数据层的UI (您的UserControl
/ Models
),并通过设置ViewModels
内部的数据层,以便UserControl
无法用于绘制任何其他数据对象