简体   繁体   中英

What's the difference between these two ways of declaring a self binding?

I have an UserControl containing a ItemsSource DependenceProperty that has to be binded to the ItemsSource property of an internal Control:

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Self}}"

vs

ItemsSource="{Binding ItemsSource, ElementName=controlName}"

controlName is the name of the control.

The first binding is not working while the second one works. I don't get the difference.

Any ideas?

EDIT:

XAML:

<UserControl x:Class="MultiSelectTreeView.MultiSelectableTreeView"

         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

         mc:Ignorable="d"

         Name="multiTree" >

This does not work ---> <TreeView ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Self}}" >
This works ---> <TreeView ItemsSource="{Binding ItemsSource, ElementName=multiTree}" >

In case you want to bind to DP of parent UserControl, you need to bind it using Mode = FindAncestor . Since you are binding on internal control, you need to travel up the Visual Tree.

Self Mode will search for DP in internal control and not on parent UserControl.

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, 
                                                   AncestorType=UserControl}}"

I'm assuming from your question that you have Xaml that is something like this in structure:

<UserControl x:Name="rootElement">
    <ListBox ItemsSource="{Binding .....}" />
</UserControl>

Your bindings are then doing the following:

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Self}}"

... this will look for the property ItemsSource on the control that the binding is declared on (that is, the ListBox ). In your case this will cause a problem because you're essentially setting up an infinite recursion: your ItemsSource is bound to the ItemsSource is bound to the... ad infinitum. You mention that you're working with a UserControl here, and I suspect that you might be expecting RelativeSource to return the root UserControl element - but this is not the case.

ItemsSource="{Binding ItemsSource, ElementName=rootElement}"

... this will bind to the property ItemsSource on the control with a specific name. If you're working in a UserControl then typically you would have set x:Name on the root element of the UserControl and would be referring to it from a binding in this way. This would allow you to bind the child ListBox to the public ItemsSource property of your UserControl .

Just for information, one other alternative is to use an AncestorType binding to find your parent UserControl . If your UserControl type is called MyControl , it would look something like this:

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType=MyControl}}"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM