WPF UserControls を使い始めたとき、UserControl のコンテンツをそのプロパティの 1 つにバインドする方法をいくつか見つけました。
私のコントロールの 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 のコンテンツをそのプロパティの 1 つにバインドしたいと思ったとき、「ねえ、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 を継承する必要があります。上記のように上書きすると、バインディングはソースを見つけられなくなります。
私の最後の質問:
- 提示された各方法の長所と短所は何ですか?
- いつどの方法を使用する必要がありますか?
- もっと方法はありますか?