将根的属性绑定到XAML中的子元素的值
我不太习惯WPF,所以这可能是简单的,但我一直在挣扎几个小时,似乎无法得到正确地做到这一点。将根的属性绑定到XAML中的子元素的值
说我有一个BaseUserControl
从UserControl
下降与依赖属性Text
。
然后在XAML中创建一个BaseUserControl后裔。我希望该属性Text
被绑定到在该后代中定义的控件。你说:
<base:BaseUserControl
... all namespaces ...
xmlns:base="clr-namespace:MyControlsBase"
x:Class="Test.MyTestControl"
Text="{Binding ElementName=MyTextBox, Path=Text}"
<TextBox x:Name="MyTextBox" Text="MyText" />
</base:BaseUserControl>
出于某种原因,我不能让MyTextBox
以更新控制自身的Text
财产。
如果我添加一个:
<TextBlock Text="{Binding ElementName=MyTextBox, Path=Text}" />
任何地方控制里面,文本块显示正确的文本框的值,因此绑定定义似乎并不成为问题。
我有别的东西这表明在该控制Text
价值......这样说:
<Window>
<StackPanel>
<test:MyTestControl x:Name="MyControl" />
<TextBlock Text="{Binding ElementName=MyControl, Path=Text}" />
</StackPanel>
</Window>
如果我更新来自任何其他方式在MyControlBase Text属性(代码隐藏,或其他),它可以工作,并且我看到文本块上的文本发生了变化......但是当它自己内部的文本框被更新时,它似乎无法更新。
当您继承控件时,绑定属性是否有任何限制?
PS:代码显然是人为的,boilerplated这个问题
注意:有明显有毛病该财产的结合,因为在跟踪窗口上,创建控件时,我得到:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=MyTextBox'. BindingExpression:Path=Text; DataItem=null; target element is 'MyTestControl' (Name=''); target property is 'Text' (type 'String')
但它只会发生在`MyTestControl的财产,而不是为了其他任何绑定到XAML中相同的属性。
我相信问题是当BaseUserControl初始化自己并尝试使用MyTextBox的Text属性进行绑定时,MyTextBox尚未初始化。在这个阶段,MyTextBox不存在,因此你得到'System.Windows.Data Error:4:无法找到SOURCE与参考绑定。
您可以在您的MyTestControl的CTOR中的InitializeComponent()之后绑定代码隐藏。
public MyTestControl()
{
InitializeComponent();
Binding b = new Binding("Text");
b.Source = MyTextBox;
SetBinding(TextProperty, b);
}
这可以工作,我将它标记为答案...但是,我已经尝试相同,但使用'b.ElementName =“MyTextBox”'而不是'b.Source = MyTextBox'(在构造对象之后),并且它不能在代码隐藏中使用(同样的问题,“用ElementName找不到源代码='MyTextBox'')。 这绝对不是关键,但我想了解为什么它不起作用。 – Jcl 2014-11-08 11:28:02
刚刚在.NET Framework 4和4.5中测试过,b.ElementName =“MyTextBox”的工作方式与b.Source相同。不知道你为什么不工作。 – Eben 2014-11-08 12:29:44
这真的很奇怪。诸如任何其他容器(不是UserControl)的类似绑定方案都可以很好地工作。虽然原因尚不清楚,但您可以尝试反向绑定(目标是“MyTextBox”,源代码是usercontrol,当然应该使用双向绑定模式)。 – 2014-11-08 07:07:24
这是行不通的,因为我不能指定一个名字('BaseUserControl'会是抽象的)。我可以为类型'BaseUserControl'做一个'FindAncestor',但那不是一般的(它可以在其中找到其他的'BaseUserControls') – Jcl 2014-11-08 11:30:05