0

その場でバインディングをプログラムで作成するコードを書いていますが、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 バインディングを適用するだけです) が、なぜこれが機能しないのか興味があります。

前もって感謝します!

4

1 に答える 1

1

バインドした直後にバインドされたプロパティの値を取得することはできません。現在、ハンドラー操作で UI スレッドをブロックしています。その後、スレッドがアイドル状態になったときにのみバインドが行われます (私は思います)。

コメントの後のすべてを削除し、Always null後で値を確認する必要があります。たとえば、別のボタンのハンドラーで確認してください。また、バインドされていない XAML に示されているように、バインドされた要素は実際にツリー内にありますか? そうでない場合は、そのようなエラーも説明されます。

編集:Textバインドが少しずれている可能性があることに気付きました.XAML をバインドし、コードで にバインドを設定するため、投稿した XAML に変換されませんTagProperty。バインディングは理論上は機能するはずですが、前述のように bindig を設定した直後にバインドされたプロパティの値が null になることに注意してください。したがって、すぐに削除しないでください (TextProperty視覚的な結果が必要な場合はバインドします)。

于 2011-09-16T02:18:35.997 に答える