8

I am trying to change the Background color of my Button when the user clicks it. I am using triggers to achieve it.

My XAML is:

<UserControl.Resources>
    <Style x:Key="myBtnStyle" TargetType="{x:Type Button}">
        <!--VerticalAlignment="Top"  VerticalContentAlignment="Top" Background="Blue"  HorizontalAlignment="Right"
        Height="24" Width="25" FontSize="16" FontWeight="Bold"  -->
        <Setter Property="VerticalAlignment" Value="Top" /> 
        <Setter Property="VerticalContentAlignment" Value="Top" />
        <Setter Property="Background" Value="Blue" />
        <Setter Property="HorizontalAlignment" Value="Right" />
        <Setter Property="Height" Value="24" />
        <Setter Property="Width" Value="25" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="FontWeight" Value="Bold" />
        <Style.Triggers>
            <Trigger Property="Button.IsMouseOver" Value="true">
                <Setter Property="Background" Value="Yellow" />
            </Trigger>
        </Style.Triggers>
    </Style>
 <!--   
    <ControlTemplate x:Key="btnTemplate" TargetType="{x:Type Button}">
        <ControlTemplate.Triggers>
            <Trigger Property="IsPressed" Value="True" >
                <Setter Property="Background" Value="Cyan" />
            </Trigger>

        </ControlTemplate.Triggers>
    </ControlTemplate> -->
</UserControl.Resources>

<Button DockPanel.Dock="Right" Style="{StaticResource myBtnStyle}"  Name="btnVert" Click="btnVert_Click"
                Margin="10,10,10,0" ToolTip="Vertical" Content="V" />

I tried various settings, but couldn't get the Background color changed on the Button when mouse is clicked. Also referred various sites - MSDN, SharpCorner, CodeProject and many others too. Couldn't get where am I going wrong?

How to get the Background color changed of Button on clicked event?

Thanks.

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
Tvd
  • 4,463
  • 18
  • 79
  • 125

2 Answers2

15

In this situation, you need to use EventTrigger with Storyboard, because [Source]:

EventTrigger - represents a trigger that applies a set of actions (animation storyboards) in response to an event.

Example:

<Window.Resources>
    <SolidColorBrush x:Key="ButtonBrush" Color="OrangeRed" />

    <Storyboard x:Key="ChangeBackgroundStoryboard">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ChangeBackgroundButton"
                                       Storyboard.TargetProperty="Background">

            <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                    Value="{StaticResource ButtonBrush}" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

<Grid>
    <Grid.Triggers>
        <EventTrigger SourceName="ChangeBackgroundButton" 
                      RoutedEvent="Button.Click">

            <BeginStoryboard Storyboard="{StaticResource ChangeBackgroundStoryboard}" />
        </EventTrigger>
    </Grid.Triggers>

    <Button Name="ChangeBackgroundButton"
            Content="TestButton"
            VerticalAlignment="Center"
            HorizontalAlignment="Center" />
</Grid>

Here Storyboard defined in resources, which defines the color ButtonBrush, which is set at the Click event. For more information, please see:

MSDN: EventTrigger

Edit

Yes, EventTrigger can be used in the template like this:

<Window.Resources>
    <SolidColorBrush x:Key="IsMouseOverBackground" Color="AliceBlue" />
    <SolidColorBrush x:Key="IsPressedBrush" Color="Gainsboro" />
    <SolidColorBrush x:Key="ButtonBrush" Color="OrangeRed" />

    <Storyboard x:Key="ChangeBackgroundStoryboard">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background">
            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ButtonBrush}" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>

    <Style x:Key="FlatButtonBaseStyle" TargetType="{x:Type Button}">
        <Setter Property="Width" Value="60" />
        <Setter Property="Height" Value="20" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="BorderBrush" Value="Gray" />
        <Setter Property="Background" Value="Transparent" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Name="Border"
                        Background="{TemplateBinding Background}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}">

                        <ContentPresenter Name="Content"
                                      Content="{TemplateBinding Content}" 
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      TextBlock.FontFamily="{TemplateBinding FontFamily}" 
                                      TextBlock.FontSize="{TemplateBinding FontSize}" />
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource IsMouseOverBackground}" />
                            <Setter Property="Opacity" Value="1" />
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="{StaticResource IsPressedBrush}" />
                        </Trigger>

                        <!-- Here --> 
                        <EventTrigger RoutedEvent="Button.Click">
                            <BeginStoryboard Storyboard="{StaticResource ChangeBackgroundStoryboard}" />
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<WrapPanel>
    <Button Content="Fisrt"                
            Style="{StaticResource FlatButtonBaseStyle}" 
            Margin="10" />

    <Button Content="Second"
            Style="{StaticResource FlatButtonBaseStyle}"
            Margin="10" />

    <Button Content="Third"
            Style="{StaticResource FlatButtonBaseStyle}" 
            Margin="10" />
</WrapPanel>

As for the possibility of contact to the other buttons through one Storyboard, you can do so:

<Window.Resources>
    <SolidColorBrush x:Key="ButtonBrush" Color="OrangeRed" />
    <SolidColorBrush x:Key="DefaultButtonBrush" Color="BlueViolet" />
</Window.Resources>

<WrapPanel>
    <WrapPanel.Triggers>
        <EventTrigger SourceName="FisrtButton" 
                      RoutedEvent="Button.Click">

            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FisrtButton"
                                       Storyboard.TargetProperty="Background">

                        <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                    Value="{StaticResource ButtonBrush}" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SecondButton"
                                       Storyboard.TargetProperty="Background">

                        <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                    Value="{StaticResource DefaultButtonBrush}" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ThirdButton"
                                       Storyboard.TargetProperty="Background">

                        <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                    Value="{StaticResource DefaultButtonBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </WrapPanel.Triggers>

    <Button Name="FisrtButton"
            Content="Fisrt"                
            Margin="10" />

    <Button Name="SecondButton"
            Content="Second"
            Margin="10" />

    <Button Name="ThirdButton"
            Content="Third"
            Margin="10" />
</WrapPanel>

In this case, you just need to specify TargetName for every Button, when you click on the first Button, the color of the remaining changes to default BlueViolet:

enter image description here

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
  • A more complete response. Shall I delete mine? :D – Nathan Feb 11 '14 at 14:37
  • @Nath: As you like :), you can edit your answer with a more complete example, and lead other sources of information. – Anatoliy Nikolaev Feb 11 '14 at 14:39
  • Thanks #Anatoliy, @Nath. I believed their was a way where this can be achieved using Triggers, Style, ControlTemplates. I haven't used StoryBoard before. Yes your solution changes the color on its button click event. But I have 3 buttons, and I wanted to set the same for all 3 i.e. when btnSide is clicked, its color becomes Orange & other 2 btns i.e. btnHorz & btnVert turn back to normal color i.e. Blue. I have set EventTrigger in my panel for all 3 btns calling same ChangeBackgroundStoryboard, hope works. In ChangeBackgroundStoryboard, how do I change color of other 2 btns back to norm clr ? – Tvd Feb 11 '14 at 15:03
  • Nothing else left to add :), great answer if i could i would upvote 10 or 20 times – aledustet Feb 11 '14 at 18:00
  • @AnatoliyNikolaev, I tried both the ways to change color of 3 btns on 1 btn click - But once turned OrangeRed btn is not becoming back to BlueViolet color. i.e. Once btn is clicked, its color changed to OrangeRed, then other btn click its color became OrangeRed. HERE previous btn color doesn't change back to BlueViolet - though it is coded in XAML respectively. The same logic I applied in code behind wrote 3 lines to change the color of 3 btns on btn click event & it does work perfectly well. I guess handling this situation in code is much simpler & easier than managing the same in XAML. – Tvd Feb 13 '14 at 08:49
0

In WPF, you can animate objects by using Storyboard.

Nathan
  • 1,220
  • 3
  • 15
  • 26