0

I'm trying to do my own button style. I want to the MouseEnter and the MouseLeave event to use the color chosen for BorderBrush and Background respectively.

My style code is:

<Style x:Key="RoundButton" TargetType="Button">
            <Setter Property="Padding" Value="5"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Margin="-1"
                                        CornerRadius="3"
                                        Background="{TemplateBinding Background}"
                                        BorderThickness="0.7"
                                        BorderBrush="{TemplateBinding BorderBrush}">
                            <ContentPresenter 
                                            Margin="-1"
                                            x:Name="MyContentPresenter"
                                            Content="{TemplateBinding Content}" 
                                            HorizontalAlignment="Center"
                                            VerticalAlignment="Center"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation To="{Binding (CHOSEN BORDER BRUSH)}" Duration="0:0:0.1" Storyboard.TargetProperty="Background.Color"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation To="{Binding (CHOSEN BACKGROUND BURSH)}" Duration="0:0:0.1" Storyboard.TargetProperty="Background.Color"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>


My usage is:

<Button Grid.Row="1"
                Style="{StaticResource RoundButton}"
                Height="30"
                HorizontalAlignment="Right"
                Margin="10"
                Background="Green"
                BorderBrush="ForestGreen">

I would like to do that using only XAML, without any converters, if possible.

  • This will help https://stackoverflow.com/a/14158951/3137337 – emoacht May 07 '22 at 12:25
  • @emoacht I don't see it. I need the binding on the color. on this question the color is given – Leandro Manes May 08 '22 at 09:41
  • You can't bind to a dynamic value in an animation object as it needs to be frozen. You would have to define the colors as resources. – BionicCode May 08 '22 at 10:01
  • Alternatively, extend the Button class and then create a new animation with the current colors in C#. You would then have to create a new animation whenever the Background or BorderBrush changes (in case you want this to be dynamic). – BionicCode May 08 '22 at 10:05
  • @BionicCode I have the color as resources, aswell the brushes. What I wanted to achieve is that the programmer sets a bursh for the ```Background``` and a brush for the ```BorderBursh```. Then, when mouse enters, I would like to paint the background with the color from the borderbrush – Leandro Manes May 08 '22 at 10:07
  • 1
    Either use a simple Trigger (no animation) to accomplish this, or let the programmer override a resource key (to define a new color). Usually you aim for a homogeneous look throughout the application, hence elements like buttons are customized by (global) styles that reference predefined resources like colors or images. Therefore, the second solution to enforce the use of resources like a `Color` with a key `ButtonBackgroundColor` shouldn't be a problem. – BionicCode May 08 '22 at 10:30

1 Answers1

0

Please note that there are some limitations to using storyboards in a style, see Animate in a Style.

However, the easy solution would be to use the <ControlTemplate.Triggers> from the default Button template. Below, the "IsDefaulted" property is unchanged from the default Button template, Property="IsMouseOver" Value="true" is modified, and Property="IsMouseOver" Value="false" is added:

<ControlTemplate.Triggers>
  <Trigger Property="IsDefaulted" Value="true">
    <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
  </Trigger>
  <Trigger Property="IsMouseOver" Value="true">
   <Setter Property="Background" TargetName="border" Value="{Binding Path=BorderBrush, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"/>
   <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
 </Trigger>
 <Trigger Property="IsMouseOver" Value="false">
   <Setter Property="Background" TargetName="border" Value="{Binding Path=Background, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"/>
   <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
 </Trigger>
 ...

Or, try naming the brushes, see also How to: Animate a Property by Using a Storyboard and use a behavior, see XAML Behaviors for WPF. Use of behaviors is not shown here.

<Button.Background>
   <SolidColorBrush x:Name="backgroundBrush" Color="Green" />
</Button.Background>

...

<Button.BorderBrush>
  <SolidColorBrush x:Name="borderBrush" Color="ForestGreen" />
</Button.BorderBrush>

...

<Storyboard>
  <ColorAnimation Storyboard.TargetName="backgroundBrush" 
                  Storyboard.TargetProperty="Color" 
                  To="{Binding ElementName=borderBrush, Path=Color}" 
                  Duration="0:0:0.1" />
</Storyboard>
Benl
  • 2,777
  • 9
  • 13
  • please, where in the ```Style``` I add this code? I need to ```TemplateBinding``` my ```Border``` in my ```ControlTemplate``` to the ```Background``` of the ```Button```. Then, the animation will switch between them. I couldnt follow what you meant here – Leandro Manes May 12 '22 at 11:57
  • Please see edit. – Benl May 13 '22 at 15:20
  • I need this to be on a style in ```App.xaml```. I couldnt make it to work. Maybe is because I'm overriding the default control template with my own, as is in my original question. I just gave up and created 4 kinds of ```button``` with pre determined colors and effects – Leandro Manes May 14 '22 at 10:08