数据绑定到WPF中的UserControl [英] Data binding to a UserControl in WPF
问题描述
我有一个要参与数据绑定的UserControl.我已经在用户控件中设置了依赖项属性,但无法使其正常工作.
I have a UserControl that I want to participate in data binding. I've set up the dependency properties in the user control, but can't get it work.
当我用静态文本(例如BlueText ="ABC")调用时,uc显示正确的文本.当我尝试将其绑定到本地公共财产时,它总是空白.
The uc displays the correct text when I call it with static text (e.g BlueText="ABC") . When i try to bind it to a local public property, it is always blank.
<src:BlueTextBox BlueText="Feeling blue" /> <!--OK-->
<src:BlueTextBox BlueText="{Binding Path=MyString}" /> <!--UserControl always BLANK!-->
<TextBox Text="{Binding Path=MyString}" Width="100"/> <!--Simple TextBox Binds OK-->
我将代码简化为以下简化示例.这是UserControl的XAML:
I've boiled the code down to the following simplified example. Here is the XAML of the UserControl:
<UserControl x:Class="Binding2.BlueTextBox" ...
<Grid>
<TextBox x:Name="myTextBox" Text="{Binding BlueText}" Foreground="Blue" Width="100" Height="26" />
</Grid>
以下是UserControl的代码:
Here is the code behind of the UserControl:
public partial class BlueTextBox : UserControl
{
public BlueTextBox()
{
InitializeComponent();
DataContext = this; // shouldn't do this - see solution
}
public static readonly DependencyProperty BlueTextProperty =
DependencyProperty.Register("BlueText", typeof(string), typeof(BlueTextBox));
public string BlueText
{
get { return GetValue(BlueTextProperty).ToString(); }
set { SetValue( BlueTextProperty, value.ToString() ); }
}
这似乎应该很简单,但我无法使其正常工作.感谢您的帮助!
This seems like it should be really easy, but I can't make it work. Thanks for your help!
更多信息:当我尝试Eugene建议的修复程序时,我注意到一些奇怪的行为.我在元数据中添加了PropertyChangedCallback;这使我可以看到BlueText设置的值.将字符串设置为静态值(="feeling blue")时,将触发PropertyChanged事件.数据绑定案例不触发PropertyChanged.我认为这意味着数据绑定值没有被发送到UserControl.(我认为在静态情况下不会调用构造函数)
More info: When i was trying the fix suggested by Eugene, I noticed some peculiar behavior. I added a PropertyChangedCallback to the metadata; this allows me to watch the value of BlueText getting set. When setting the string to a static value (="feeling blue") the PropertyChanged event fires. The data binding case does not fire PropertyChanged. I think this means the data-bound value is not getting sent to the UserControl. (I think the constructor does not get called in the static case)
解决方案::Arcturus和jpsstavares正确识别了问题.首先,在控件的构造函数中设置了DataContext = this时,我覆盖了数据绑定.这样可以防止设置数据绑定值.我还必须将控件命名为x:Name = root,并在XAML中指定Binding ElementName = root.要获得TwoWay绑定,我需要在调用方中设置Mode = TwoWay.这是正确的代码:
Solution: The problems were correctly identified by Arcturus and jpsstavares. First, I was overwriting the data binding when is set DataContext=this in the constructor of the control. This prevented the data bound value from getting set. I also had to name the control x:Name=root, and specify the Binding ElementName=root int the XAML. To get the TwoWay binding, I needed to set Mode=TwoWay in the caller. Here is the correct code:
<src:BlueTextBox BlueText="{Binding Path=MyString, Mode=TwoWay}}" /> <!--OK-->
现在在用户控件中添加了XAML:
Now the XAML in the UserControl:
<UserControl x:Class="Binding2.BlueTextBox" x:Name="root"...
<Grid>
<TextBox x:Name="myTextBox" Text="{Binding ElementName=root, Path=BlueText}" Foreground="Blue" Width="100" Height="26" />
</Grid>
最后,我在UserControl的构造函数中删除了DataContext = this.
Finally I removed the DataContext=this in the constructor of the UserControl.
public BlueTextBox()
{
InitializeComponent();
//DataContext = this; -- don't do this
}
感谢大家的大力帮助!
推荐答案
您将控件中的DataContext设置为其自身,从而在其他控件中使用此控件时会覆盖DataContext.以您的情况为例:
You set the DataContext in the Control to itself, thus overwriting the DataContext when using this Control in other controls. Taking your binding as example in your situation:
<src:BlueTextBox BlueText="{Binding Path=MyString}" />
一旦加载并设置了所有Datacontext,由于将DataContext设置为它,它将在BlueTextBox控件中寻找MyString路径.我想这不是您打算的工作方式;).
Once loaded and all the Datacontext is set, it will look for the path MyString in your BlueTextBox thing control due to you setting the DataContext to it. I guess this is not how you intended this to work ;).
解决方案:
更改文本绑定为2个绑定之一:
Change the text binding either one of the 2 bindings:
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:BlueTextBox}}, Path=BlueText}
或
命名您的控件根(或类似名称)
Name your control Root (or something like that)
<UserControl x:Name="Root"
{Binding ElementName=Root, Path=BlueText}
然后删除
DataContext = this;
来自UserControl的构造函数,它应该像超级按钮一样工作.
from the constructor of your UserControl and it should work like a charm..
这篇关于数据绑定到WPF中的UserControl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!