如何将视图模型属性公开为外部可绑定依赖项属性?

时间:2011-11-10 10:39:30

标签: wpf data-binding mvvm user-controls dependency-properties

我正在编写一个内部使用MVVM的WPF用户控件。为了开箱即用,它创建了自己的视图模型(这部分与问题无关)。

我的控件公开了许多依赖项属性。主机视图(使用我的控件的人)可以设置这些DP或绑定它们。其中一些DP具有相应的视图模型属性。

这就是我想要实现的目标(参见图表):我控件视图中的DP绑定到视图模型的相应属性。此外,主机视图也需要能够设置或绑定这些DP - 与使用任何其他控件的方式相同。

但是,只要主机视图设置或绑定DP的值,原始绑定(将其内部绑定到控件的视图模型)就会丢失。这是因为每个DP只能有一个绑定集。所以这不起作用:

Diagram of what doesn't work

一种解决方案是使视图模型成为DependencyObject及其属性DP。这样,我可以将控件的视图模型绑定到其视图而不是相反,从而有效地反转左箭头。但是,出于各种原因,我希望我的视图模型使用普通的C#属性和INotifyPropertyChanged。

关于如何将视图模型属性公开为外部可绑定依赖项属性的任何想法?

编辑:

澄清要求:视图实际上并不创建视图模型本身(我意识到这会违反关注点的分离);相反,它使用视图模型定位器来执行此操作。 (这是一个非常模块化的企业应用程序。)我知道这不是一种典型的方法(参见Rachel的回答)。但是,接受所描述的设置,有没有办法达到预期的效果?

2 个答案:

答案 0 :(得分:1)

如果我为ViewModel创建CustomControl,则预计用户将使用该ViewModel作为CustomControl.DataContext。在任何其他时间,我的UserControl都没有与它们关联的ViewModels。

例如,假设我想要一个PopupControl。

我要创建一个UserControl,其中包含代码隐藏UserControl(无ViewModel)

中的所有自定义属性和逻辑
<local:Popup Header="{Binding PopupHeader}"
             IsVisible="{Binding IsVisible}" />

我会创建一个PopupViewModel并构建我的PopupUserControl,期望DataContext的类型为PopupViewModel

<DataTemplate DataType="{x:Type local:PopupViewModel}">
    <local:PopupView />
</DataTemplate>

<ContentControl Content="{Binding MyPopupViewModel}" />

IsVisiblePopupHeader等属性会存在于ViewModel中,而不会出现在PopupUserControl

答案 1 :(得分:1)

所以情况是你有VM和View,他们必须是彼此绑定的数据,VM不能DependencyObject?好吧,三重绑定VM-V-Host是不可能的,AFAIK。

一种可能的方法是在View中制作DependencyProperties的重复集。原始属性将绑定到VM并将影响View的外观,重复属性将绑定到Host并以某种方式影响VM(例如,使用DP更改逻辑)。

相关问题