我有一个wpf用户控件,它公开了一个自定义依赖项属性。在用户控件内部,一个文本块绑定(bind)到dp的值。此数据绑定(bind)在所有情况下都适用,但数据源是对象时除外。
重现此代码所需的最少代码是:
这是用户控件的主要部分
<StackPanel Orientation="Horizontal">
<TextBlock Text="**SimpleUC** UCValue: "/>
<TextBlock Text="{Binding UCValue}"/>
</StackPanel>
以及后面的用户控制代码:
public SimpleUC()
{
InitializeComponent();
this.DataContext = this;
}
public string UCValue
{
get { return (string)GetValue(UCValueProperty); }
set { SetValue(UCValueProperty, value); }
}
public static readonly DependencyProperty UCValueProperty =
DependencyProperty.Register("UCValue", typeof(string), typeof(SimpleUC), new UIPropertyMetadata("value not set"));
这是测试窗口。我将项目xml命名空间导入为“custom”
<Window.Resources>
<Style TargetType="{x:Type StackPanel}">
<Setter Property="Margin" Value="20"/>
</Style>
</Window.Resources>
<StackPanel>
<StackPanel>
<TextBlock Text="This fails to bind:"/>
<custom:SimpleUC UCValue="{Binding SomeData}"/>
</StackPanel>
<StackPanel>
<TextBlock>The same binding on a regular control like Label</TextBlock>
<Label Content="{Binding SomeData}"/>
</StackPanel>
<Slider x:Name="sld" />
<StackPanel>
<TextBlock>However, binding the UC to another element value, like a slider works</TextBlock>
<custom:SimpleUC UCValue="{Binding ElementName=sld,Path=Value}"/>
</StackPanel>
</StackPanel>
而后面的测试窗口代码是:
public TestWindow()
{
InitializeComponent();
this.DataContext = this;
}
//property to bind to
public string SomeData { get { return "Hello S.O."; } }
当我在TestWindow上打开诊断跟踪时,它会弹出错误“BindingExpression路径错误:
'SomeData' property not found on 'object' ''SimpleUC' (Name='')' ... "
绑定(bind)表达式与我在相邻标签中使用的表达式相同,并且效果很好。这种行为对我来说似乎很奇怪。谁能给我一些启示? 最佳答案
您在这里将SimpleUC的DataContext设置为其自身
public SimpleUC()
{
InitializeComponent();
this.DataContext = this; // wrong way!
}
所以当你在这里使用绑定(bind)
<custom:SimpleUC UCValue="{Binding SomeData}"/>
它在控件的数据上下文中搜索设置为该对象的属性SomeData,因为SimpleUC构造函数中的代码将覆盖DataContext的值,并且不再像您期望的那样将其设置为TestWindow对象。这就是您的解决方案起作用的原因-它不会影响从window继承的DataContext。您也可以保留
this.DataContext = this;
,但可以像这样设置元素在何处显式搜索属性(跳过无关)<Window ... Name="wnd1">
<custom:SimpleUC UCValue="{Binding SomeData, ElementName=wnd1}"/>
...
但是我的观点是,答案的变体对我来说更方便,为此设置数据上下文不是一个很好的做法。
希望能帮助到你。