Twoway-bind视图的DependencyProperty到viewmodel的属性?

网上的多个源告诉我们,在MVVM ,视图和视图模型之间的通信/同步应该通过依赖属性进行。 如果我理解正确,应该使用双向绑定将视图的依赖项属性绑定到viewmodel的属性。 现在,之前已经提出了类似的问题,但没有足够的答案。

在我开始分析这个相当复杂的问题之前,这是我的问题:

如何将自定义视图的DependencyProperty与viewmodel的属性同步?

在理想的世界中,您只需将其绑定为:

  

这不起作用,因为MyProperty不是UserControl的成员。 卫生署! 我尝试了不同的方法,但没有一个certificate是成功的。

一种解决方案是定义一个基类UserControlEx ,它具有必要的依赖属性,以使上述工作正常。 然而,这很快变得非常混乱。 还不够好!

我使用Caliburn.Micro将ViewModel与View分开。 不过,它可能在MVVM中的工作方式相同。 我猜MVVM也将视图的DataContext属性设置为ViewModel的实例。

视图

 // in the class of the view: MyView public string ViewModelString // the property which stays in sync with VM's property { get { return (string)GetValue(ViewModelStringProperty); } set { var oldValue = (string) GetValue(ViewModelStringProperty); if (oldValue != value) SetValue(ViewModelStringProperty, value); } } public static readonly DependencyProperty ViewModelStringProperty = DependencyProperty.Register( "ViewModelString", typeof(string), typeof(MyView), new PropertyMetadata(OnStringValueChanged) ); private static void OnStringValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { // do some custom stuff, if needed // if not, just pass null instead of a delegate } public MyView() { InitializeComponent(); // This is the binding, which binds the property of the VM // to your dep. property. // My convention is give my property wrapper in the view the same // name as the property in the VM has. var nameOfPropertyInVm = "ViewModelString" var binding = new Binding(nameOfPropertyInVm) { Mode = BindingMode.TwoWay }; this.SetBinding(SearchStringProperty, binding); } 

VM

 // in the class of the ViewModel: MyViewModel public string ViewModelStringProperty { get; set; } 

请注意,这种实现完全缺乏INotifyPropertyChanged接口的实现。 您需要正确更新此代码。

如果你想在XAML中这样做,你可以尝试使用样式来实现它。

这是一个例子:

       

在你的情况下, MyViewPropertyMyViewModelProperty都会被命名为MyProperty但我使用不同的名称只是为了清楚什么是什么。

假设您已在View中定义了DependencyProperty“DepProp”,并希望在ViewModel(实现INotifyPropertyChanged但不实现DependencyObject)中使用完全相同的值。 您应该能够在XAML中执行以下操作:

      ...