简体   繁体   English

C#WPF MVVM触发器永久更改按钮的背景色

[英]C# WPF MVVM trigger change background color of button permanently

I want to change the color of my button permanently, if the user clicked a button. 如果用户单击按钮,我想永久更改按钮的颜色。 How do I achieve that in XAML? 如何在XAML中实现这一目标? The trigger I have right now won't work, because they are only temporary, not overriding default values. 我现在拥有的触发器将不起作用,因为它们只是临时的,不会覆盖默认值。

Here my button template: 这是我的按钮模板:

<Style TargetType="{x:Type Button}" x:Key="ButtonStyleNavigation">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Foreground" Value="#FF365B74" /> 
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="FontFamily" Value="Arial" />
            <!-- <Setter Property="BorderThickness" Value="2"/>-->
            <!-- <Setter Property="BorderBrush" Value="Yellow"/>-->

            <Setter Property="FontSize" Value="15" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border CornerRadius="10" Background="{TemplateBinding Background}">
                            <Grid>
                                <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0" />
                            </Grid>
                        </Border>

                        <ControlTemplate.Triggers>

                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value="0.3"/>
                            </Trigger>

                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="Yellow" />
                                <Setter Property="Background" Value="#FF658EAA"/>
                            </Trigger>

                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" Value="Yellow" />
                                <Setter Property="Foreground" Value="#FF658EAA" />
                            </Trigger>

                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

SOLUTION: 解:

So, I was able to get what I needed with the use of a ToggleButton . 因此,使用ToggleButton可以得到所需的东西。 I've bound for each button one property to their IsChecked function. 我已将每个按钮的一个属性绑定到其IsChecked函数。 In my ViewModel I change the checked-state accordingly to my desire. 在我的ViewModel我根据自己的意愿更改了检查状态。 (mentioned in the comments) (在评论中提到)

Here is my new ToggleButton template: 这是我的新ToggleButton模板:

<Style TargetType="{x:Type ToggleButton}" x:Key="ButtonStyleNavigation">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Foreground" Value="#FF365B74" />
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="FontFamily" Value="Arial" />

            <Setter Property="FontSize" Value="15" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Border CornerRadius="10" Background="{TemplateBinding Background}" Height="19">
                            <Grid>
                                <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0" />
                            </Grid>
                        </Border>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Foreground" Value="Yellow" />
                                <Setter Property="Background" Value="#FF658EAA"/>
                            </Trigger>

                            <Trigger Property="IsChecked" Value="False">
                                <Setter Property="Background" Value="Transparent" />
                                <Setter Property="Foreground" Value="#FF365B74" />
                            </Trigger>

                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="Yellow" />
                                <Setter Property="Background" Value="#FF658EAA"/>
                            </Trigger>

                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" Value="Yellow" />
                                <Setter Property="Foreground" Value="#FF658EAA" />
                            </Trigger>

                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Sounds like you want a ToggleButton. 听起来像您想要一个ToggleButton。 They have a bool property called "IsChecked" that changes each time you click the button. 它们具有一个名为“ IsChecked”的布尔属性,该属性在每次单击按钮时都会更改。

Taking the style you provided and changing it like so should achieve what you want. 按照您提供的样式进行更改,这样应该可以实现您想要的。

<Style TargetType="{x:Type ToggleButton}" x:Key="ButtonStyleNavigation">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Foreground" Value="#FF365B74" />
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="FontFamily" Value="Arial" />

            <Setter Property="FontSize" Value="15" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Border CornerRadius="10" Background="{TemplateBinding Background}">
                            <Grid>
                                <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0" />
                            </Grid>
                        </Border>

                        <ControlTemplate.Triggers>

                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value="0.3"/>
                            </Trigger>

                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Background" Value="Yellow" />
                                <Setter Property="Foreground" Value="#FF658EAA" />
                            </Trigger>

                            <Trigger Property="IsChecked" Value="False">
                                <Setter Property="Background" Value="Transparent" />
                                <Setter Property="Foreground" Value="#FF658EAA" />
                            </Trigger>

                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

I have removed the IsMouseOver trigger as it conflicts with the IsChecked triggers. 我删除了IsMouseOver触发器,因为它与IsChecked触发器冲突。

When you say you permanently i presume this is what you mean. 当你永久地说你时,我想这就是你的意思。 If you wish for the button to remain the same colour after a user clicks on the button again, you will have to deal with click events and check for number of clicks on the button. 如果希望用户再次单击按钮后按钮保持相同的颜色,则必须处理单击事件并检查按钮的单击次数。

EDIT: 编辑:

As per your comment, if you want to have only one button enabled at time, look into using radio buttons instead. 根据您的评论,如果您一次只想启用一个按钮,则可以考虑使用单选按钮。

Here is a tutorial on getting multiple radio buttons set up. 是有关设置多个单选按钮的教程。

Check out this answer on how to style them to look like normal buttons. 请查看答案,了解如何设置它们的外观以使其类似于普通按钮。

You can then use the triggers in a similar fashion to check for enum values in your view model. 然后,您可以类似的方式使用触发器来检查视图模型中的枚举值。

Here is a pure xaml answer, using a ControlTemplate as requested, taking your original question and just changing the <ControlTemplate.Triggers> section: 这是一个纯粹的xaml答案,根据要求使用ControlTemplate ,以您的原始问题,仅更改<ControlTemplate.Triggers>部分:

<ControlTemplate.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)" To="Yellow" Duration="0"/>
                <ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="#FF658EAA" Duration="0"/>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</ControlTemplate.Triggers>

In your original question you had (perhaps unintentionally) triggered from the mouse over event, in which case change here the RoutedEvent accordingly. 在最初的问题中,您(可能是无意地)将鼠标悬停事件触发了,在这种情况下,请相应地更改RoutedEvent

NB. 注意 You may be able to find an alternative to ColourAnimation with a zero duration, but I thought I'd post this as it at least gives you something to work with. 您也许可以找到持续时间为零的ColourAnimation替代方案,但我认为我会发布此替代方案,因为它至少为您提供了一些有用的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM