wpfxamldata-bindingcontroltemplate

Why does template binded converter not work?


I have control template with a Border. I want to bind its background by template binding, but I also need to create an x:Name property for the SolidColorBrush. So I create a simple converter from Brush to Color, but it doesn't work and I don't understand why.

My XAML:

<ControlTemplate TargetType="Button" x:Key="appBtns">
    <ControlTemplate.Resources>
        <local:ColorConverter x:Key="ColorConverter"/>
    </ControlTemplate.Resources>
    <Border x:Name="BackRect" CornerRadius="15" BorderThickness="0" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
        <Border.Background >
            <SolidColorBrush x:Name="BackRectColor" Color="{TemplateBinding Background, Converter={StaticResource ColorConverter}}"/>
        </Border.Background>
    </Border>
</ControlTemplate>

My converter:

public class ColorConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((SolidColorBrush)value).Color;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

Solution

  • The TemplateBinding markup extension is known to be very limited in some scenarios. However, you can simply use a regular binding with a RelativeSource of TemplatedParent instead.

    <SolidColorBrush x:Name="BackRectColor" Color="{Binding Background, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}}"/>
    

    In fact, if you always use a SolidColorBrush, you do not even need a converter. Just specify the Color property of the Background SolidColorBrush as property path. It is resolved at runtime.

    <ControlTemplate TargetType="Button" x:Key="appBtns">
       <Border x:Name="BackRect" CornerRadius="15" BorderThickness="0" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
          <Border.Background >
             <SolidColorBrush x:Name="BackRectColor" Color="{Binding Background.Color, RelativeSource={RelativeSource TemplatedParent}}"/>
          </Border.Background>
       </Border>
    </ControlTemplate>