0
votes

I have restyled a Button using a ControlTemplate in a Style, which contains a VisualStateManager MouseOver state that inverts the Background to Black and the Foreground to White.

I then use this styled button to host a Path object with its Fill property set to Black.

How do I make the Fill property of the Path object, contained within the Content of the Button change to White when the MouseOver state is triggered without having to move the Path into the ControlTemplate itself which means creating a seperate Style for each button?

1

1 Answers

1
votes

Your fill is outside of the Visual State Manager "context" of the Button. I see two ways to deal with this issue:

i) Bring your Path inside of the Button (probably right inside the Grid under Border x:Name="Background" of the ControlTemplate TargetType="Button"), give it an x:Name to use with the Visual State Manager of the Button.

ii) Use your Path as Button content and then add a dedicated Visual State Manager for this Button content. You are likely to use i:EventTrigger EventName="Click" for your content (see an example of this).

When you would like to use different Path visuals for essentially the same button, you are forced to violate the DRY principle with either of these alternatives. (Making a custom control is the ultimate solution but here you are losing the benefits of speed and short-term convenience).

The following example uses option (i) and looks like this:

Vector Based Button Violating the DRY Principle

and this:

<UserControl x:Class="rasx.Buttons.MainPage"
    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"
    mc:Ignorable="d"
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <ControlTemplate x:Key="ButterflyPathTemplate" TargetType="ContentControl">
            <Canvas x:Name="BackgroundCanvas"
                Width="140" Height="90">
                <!--http://www.thexamlproject.com/#/artwork/437-->
                <!--Butterfly:-->
                <Path
                    Data="F1 M 133.242,3.82999C 133.103,2.12811 130.674,0.701721 129.535,0.36969C 109.54,-5.44736 77.5898,30.2498 70.3398,38.7362L 70.3606,38.386C 70.3763,38.2512 70.3841,38.1152 70.3841,37.9765C 70.3841,35.8977 68.6992,34.2134 66.621,34.2134C 64.5436,34.2134 62.86,35.8977 62.86,37.9765C 62.86,38.1152 62.8691,38.2512 62.8835,38.386L 62.9036,38.7362C 55.6529,30.2498 23.7012,-5.44736 3.70638,0.36969C 2.56775,0.701721 0.137329,2.12689 0,3.82999C -0.330811,7.9361 1.14774,11.3326 3.84241,13.9817C 14.5253,24.4817 11.093,34.8846 14.0865,41.6177C 15.8437,45.5721 28.8476,46.5057 25.9505,47.5474C -1.51242,57.4354 31.4427,94.563 46.8196,85.3365C 52.6581,81.8339 62.7916,64.5942 64.2238,62.1269L 64.916,74.3352C 64.916,75.2766 65.6784,76.0396 66.6197,76.0396C 67.5625,76.0396 68.3241,75.2766 68.3241,74.3352L 69.0169,62.1269C 70.4478,64.5942 80.582,81.8339 86.4205,85.3365C 101.799,94.563 134.754,57.4354 107.292,47.5474C 104.393,46.5057 117.397,45.5721 119.155,41.6177C 122.147,34.8846 118.715,24.4803 129.398,13.9817C 132.092,11.3326 133.573,7.93475 133.242,3.82999 Z "
                    Fill="{TemplateBinding Foreground}"
                    Stretch="Uniform"
                    Width="133.334" Height="87.0643"
                    />
            </Canvas>
        </ControlTemplate>
        <ControlTemplate x:Key="ButterflyPathButtonTemplate" TargetType="Button">
            <Grid>
                <vsm:VisualStateManager.VisualStateGroups>
                    <vsm:VisualStateGroup x:Name="CommonStates">
                        <vsm:VisualState x:Name="Normal">
                        </vsm:VisualState>
                        <vsm:VisualState x:Name="MouseOver">
                            <Storyboard>
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetName="BackgroundContent"
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                    To="Red"
                                    />
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetName="ContentPresenter"
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                    To="Red"
                                    />
                            </Storyboard>
                        </vsm:VisualState>
                        <vsm:VisualState x:Name="Pressed">
                            <Storyboard>
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)"
                                    Storyboard.TargetName="Background"
                                    To="Red"
                                    />
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetName="BackgroundContent"
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                    To="White"
                                    />
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetName="ContentPresenter"
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                    To="White"
                                    />
                            </Storyboard>
                        </vsm:VisualState>
                        <vsm:VisualState x:Name="Disabled">
                            <Storyboard>
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetName="BackgroundContent"
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                    To="Gray"
                                    />
                                <ColorAnimation
                                    Duration="0"
                                    Storyboard.TargetName="ContentPresenter"
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                    To="Gray"
                                    />
                            </Storyboard>
                        </vsm:VisualState>
                    </vsm:VisualStateGroup>
                    <vsm:VisualStateGroup x:Name="FocusStates">
                        <vsm:VisualState x:Name="Focused">
                        </vsm:VisualState>
                        <vsm:VisualState x:Name="Unfocused" />
                    </vsm:VisualStateGroup>
                </vsm:VisualStateManager.VisualStateGroups>
                <Border
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid x:Name="Background"
                        Background="Transparent">
                        <!-- TODO: build custom control with BackgroundContentTemplate property needed? -->
                        <ContentControl x:Name="BackgroundContent"
                            Foreground="{TemplateBinding Foreground}"
                            Template="{StaticResource ButterflyPathTemplate}" Background="Black"
                            />
                    </Grid>
                </Border>
                <!--Default ContentPresenter changed to TextBlock:-->
                <TextBlock x:Name="ContentPresenter"
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                    Margin="{TemplateBinding Padding}"
                    Text="{TemplateBinding Content}"
                    />
                <Rectangle x:Name="DisabledVisualElement"
                    IsHitTestVisible="false"
                    Opacity="0"
                    />
                <Rectangle x:Name="FocusVisualElement"
                    IsHitTestVisible="false"
                    Opacity="0"
                    />
            </Grid>
        </ControlTemplate>
        <Style x:Key="VectorButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Foreground" Value="Green" />
            <Setter Property="Padding" Value="0,90,0,0" />
            <Setter Property="Template" Value="{StaticResource ButterflyPathButtonTemplate}" />
        </Style>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Button
            Content="Yes"
            Style="{StaticResource VectorButtonStyle}"
            />
        <Button Grid.Row="1"
            Content="Nope"
            IsEnabled="False"
            Style="{StaticResource VectorButtonStyle}"
            />
    </Grid>
</UserControl>