我知道有很多关于依赖属性的问题,我已经查看了很多这些问题,但是它们似乎都没有解决我的问题。
我有一个这样的窗口:
<Window x:Class="WpfBindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfBindingTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<local:TextInputWrapper MyText="{Binding MyTextValue, Mode=TwoWay}" />
<TextBox Text="{Binding MyTextValue, Mode=TwoWay}"/>
</StackPanel>
</Window>
其中MyTextValue只是一个字符串属性,通知何时更改:
private string _myTextValue = "Totally different value";
public string MyTextValue { get { return _myTextValue; } set { _myTextValue = value; OnPropertyChanged(); } }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
TextInputWrapper也很简单:
<UserControl x:Class="WpfBindingTest.TextInputWrapper"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfBindingTest"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<TextBox Text="{Binding MyText}"></TextBox>
</UserControl>
代码隐藏:
public partial class TextInputWrapper : UserControl
{
public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText",
typeof(string), typeof(TextInputWrapper), new PropertyMetadata("Empty"));
public TextInputWrapper()
{
InitializeComponent();
}
public string MyText
{
get { return (string)GetValue(MyTextProperty); }
set { SetValue(MyTextProperty, value); }
}
}
现在据我所知,我的Window现在应该有两个相互绑定的TextBox控件。如果我在一个中更改值,则另一个应该更新。
然而,我最终得到了两个单独的TextBoxes,其中第一个以文本“Empty”开头,而下一个文本“文本为”Totally different value“。像这样:
并且更改其中任何一个的文本都不会在另一个中重现。
我希望他们两个都从文本“Totally different value”开始,并与他们的值同步(通过将更改传播到MainWindow上的MyTextValue属性,并通过在那里通知更改,然后更改将传播到另一个文本框)。在我的控件中正确实现数据绑定我错过了什么?
答案 0 :(得分:2)
删除作业
DataContext="{Binding RelativeSource={RelativeSource Self}}"
来自UserControl的XAML的。而是设置&#34;内部&#34;的RelativeSource
。绑定到控件实例:
<UserControl x:Class="WpfBindingTest.TextInputWrapper" ...>
<TextBox Text="{Binding MyText,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl>
显式设置UserControl的DataContext会阻止从其父控件继承DataContext,即像
这样的绑定<local:TextInputWrapper MyText="{Binding MyTextValue, Mode=TwoWay}" />
将使用UserControl作为源对象,而不是当前的DataContext。
作为一般规则,从不显式设置UserControl的DataContext。
答案 1 :(得分:0)
尝试更改此行:
public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText",
typeof(string), typeof(TextInputWrapper), new PropertyMetadata("Empty"));
对此:
public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText",
typeof(string), typeof(TextInputWrapper), new FrameworkPropertyMetadata("Empty", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));