Binding ElementName. 它使用视觉树还是逻辑树?

20
拥有 {Binding ElementName=foo},它会查找视觉树还是逻辑树?
关于 WPF 中的逻辑树和视觉树,请参考此博客文章:Of logical and visual trees in WPF | Data See, Data Do。当使用 {Binding ElementName=Foo} 时,它会查找名称范围,而这与可继承属性一样,需要向上遍历祖先节点来查找逻辑树。
另外,在 Silverlight 中可以通过附加行为使用 ElementName 和 RelativeSource 绑定,以便在视觉树中查找其他元素进行绑定,具体请参阅此博客文章:ElementName binding in Silverlight via Attached Behaviours
编辑后:
根据 MSDN 文章 FrameworkElement Class,看起来逻辑树用于通过 ElementName 进行绑定。 FrameworkElement 扩展了 UIElement 并添加了对数据绑定和动态资源引用的支持,但是在存储为 Expression 的成员值(支持数据绑定和动态资源的编程结构)的解析能力由 FrameworkElement 实现。

ElementName指向x:Name,因此必须以某种方式找到该名称。这里涉及到一个NameScope概念。

对于大多数场景,应调用FrameworkElement和FrameworkContentElement公开的FindName方法来按名称搜索元素,而应使用FrameworkElement和FrameworkContentElement公开的Name属性作为标记属性设置初始名称。在FrameworkElement和FrameworkContentElement上公开的RegisterName方法是必要的,以在特定命名范围内建立名称(没有可以直接完成此操作的NameScope成员;您必须首先设置当前名称范围才能使用RegisterName)。

另一方面,Visual类既没有FindName方法,也没有实现INameScope


使用逻辑树。稍后会发布详细信息。 - alex2k8
2个回答

6
我认为这是一个逻辑树。当使用控件模板时,你是用另一个视觉树替换了一个视觉树,但我不认为你可以引用在控件模板内定义的名称。
例如:
<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.Resources>
            <ControlTemplate x:Key="Foo" TargetType="Button">
                <Border x:Name="border" Background="Red">
                    <Label Content="{TemplateBinding Content}"></Label>
                </Border>
            </ControlTemplate>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Button x:Name="buttonFoo" Background="Green" HorizontalAlignment="Center" VerticalAlignment="Center" Template="{DynamicResource Foo}">Foo</Button>
        <Label x:Name="labelBar" Grid.Column="1"  HorizontalAlignment="Center" VerticalAlignment="Center" Background="{Binding ElementName=border, Path=Background}">Bar</Label>
    </Grid>
</Page>

在ControlTemplate中找不到名为"border"的元素,但将labelBar绑定中的ElementName更改为"buttonFoo"会使背景变成绿色,正如预期。


0

ElementName 属性在绑定中的作用是基于逻辑树的,因为在 Xaml 中使用 ElementName 来仅从逻辑树中推断出特定控件。

它会查找可视树还是逻辑树?

您提出的前提是错误的,实际上没有在任何一棵树上进行查找。只是为绑定使用反射操作设置了一个属性,而不是默认使用逻辑树的继承 DataContext

如果阅读 Binding.ElementName Property (System.Windows.Data) 的文档(我加粗):

"... ElementName 属性是你可以显式设置 Binding 的并覆盖继承的数据上下文的方式之一。"

源是任何已实例化的对象,位于当前操作命名空间内,可以访问和反射。

没有多余也没有不足,最有可能会在逻辑树中(但不一定),因为人们在 Xaml 中命名其逻辑元素,但也可以在可视化树中。


请参阅数据绑定概述以获取更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接