11
votes

I remember reading a couple of weeks ago that it sometimes doesn't work inside templates, and I recently tried to bind things in two different windows and it couldn't find the name declarations, so I assumed that it was local to the namespace of the class and just bound by setting the datacontext instead. However, I'm really curious when I am able to use binding elementname and when I cannot, because it's far more convenient when it is possible.

edit: In reading that article, I found this to be interesting:

"For this reason, styles and templates both define their own XAML namescopes, independent of whatever location in an object tree where the style or template is applied."

if this is true, doesn't that mean that Binding ElementName should not work in templates at all? But then I definitely have some working bindings on ElementName within my templates. That is the most confusing part, why do some bindings randomly work inside the templates and others do not? It must have some method for trying to resolve the name even if it isn't in the template or same namescope

1
ElementName binding only works for elements in the same NameScopeFederico Berasategui
which namescope? like these: xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft.com/winfx/2006/xaml" but if it's just those two then all of my files have those so then I should be able to reference everything using ElementNameJames Joshua Street
That's a Namespace, not a Namescope. Those are 2 different concepts. Namespace is an XML concept, and Namescope is a XAML concept.Federico Berasategui
lol didn't realize they were different when glancing at it. That helps a lot actuallyJames Joshua Street
I'm pretty sure an ElementName binding does not work if it is defined inside a DataTemplate and points to a UI Element Outside that DataTemplate. If you have a working one, please post the XAML.Federico Berasategui

1 Answers

16
votes

Basically you need to be in the same name scope (read this). Most UI elements are in the same tree sharing the same name scope, however there can be breaks and barriers (styles/templates) and if you have abstract objects like DataGrid columns they do not have a name scope at all.

I've been working with WPF long enough to guess when i'll run into problems and i know common areas but don't think there's an easy way to tell in all situations up-front.


if this is true, doesn't that mean that Binding ElementName should not work in templates at all? But then I definitely have some working bindings on ElementName within my templates.

Within is just fine, that is the same scope. The point here is that if you apply the template and they would not have their own scopes there would be conflicts.

e.g.

<Button/>
<Button/>

If we expand the ControlTemplate you would get something like:

<Border Name="bd" Background="{TemplateBinding Background}">...</Border>
<Border Name="bd" Background="{TemplateBinding Background}">...</Border>

Obviously we would get a name conflict.

Same for DataTemplates in ItemsControls, if you name controls in the template that name would conflict with the same control instance in the applied template of other items.


On another note, you can bind from inside a template to the outside because logically there can only be one instance with that name or you can give them a distinct precedence based on how "close" the name scope is, e.g.

<TextBox Name="tb" Text="Test"/>
<ItemsControl ItemsSource="ABC">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text, ElementName=tb}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>