我有一个用户控件,其中包含三个复选框和三个日期选择器。例如,用户控件上的一个日期选择器看起来像这样(为了清晰起见,删除了无关的属性,如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对象)发送到依赖属性,它将在那里发送到虚拟机。
我希望我已经清楚地解释了这一点。任何人都能看到出了什么问题?
感谢您的帮助。
答案 0 :(得分:2)
正在解决绑定时,它正在查找正在应用它的控件的VRTSystem
上的DataContext
属性。
'DataContext'属性由子控件继承,因此如果您在DataContext
上设置Window
,则其所有子级都将具有相同的DataContext
。但是,如果其中一个子项本身已应用了不同的DataContext,则其所有子项都将使用它。
在您的情况下,Window
有一个DataContext
,UserControl
也是如此。因此,默认情况下UserControl
或它的孩子的所有绑定都会在VRTSystem
UserControls
上找到DataContext
属性,这不是您想要的。< / p>
因此,要明确定位DataContext
的{{1}},您必须通过设置其Window
属性来告诉绑定:
RelativeSource