将用户控件的依赖项属性绑定到父视图模型上的属性时出错

时间:2013-01-29 20:28:07

标签: wpf binding user-controls

我有一个用户控件,其中包含三个复选框和三个日期选择器。例如,用户控件上的一个日期选择器看起来像这样(为了清晰起见,删除了无关的属性,如Width等)......

<telerik:RadDatePicker DisplayFormat="Long"
                       SelectedValue="{Binding DepositPaidDate, Mode=TwoWay}"/>

控件的视图模型有一个名为PaidDate的公共属性,类型为PaidDate(是的,属性和类具有相同的名称),控件上的顶级Grid将其DataContext设置为PaidDate属性,Grid中的各个控件绑定到此PaidDate对象的属性。

当在窗口上使用此控件,并且后面的窗口代码显式设置控件的VM上的PaidDate属性时,一切正常。例如,我创建了一个测试窗口,其构造函数看起来像这样......

public PaidDateWindow(PaidDate paidDate, string windowTitle) {
  InitializeComponent();
  ((PaidDateControlViewModel)PaidDateCtrl.DataContext).PaidDate = paidDate;
  Title = windowTitle;
}

......这个工作得很好。我可以显示窗口,数据显示正确。

当我尝试通过控件上的依赖项属性设置此问题时,问题就出现了。用户控件后面的代码中的依赖属性看起来像这样......

public static readonly DependencyProperty PaidDateProperty = DependencyProperty.Register("PaidDate", typeof(PaidDate), typeof(PaidDateControl), new FrameworkPropertyMetadata(SetPaidDateStatic));

private static void SetPaidDateStatic(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  (d as PaidDateControl).SetPaidDate((PaidDate)e.NewValue);
}

private void SetPaidDate(PaidDate paidDate) {
  if (DataContext != null) {
    ((PaidDateControlViewModel)DataContext).PaidDate = paidDate;
  }
}

public PaidDate PaidDate {
  get {
    return (PaidDate)GetValue(PaidDateProperty);
  }
  set {
    SetValue(PaidDateProperty, value);
  }
}

正如您所看到的,依赖属性只是将PaidDate对象传递给视图模型,这与我在前一段代码中手动执行此操作具有相同的效果。

当我尝试将此依赖项属性绑定到窗口视图模型上的属性时,我收到绑定错误。这是父窗口中的XAML ...

<vrtSystemsUserControls:PaidDateControl
  PaidDate="{Binding Path=VRTSystem.PaidDate, Mode=TwoWay}" />

父窗口的VM包含一个名为VrtSystem的属性,窗口上的大量其他控件绑定到该属性上。 VrtSystem还包含一个名为PaidDate的属性,这就是我想传递给用户控件的内容。

然而,当我运行它时,我得到以下绑定错误...

System.Windows.Data Error: 40 : BindingExpression path error:
'VRTSystem' property not found on 'object' ''PaidDateControlViewModel' (HashCode=18319327)'.
BindingExpression:Path=VRTSystem.PaidDate; DataItem='PaidDateControlViewModel' (HashCode=18319327);
target element is 'PaidDateControl' (Name=''); target property is 'PaidDate' (type 'PaidDate')

现在它看起来好像WPF正在将实际绑定信息传递给用户控件而不是PaidDate对象,因为错误说它正在尝试在用户控件的VM上找到VrtSystem属性。我不知道它为什么这样做,因为我认为绑定的想法是解决窗口级别的绑定,然后将结果(即PaidDate对象)发送到依赖属性,它将在那里发送到虚拟机。

我希望我已经清楚地解释了这一点。任何人都能看到出了什么问题?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

正在解决绑定时,它正在查找正在应用它的控件的VRTSystem上的DataContext属性。

'DataContext'属性由子控件继承,因此如果您在DataContext上设置Window,则其所有子级都将具有相同的DataContext。但是,如果其中一个子项本身已应用了不同的DataContext,则其所有子项都将使用它。

在您的情况下,Window有一个DataContextUserControl也是如此。因此,默认情况下UserControl或它的孩子的所有绑定都会在VRTSystem UserControls上找到DataContext属性,这不是您想要的。< / p>

因此,要明确定位DataContext的{​​{1}},您必须通过设置其Window属性来告诉绑定:

RelativeSource