在自定义usercontrol中使用DependencyProperty更新源

时间:2012-07-23 12:09:13

标签: wpf user-controls dependency-properties

当自定义UserControl的目标DependencyProperty发生更改时,我没有更新绑定源。

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

我的绑定在MyUserControl的根XAML中看起来像这样。

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

如果我将MyDependencyProperty与FrameworkPropertyMetadata一起使用并在属性更改时使用回调函数,我可以执行以下操作正常

// 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改变,就不是设置器。

事件的排序似乎没有问题。 ViewModel是在第一次更改DependencyProperty之前很久就创建的。

我也看了Setting up binding to a custom DependencyProperty inside a WPF user control 但他的问题似乎略有不同,因为我实际上从我自己的Base类继承了DependencyProperty。

感谢您的帮助。

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

很抱歉这个可怕的链接,我不知道很多快速的文件共享网站。如果它的评论不好,我会尽快删除它,但似乎没问题。

2 个答案:

答案 0 :(得分:0)

回复更新/无关的信息已删除

查看示例中的代码后,我看到了问题所在。你有这个“选择器”控件。在BindDependencies方法中,您在MyControlBase.MyDependencyProperty上设置了绑定。但与此同时,您还将此属性绑定到控件的datacontext(在MyUserControl.xaml中)。实际上这意味着在BindDependencies方法中你覆盖绑定到你的viewmodel因此它在该方法之后不活跃 - 你可以通过在{{之前和之后闯入1}}调用和调用SetBinding - 绑定是不同的。这就是您的代码不起作用的原因。我想你必须找到另一种方法来转移价值:)

其他一些信息

在WPF中,属性只能是一个绑定的目标。这实际上是非常合乎逻辑的 - 如果一个属性绑定到两个源 - 它应该使用哪一个?绑定被标记为BindingOperations.GetBindingExpression(control, MyUserControlBase.MyPropertyDependencyProperty)的事实在这种情况下并不重要,因为它仍然被视为针对控件属性的绑定。

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

答案 1 :(得分: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属性以更改此行为。