7

In the following XAML I'm using a Rectangle with a Border as the Template for a ToggleButton. I want the BorderBrush to be a different colour to reflect the changing value of ToggleButton.IsChecked. Unfortunately my attempt here of using a TemplateBinding in the DataTrigger doesn't work. What do I need to do instead?

<StackPanel Orientation="Horizontal">
    <StackPanel.Resources>
        <ControlTemplate x:Key="ButtonAsSwatchTemplate">
            <Border BorderThickness="1">
                <Border.Style>
                    <Style>
                        <Setter Property="BorderBrush" Value="Gainsboro" /> 
                        <Style.Triggers>
                            <!-- TemplateBinding doesn't work.-->
                            <DataTrigger                              
                                 Binding={TemplateBinding Property=IsChecked}    
                                 Value="True">
                                <Setter Property="BorderBrush" Value="Black" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
                <Rectangle Fill="{TemplateBinding Property=Background}"
                           Width="15" Height="15" />
            </Border>
        </ControlTemplate>
    </StackPanel.Resources>
    <ToggleButton Template="{StaticResource ButtonAsSwatchTemplate}"
                  HorizontalAlignment="Center" VerticalAlignment="Center"
                  Margin="2" Background="Red" />
</StackPanel>

EDIT

When I build and reload the designer I get the following error:

Error 1 Property 'Binding' does not support values of type 'TemplateBindingExpression'.

SOLUTION

<StackPanel Orientation="Horizontal">
    <StackPanel.Resources>
        <ControlTemplate x:Key="ButtonAsSwatchTemplate">    
            <Border x:Name="SwatchBorder" BorderThickness="1">
                <Rectangle Fill="{TemplateBinding Property=Background}" Width="15" Height="15" />
            </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="ToggleButton.IsChecked" Value="True">
                <Setter TargetName="SwatchBorder" Property="BorderBrush" Value="Yellow" />
            </Trigger>
        </ControlTemplate.Triggers>
            </ControlTemplate>
        </StackPanel.Resources>
    <RadioButton Template="{StaticResource ButtonAsSwatchTemplate}"
        GroupName="CropGuidesColourRadioButtonGroup"
        IsChecked="{Binding Checked}" Margin="2" Background="Red" />
    <RadioButton Template="{StaticResource ButtonAsSwatchTemplate}"
        GroupName="CropGuidesColourRadioButtonGroup" 
        IsChecked="{Binding Checked}" Margin="2" Background="Black" />
    ...
</StackPanel>
Grokodile
  • 3,881
  • 5
  • 33
  • 59

2 Answers2

9

You could use a Trigger in the ControlTemplate, e.g.

<StackPanel Orientation="Horizontal">
    <StackPanel.Resources>
        <ControlTemplate x:Key="ButtonAsSwatchTemplate">
            <Border x:Name="myBorder" BorderBrush="Gainsboro" BorderThickness="1">
                <Rectangle Fill="{TemplateBinding Property=Background}" Width="15" Height="15" />
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="ToggleButton.IsChecked" Value="True">
                    <Setter TargetName="myBorder" Property="BorderBrush" Value="Black" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </StackPanel.Resources>
    <ToggleButton Template="{StaticResource ButtonAsSwatchTemplate}"
              HorizontalAlignment="Center" VerticalAlignment="Center"
              Margin="2" Background="Red" />
</StackPanel>
Rob
  • 4,733
  • 3
  • 32
  • 29
  • 1
    Thanks for this. I'd been trying to do TemplateBindings in the ControlTemplate triggers, but didn't realize I could access the DependencyProperties of the control from the controltemplate – William Thomas Waller Jun 25 '15 at 22:18
0

One problem I see right away is that you are setting BorderBrush as a local property value on Border. This will always override the value applied by the style. Try removing the explicit BorderBrush attribute and see if that works.

Border BorderBrush="Gainsboro" BorderThickness="1"

Dependency Property Value Inheritance

Josh
  • 68,005
  • 14
  • 144
  • 156
  • good call, I've removed that from my code and updated the sample in my question, but I still get the error which I've added above as an edit. – Grokodile Jul 21 '11 at 00:59