Binding ElementName. Does it use Visual Tree or Logical Tree

对着背影说爱祢 提交于 2019-11-26 15:48:59

问题


Having {Binding ElementName=foo}, will it lookup visual or logical tree?

Of logical and visual trees in WPF | Data See, Data Do

When does the logical tree matter?

When looking up a name, such as in {Binding ElementName=Foo}, the search walks up the ancestry looking for a name scope, again just as it does for inheritable properties.

ElementName binding in Silverlight via Attached Behaviours

In order to enable this, WPF provides ElementName and RelativeSource bindings, giving you a powerful mechanism for locating other elements within your visual tree to bind to

EDIT:

It looks like the Logical Tree used for binding by ElementName.

Argument # 1.

According to MSDN article FrameworkElement Class:

FrameworkElement extends UIElement and adds the following capabilities:

  • Support for data binding and dynamic resource references: The property-level support for data binding and resources is implemented by the DependencyProperty class and embodied in the property system, but the ability to resolve a member value that is stored as an Expression (the programming construct that underlies both data binding and dynamic resources) is implemented by FrameworkElement. For more information, see Data Binding Overview and Resources Overview.

Argument # 2.

ElementName points to x:Name, so this name should be found some how. There is a NameScope concept.

For most scenarios, the FindName methods exposed on FrameworkElement and FrameworkContentElement are more appropriate methods to call to search for elements by name. The Name properties exposed by FrameworkElement and FrameworkContentElement are more appropriate properties to use to set the initial name as markup attributes. And the RegisterName methods exposed on FrameworkElement and FrameworkContentElement is necessary to establish a name into a specific namescope (there is no NameScope member that can do this directly; you must set the current namescope first to use RegisterName).

On the other hand, Visual class neither have FindName method, nor implement INameScope.


回答1:


I think it's logical tree. When using ControlTemplates, you're replacing one visual tree with another, but I don't think you can reference the names defined inside of the ControlTemplate.

For example:

<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>

Doesn't find the element named "border" in the ControlTemplate, but changing ElementName in labelBar's binding to "buttonFoo" makes the Background Green, as expected.




回答2:


The ElementName property of a binding in a sense (see below answer) works off of the logical tree because one is using ElementName to divine a specific control solely on the logical tree in the Xaml.

will it lookup visual or logical tree?

The premise you propose is wrong, there is no lookup per-se on either tree. One is simply setting a Source property for reflection operation used by the binding instead of defaulting to the inherited DataContext of the logical tree.

If one reads the documentation of Binding.ElementName Property (System.Windows.Data) (bolding mine):

"...the ElementName property is one of the ways you can explicitly set the source of a Binding and override the inherited data context."

The source is any instantiated object which is within the current operations namespace which can be accessed and reflected off of.

No more no less and most likely will be in the Logical Tree (but doesn't have too) because people name there logical items in Xaml, but also could be in the visual tree.


See Data Binding Overview for more info.



来源:https://stackoverflow.com/questions/705853/binding-elementname-does-it-use-visual-tree-or-logical-tree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!