2

**Edit - I flagged the DynamicResource answer as the answer for this. That resolved the problem I described here. I was still having trouble in my main application and it turned out it was because I was using the brush elsewhere as a StaticResource before using it on my border as a DynamicResource. When I switched everything to DynamicResource it worked correctly. Thanks!

I can't seem to get the BorderBrush to work in a templated ToggleButton. Here's my sample .xaml, if you run this, you'll see that the border becomes transparent when you mouseover or check one of the buttons.

<Window x:Class="ToggleButtonStyle.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ToggleButtonStyle"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <!-- <ResourceDictionary Source="Dictionary1.xaml" /> -->
    <!-- main color of buttons-->
    <Color x:Key="MainThemeColor">Orange</Color>

    <!-- hover-over color for buttons -->
    <Color x:Key="MouseOverColor">Purple</Color>

    <!-- 5. Mouse over background color for step buttons -->
    <SolidColorBrush x:Key="MouseOverBackgroundBrush" Color="{DynamicResource MouseOverColor}"/>

    <!-- 6. Background color active step -->
    <SolidColorBrush x:Key="CheckedBackgroundBrush" Color="{DynamicResource MainThemeColor}"/>

    <Style TargetType="{x:Type ToggleButton}" x:Key="ToggleButtonStyle">
        <Setter Property="Background" Value="White" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="Width" Value="Auto"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="MinWidth" Value="80"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness ="{TemplateBinding BorderThickness}" Padding="5" Margin="2">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="BorderBrush" Value="{StaticResource CheckedBackgroundBrush}" />
                <Setter Property="Background" Value="{StaticResource MouseOverBackgroundBrush}" />
                <Setter Property="Foreground" Value="#333333" />
            </Trigger>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="BorderBrush" Value="{StaticResource MouseOverBackgroundBrush}"/>
                <Setter Property="Background" Value="{StaticResource CheckedBackgroundBrush}" />
                <Setter Property="Foreground" Value="#ffffff"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <StackPanel Orientation="Horizontal">
        <ToggleButton Style="{DynamicResource ToggleButtonStyle}">Button 1</ToggleButton>
        <ToggleButton Style="{DynamicResource ToggleButtonStyle}">Button 2</ToggleButton>
        <ToggleButton Style="{DynamicResource ToggleButtonStyle}">Button 3</ToggleButton>
    </StackPanel>
</Grid>

MadSkeletor
  • 161
  • 1
  • 14
  • You could try to use WPF Inspector or Visual Studio 2015 to look at the Visual tree. There you can see which resources are applied and from which style. – Michael Jan 06 '17 at 22:52
  • I have done that. It just says the BorderBrush is "Transparent" and it's coming from a style trigger. – MadSkeletor Jan 06 '17 at 23:06
  • You could try to set the BorderBrush setter to a specific value instead of referencing a static resource. Just to see if that works. – Michael Jan 06 '17 at 23:09
  • It does work. I was going to mention that in my initial example but I didn't want to make it too confusing. – MadSkeletor Jan 06 '17 at 23:09
  • Then you could try using StaticResource instead of DynamicResource like ``. When you debug you will get error messages in the output pane in VS if the resource can not be found. – Michael Jan 06 '17 at 23:12
  • Okay, I see they are just above.....hmmm.... – Michael Jan 06 '17 at 23:12
  • If you use static resources it works as well, but why wouldn't it work with a dynamic resource? My example is simplified from an application problem we are having. I'd like to use dynamic resource because we allow custom dictionaries to be created, so the control ends up with multiple dictionaries in the merged dictionary. I'd like people to be able to just override the main colors if they want in the custom dictionary. – MadSkeletor Jan 06 '17 at 23:14
  • Can you do that without restarting the application? – Michael Jan 06 '17 at 23:19
  • See here the difference between Static and Dynamic: http://stackoverflow.com/questions/200839/whats-the-difference-between-staticresource-and-dynamicresource-in-wpf – Michael Jan 06 '17 at 23:20

2 Answers2

2

Using a Rectangle seems to work. Take a look at this: DynamicResource color doesn't work for BorderBrush on a Border - Bug?. Doesn't make any sense to me that this should not work.

<Style TargetType="{x:Type ToggleButton}">
        <Setter Property="Background" Value="White" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="BorderBrush" Value="{DynamicResource MouseOverBackgroundBrush}"/>
        <Setter Property="Width" Value="Auto"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="MinWidth" Value="80"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid>
                        <Rectangle Fill="{TemplateBinding Background}"
                                   Stroke="{TemplateBinding BorderBrush}"
                                   StrokeThickness="{TemplateBinding BorderThickness}" 
                                   Margin="2">
                        </Rectangle>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="BorderBrush" Value="{StaticResource CheckedBackgroundBrush}" />
                <Setter Property="Background" Value="{StaticResource MouseOverBackgroundBrush}" />
                <Setter Property="Foreground" Value="#333333" />
            </Trigger>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="BorderBrush" Value="{StaticResource MouseOverBackgroundBrush}"/>
                <Setter Property="Background" Value="{StaticResource CheckedBackgroundBrush}" />
                <Setter Property="Foreground" Value="#ffffff"/>
            </Trigger>
        </Style.Triggers>
    </Style>
Community
  • 1
  • 1
Michael
  • 3,350
  • 2
  • 21
  • 35
1

Since the Color property of the Brushes are set using the DynamicResource markup extension you should also set the properties in your setter using DynamicResource:

<Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
        <Setter Property="BorderBrush" Value="{DynamicResource CheckedBackgroundBrush}" />
        <Setter Property="Background" Value="{DynamicResource MouseOverBackgroundBrush}" />
        <Setter Property="Foreground" Value="#333333" />
    </Trigger>
    <Trigger Property="IsChecked" Value="True">
        <Setter Property="BorderBrush" Value="{DynamicResource MouseOverBackgroundBrush}"/>
        <Setter Property="Background" Value="{DynamicResource CheckedBackgroundBrush}" />
        <Setter Property="Foreground" Value="#ffffff"/>
    </Trigger>
</Style.Triggers>

I you use StaticResource the value of the setters won't be updated once the dynamic color resources have actually been looked up at runtime.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • This works as well with a `Border`. Still strange that the other approach works with a `Rectangle` and that it works with a combination of StaticResource and DynamicResource for anything else than BorderBrush. – Michael Jan 07 '17 at 15:47
  • **edit, my bad, I just had a wrong name. It does work with resource dictionary as well – MadSkeletor Jan 09 '17 at 14:33