2012-07-23 16 views
0

当自定义UserControl的目标DependencyProperty更改时,我得到的绑定源不会更新。在自定义用户控件中使用DependencyProperty更新源代码

源代码是一个加载了MEF的ViewModel到我的自定义UserControl的DataContext中。

我的结合看起来像这样的的MyUserControl

// MyUserControl.xaml 
<MyUserControlBase x:Class="MyUserControl" MyDependencyProperty="{Binding ViewModelProperty}"> 

如果我使用MyDependencyProperty与FrameworkPropertyMetadata和使用回调函数,当属性的变化,我可以做哪些工作正常,以下根XAML

// MyUserControlBase.cs 
private static void MyDependencyProperty_Changed(DependencyObject depObj, DependencyPropertyChangedEventArgs args) 
{ 
    var filter = (UserControl)depObj; 
    var vm = (ViewModel)filter.DataContext; 
    vm.ViewModelProperty= (VMPropType)args.NewValue; 
} 

在继承UserControl的MyUserControlBase中注册DependencyProperty。

// MyUserControlBase.cs 
public static readonly DependencyProperty MyDependencyPropertyProperty = DependencyProperty.Register("MyDependencyProperty", 
      typeof(VMPropType), 
      typeof(MyUserControlBase), 
      new FrameworkPropertyMetadata(null, MyDependencyProperty_Changed)); 

但是为什么我不能在XAML中完成简单的双向绑定工作?

输出窗口显示没有绑定失败。我可以看到正在调用ViewModel.ViewModelProperty getter。一旦MyDependencyProperty发生变化,就不要使用setter。

它似乎不是事件顺序的问题。 ViewModel在DependencyProperty第一次被改变之前就已经创建好了。

我也看过Setting up binding to a custom DependencyProperty inside a WPF user control 但他的问题似乎稍有不同,因为我actualy从我自己的基类持有DependencyProperty继承。

谢谢你的帮助。

编辑:链接到示例解决方案。 Solution zip here

对不起,可怕的链接,我不知道很多快速fileshareing网站。如果它的坏评论,我会尽快删除它,但它似乎确定。

+0

请在注册依赖项属性的位置填写代码。 – Jefim 2012-07-23 12:48:40

回答

0

回答更新/不相干的信息删除

看你的样品中的代码,我看到的问题是什么之后。你有这个“选择器”控制。在BindDependencies方法中,您在MyControlBase.MyDependencyProperty上设置绑定。但同时你也将这个属性绑定到你的控件的datacontext(在MyUserControl.xaml)。实际上,这意味着在BindDependencies方法中,您将覆盖绑定到您的viewmodel,因此在该方法之后它不是活动的 - 您可以通过分入SetBinding呼叫之前和之后来访问并调用BindingOperations.GetBindingExpression(control, MyUserControlBase.MyPropertyDependencyProperty) - 绑定是不同的。这就是为什么你的代码不起作用。我想你必须找到转移的价值有:)

一些额外的信息

在WPF属性只能有一个绑定的目标的另一种方式。这实际上非常合乎逻辑 - 如果一个属性绑定到两个源 - 它应该使用哪一个?绑定被标记为OneWayToSource的事实在这种情况下并不重要,因为它仍然作为绑定来对待控件的属性。

您可以调查并查看它是否适用于您的一种方法是MultiBinding - 它允许通过实施您自己的IMultiValueConverter将控件的属性绑定到多个源。您可以在所提供的链接中的MSDN上找到关于此的更多信息。

0

你暴露ViewModelProperty作为一个普通的属性..

通常你做以下....

public static readonly DependencyProperty ViewModelPropertyProperty = DependencyProperty.Register("ViewModelProperty", 
      typeof(VMPropType), 
      typeof(MyUserControlBase), 
      new FrameworkPropertyMetadata(null, ViewModelProperty_Changed)); 

public VMPropType ViewModelProperty { 
    get { return (VMPropType)GetValue(ViewModelPropertyProperty); } 
    set { SetValue(ViewModelPropertyProperty,value); } 
} 

编辑 - 注释之后。

你什么时候检查房屋改变了?默认情况下,WPF绑定仅在失去焦点时更新值,您更改更改绑定的UpdateSourceTrigger属性以改变此行为。

+0

在MyUserControlBase_Changed方法中,它是DependencyProperty的Register方法的回调。 DependencyPropertyChangedEventArgs.NewValue显示正确。它只是不更新​​我的XAML绑定源。我已经尝试使用UpdateSourceTrigger = PropertyChanged。 – CodeMonkey 2012-07-23 14:39:31

+0

您可以在ViewModelProperty的实际设置器中添加一个检查。您可能检查得太早,而且这种变化还没有经过级联。 – 2012-07-23 14:42:36

+0

我已经做到了,但只有当我做'新的MyUserControl()“和MEF创建ViewModel时才会被命中。我得到了两个get的返回null和一个赋值为null的集合。之后,我看到一个在MyUserControlBase上的过程.MyDependencyProperty_Changed其中args包含正确的值,但ViewModel中没有任何更改。 – CodeMonkey 2012-07-23 15:25:43

相关问题