在开始使用 WPF UserControls 时,我偶然发现了几种将 UserControl 的内容绑定到其属性之一的方法。
这是我的控件的示例 C# 代码:
public sealed partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
public static readonly DependencyProperty TheTextProperty =
DependencyProperty.Register("TheText",
typeof (string),
typeof(MyUserControl),
new FrameworkPropertyMetadata(0,
FrameworkPropertyMetadataOptions.
BindsTwoWayByDefault)
);
public string TheText
{
get { return (string)GetValue(TheTextProperty); }
set { SetValue(TheTextProperty, value); }
}
}
以下是我发现将内容绑定到此属性的不同方法:
内容使用与 RelativeSource/AncestorType 的绑定
<UserControl x:Class="MyUserControl"
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">
<StackPanel>
<TextBox Text="{Binding TheText,
RelativeSource={RelativeSource
AncestorType={x:Type UserControl}}}" />
</StackPanel>
</UserControl>
可视化树根的 DataContext 在 XAML 中设置为 UserControl
<UserControl x:Class="MyUserControl"
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">
<StackPanel DataContext="{Binding
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
<TextBox Text="{Binding TheText}" />
</StackPanel>
</UserControl>
可视化树根的 DataContext 在构造函数中设置为 UserControl
<UserControl x:Class="MyUserControl"
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">
<StackPanel x:Name="VisualTreeRoot">
<TextBox Text="{Binding TheText}" />
</StackPanel>
</UserControl>
这是构造函数:
public MyUserControl()
{
InitializeComponent();
VisualTreeRoot.DataContext = this;
}
最后但并非最不重要的一点:对在 WPF 中编程 UserControls 的其他人的警告
我第一次想将 UserControl 的内容绑定到它的一个属性时,我虽然“嘿,让我们直接将 UserControl 的 DataContext 设置为它自己”:
<UserControl x:Class="MyUserControl"
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"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
或者:
public MyUserControl()
{
InitializeComponent();
this.DataContext = this;
}
但是,如果 UserControl 的用户想要将其属性绑定到其他绑定源,这将不起作用。UserControl 需要从其父级继承 DataContext 才能使其工作。通过如上所述覆盖它,绑定将不再找到它们的源。
我最后的问题:
- 所提出的每种方法的优点和缺点是什么?
- 什么时候应该使用哪种方法?
- 还有更多方法吗?