以编程方式创建RelativeSource FindAncestor绑定

时间:2011-09-16 02:13:19

标签: c# wpf xaml relativesource findancestor

我正在编写一些以编程方式动态创建绑定的代码,但我似乎无法读取其RelativeSourceMode设置为FindAncestor的绑定所产生的值。我想知道是否有人用这种模式在代码(而不是XAML)中成功创建了一个RelativeSource绑定?

启用Binding跟踪后,警告为:

  

System.Windows.Data警告:64:BindingExpression(hash = 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绑定(使用VisualTreeHelper.GetParent(...)定位FindAncestor绑定的目标元素,然后只应用RelativeSource Self绑定)但我很好奇为什么这不起作用。

提前致谢!

1 个答案:

答案 0 :(得分:1)

绑定后无法获取绑定属性的值,您当前正在使用处理程序操作阻止UI线程,绑定只会在线程空闲之后发生(我认为)。

您应该在Always null评论后删除所有内容并稍后检查该值,例如在另一个按钮的处理程序中。另外,绑定元素实际上是在XAML中显示的树中没有绑定吗?如果不是这样也可以解释这样的错误。

编辑:我刚刚注意到您的绑定可能有点过时,它们不会转换为您在绑定Text的XAML中发布的XAML,并且在您的代码中在TagProperty上设置绑定。忽略绑定应该在理论上工作,只需注意在设置bindig后立即绑定属性的值将为null,如前所述,所以不要立即删除它(如果你想要视觉,请绑定TextProperty结果)。