Dan
Dan

Reputation: 1192

RelativeSource binding works from Style but not ControlTemplate

An entry in my Application.Resources ResourceDictionary is a control template that, slimmed down, looks similar to the following:

<ControlTemplate TargetType="{x:Type ToggleButton}">
    <Border>
        <Border.BorderBrush>
            <SolidColorBrush Color="{Binding Path=BorderColor, RelativeSource={RelativeSource AncestorType=UserControl}" />
        </Border.BorderBrush>
    </Border>
</ControlTemplate>

Each UserControl has its own property BorderColor which this pulls from. In this example, the binding fails to find the property.

Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''.

However, it works in another entry in the dictionary:

<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="BorderBrush" Value="{Binding Path=BorderColor, RelativeSource={RelativeSource AncestorType=UserControl}"/>
</Style>

How can I fix the binding in the first example? Preferably I would like to not need additional properties on the instance of each control in the user control.

Upvotes: 4

Views: 1417

Answers (2)

user2837961
user2837961

Reputation: 1555

It works if you use Background instead of BorderColor. Is BorderColor your own property?

<Window.Resources>
<ControlTemplate x:Key="template" TargetType="{x:Type ToggleButton}">
    <Border>
        <Border.BorderBrush>
                <SolidColorBrush Color="{Binding Path=Background,RelativeSource={RelativeSource AncestorType=UserControl}}" />
        </Border.BorderBrush>
    </Border>
</ControlTemplate>
</Window.Resources>

<UserControl Background="Aqua">
    <ToggleButton Template="{StaticResource template}"></ToggleButton>

</UserControl>

Upvotes: -1

mm8
mm8

Reputation: 169200

Two suggestions:

If the ControlTemplate is part of a Style you could set the BorderBrush property of the ToggleButton to the SolidColorBrush with the binding and use a TemplateBinding in the template:

<Style x:Key="myStyle" TargetType="ToggleButton">
    <Setter Property="BorderBrush">
        <Setter.Value>
            <SolidColorBrush Color="{Binding Path=BorderColor, RelativeSource={RelativeSource AncestorType=UserControl}}" />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border BorderBrush="{TemplateBinding Background}" BorderThickness="10">
                    <TextBlock>....</TextBlock>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

If you want to define a standalone ControlTemplate for some reason a workaround would be to bind to a Brush property instead of a Color property:

<ControlTemplate TargetType="{x:Type ToggleButton}">
    <Border BorderBrush="{Binding Path=BorderBrushProperty, RelativeSource={RelativeSource AncestorType=UserControl}}" BorderThickness="10">
        <TextBlock>....</TextBlock>
    </Border>
</ControlTemplate>

Upvotes: 2

Related Questions