在WPF中,在事件触发时更改按钮背景颜色

8

我正在尝试在用户单击按钮时更改按钮的背景颜色。我使用触发器来实现。

我的XAML如下:

<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" />

我尝试了各种设置,但是无法在单击鼠标时更改按钮的背景颜色。我也参考了各种网站-MSDNSharpCornerCodeProject以及其他许多网站。我不知道哪里出了问题,请问该如何在单击事件中更改按钮的Background颜色?谢谢。

你的IsMouseOver触发器起作用了吗?如果是,为什么不以同样的方式添加ISPressed呢? - o_weisman
1
@o_weisman,IsMouseOver也不起作用了... - Tvd
2个回答

15
在这种情况下,您需要使用EventTriggerStoryboard,因为[Source]:

EventTrigger - 表示在事件发生时应用一组动作(动画故事板)的触发器。

示例:
<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>

这里在资源中定义了Storyboard,它定义了颜色为ButtonBrush的内容,并在Click事件中进行设置。更多信息请参见:

MSDN:EventTrigger

Edit

是的,EventTrigger可以像这样在模板中使用:

<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>

如果你想通过一个Storyboard与其他按钮进行联系,可以这样做:

<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>
在这种情况下,您只需要为每个按钮指定TargetName。当您单击第一个按钮时,剩余按钮的颜色会更改为默认值BlueViolet

输入图像描述


更完整的回复。我应该删除我的吗? :D - Nathan
@Nath:随你喜欢:),你可以编辑你的回答,提供一个更完整的例子,并引导其他信息源。 - Anatoliy Nikolaev
谢谢Anatoliy和@Nath。我相信可以使用Triggers、Style、ControlTemplates来实现这个功能。我以前没有使用过StoryBoard。是的,你的解决方案在按钮单击事件上改变了颜色。但是我有3个按钮,我想为所有3个按钮设置相同的颜色。即当btnSide被点击时,它的颜色变成橙色,而另外2个按钮btnHorz和btnVert则恢复到蓝色。我已经在我的面板中为所有3个按钮设置了EventTrigger,调用同一个ChangeBackgroundStoryboard,希望能起作用。在ChangeBackgroundStoryboard中,我如何将其他2个按钮的颜色改回norm clr? - Tvd
没有其他需要添加的内容了:)如果可以的话,我会点赞10或20次,非常好的答案。 - aledustet
非常感谢您:) - Anatoliy Nikolaev
@AnatoliyNikolaev,我尝试了两种方法来改变单击一个按钮时三个按钮颜色的方式 - 但是一旦将它们转换为橙红色,按钮就无法恢复为蓝紫色。即:一次按钮单击后,它的颜色变为橙红色,然后另一个按钮被单击,其颜色变为橙红色。此时,先前的按钮颜色不会返回到蓝紫色 - 尽管在XAML中进行了编码。我在代码后台应用相同的逻辑,在按钮单击事件中编写了3行来更改3个按钮的颜色,而它完全可以正常工作。我认为在代码中处理这种情况比在XAML中管理更简单、更容易。 - Tvd

0
在WPF中,您可以使用Storyboard来对对象进行动画处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接