我正在编写一个内部使用MVVM的WPF用户控件。为了开箱即用,它创建了自己的视图模型(这部分与问题无关)。
我的控件公开了许多依赖项属性。主机视图(使用我的控件的人)可以设置这些DP或绑定它们。其中一些DP具有相应的视图模型属性。
这就是我想要实现的目标(参见图表):我控件视图中的DP绑定到视图模型的相应属性。此外,主机视图也需要能够设置或绑定这些DP - 与使用任何其他控件的方式相同。
但是,只要主机视图设置或绑定DP的值,原始绑定(将其内部绑定到控件的视图模型)就会丢失。这是因为每个DP只能有一个绑定集。所以这不起作用:
一种解决方案是使视图模型成为DependencyObject及其属性DP。这样,我可以将控件的视图模型绑定到其视图而不是相反,从而有效地反转左箭头。但是,出于各种原因,我希望我的视图模型使用普通的C#属性和INotifyPropertyChanged。
关于如何将视图模型属性公开为外部可绑定依赖项属性的任何想法?
编辑:
澄清要求:视图实际上并不创建视图模型本身(我意识到这会违反关注点的分离);相反,它使用视图模型定位器来执行此操作。 (这是一个非常模块化的企业应用程序。)我知道这不是一种典型的方法(参见Rachel的回答)。但是,接受所描述的设置,有没有办法达到预期的效果?
答案 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}" />
IsVisible
或PopupHeader
等属性会存在于ViewModel
中,而不会出现在PopupUserControl
答案 1 :(得分:1)
所以情况是你有VM和View,他们必须是彼此绑定的数据,VM不能DependencyObject
?好吧,三重绑定VM-V-Host是不可能的,AFAIK。
一种可能的方法是在View中制作DependencyProperties
的重复集。原始属性将绑定到VM并将影响View的外观,重复属性将绑定到Host并以某种方式影响VM(例如,使用DP更改逻辑)。