我会解释我的意思。
我们说我将TextBox包装到UserControl中并公开属性 Id 要绑定到此属性,它必须是Dependency属性。好的,这里我们去(注意愚蠢的舞蹈与OnIdChanged调用属性setter所以我们得到INotifyPropertyChanged工作):
public static readonly DependencyProperty IdProperty =
DependencyProperty.RegisterAttached("Id", typeof(string), typeof(MyTextBox), new PropertyMetadata(OnIdChanged));
public string Id
{
get
{
return (string)GetValue(IdProperty);
}
set
{
this.SetValue(IdProperty, value);
this.OnPropertyChanged("Id");
}
}
private static void OnIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as Lookup).Id = e.NewValue as string;
}
所以,这似乎就是我所需要的。我创建另一个用户控件。删除MyTextBox:
<Lookup:MyTextBox Id="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.CurrentItem.DeviceId, Mode=TwoWay, NotifyOnValidationError=True}"/>
如您所见 - 我必须使用DataContextProxy。说实话,这对我来说有点神奇,我曾经做过一次并且在常规方式没有约束力的时候尝试过。我该如何编写用户控件代码,以便我可以像这样绑定它?
<Lookup:MyTextBox Id="{Binding Path=CurrentItem.DeviceId, Mode=TwoWay, NotifyOnValidationError=True}"/>
这就是我可以将TextBox绑定到自定义文本旁边的方法,它可以按预期工作。秘密是什么?
修改
以下是2个截图。第一个展示了当我绑定到Lookup控件(自定义UserControl)时我获取的源代码 - 指向SELF
第二个 - 我的XAML中的下一个字段 - 是常规文本框,绑定到同一个CurrentItem但它来自我的ViewModel
编辑2
我想为什么DataContext指向UserControl本身。我想为什么但不明白为什么......
在初始化之后我的UserControl(查找)代码中我设置了this.DataContext =这样内部控件它绑定到内部属性。它以某种方式传播到父ViewModel。我将此代码更改为LayoutRoot.DataContext = this - 问题已解决。但我不明白为什么它会像这样,我仍然无法获得良好的物业路线..
答案 0 :(得分:2)
我在I wrote some time ago的博文中介绍了这个问题。如果将UserControl的DataContext设置为自身,则不能再将其放在另一个UserControl或Window中,并期望它继承其父级的DataContext。这意味着您不能只将它放在视图中并指定视图模型的绑定。原因是您已阻止ViewModel DataContext的继承。 UserControl公开的任何属性都将其绑定Source设置为UserControl。
解决方案是将UserControl中的某些元素的DataContext设置为UserControl本身。通常,您可以设置UserControl的直接子项。