その場でバインディングをプログラムで作成するコードを書いていますが、RelativeSourceMode が FindAncestor に設定されているバインディングの結果の値を読み取ることができないようです。このモードでコード (XAML ではない) で RelativeSource バインディングを正常に作成した人がいるかどうか疑問に思っていましたか?
Binding トレースをオンにすると、警告は次のようになります。
System.Windows.Data 警告: 64: BindingExpression (ハッシュ = 57957548): RelativeSource (FindAncestor) にはツリー コンテキストが必要です
RelativeSource バインディングを作成するサンプル コードを次に示します。
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
// Create RelativeSource FindAncestor Binding
var binding = new Binding
{
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ListBoxItem), 1),
Path = new PropertyPath("Tag"),
};
PresentationTraceSources.SetTraceLevel(binding, PresentationTraceLevel.High);
BindingOperations.SetBinding(textBlock, TagProperty, binding);
// Always null
var findAncestorBindingResult = textBlock.Tag;
// Create RelativeSource Self Binding
binding = new Binding
{
RelativeSource = new RelativeSource(RelativeSourceMode.Self),
Path = new PropertyPath("Text"),
};
PresentationTraceSources.SetTraceLevel(binding, PresentationTraceLevel.High);
BindingOperations.SetBinding(textBlock, TagProperty, binding);
// Has correct value Text property set from XAML
var selfBindingResult = textBlock.Tag;
}
対応する XAML は次のとおりです。
<StackPanel>
<ListBox x:Name="listBox">
<ListBoxItem x:Name="listBoxItem" Tag="Item One" >
<ListBoxItem.Content>
<TextBlock x:Name="textBlock">
<TextBlock.Text>
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}" Path="Tag" />
</TextBlock.Text>
</TextBlock>
</ListBoxItem.Content>
</ListBoxItem>
</ListBox>
<Button Content="Debug" Click="ButtonBase_OnClick" />
</StackPanel>
ツリーが読み込まれるので、FindAncestor バインディングをシミュレートできます (FindAncestor バインディングVisualTreeHelper.GetParent(...)
のターゲット要素を見つけてから、それに RelativeSource Self バインディングを適用するだけです) が、なぜこれが機能しないのか興味があります。
前もって感謝します!