You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3中如何为按钮设置选中、悬浮、点击时的不同颜色

WinUI实现单选按钮组(带自定义样式)

解决你遇到的问题,核心是用ToggleButton替代普通Button:它自带选中/未选中状态,且通过GroupName属性可自动实现同组单选互斥,不用手动写按钮重置逻辑。以下是具体实现步骤:

1. 替换按钮为ToggleButton并设置分组

把原来的Button换成ToggleButton,给同组按钮设置相同的GroupName,这样点击其中一个时,同组其他ToggleButton会自动取消选中:

<ToggleButton
    Style="{StaticResource RadioToggleButtonStyle}"
    Grid.Row="0"
    Grid.Column="0"
    Height="40"
    HorizontalAlignment="Stretch"
    Content="InRegion"
    x:Name="InRegion"
    GroupName="RegionGroup"/>

<ToggleButton
    Style="{StaticResource RadioToggleButtonStyle}"
    Grid.Row="0"
    Grid.Column="2"
    Height="40"
    HorizontalAlignment="Stretch"
    Content="OutRegion"
    x:Name="OutRegion"
    GroupName="RegionGroup"/>

2. 修改样式支持选中状态

ToggleButton内置CheckStates视觉状态组(包含Checked/Unchecked/Indeterminate),你只需要在样式中添加这个组的状态逻辑即可,不用自己定义不存在的Selected状态:

<Style x:Key="RadioToggleButtonStyle"
       BasedOn="{StaticResource DefaultToggleButtonStyle}"
       TargetType="ToggleButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                    <Border BorderThickness="1"
                            BorderBrush="LightGray"
                            CornerRadius="3">
                        <Rectangle x:Name="ButtonBase"
                                   Fill="#fbfbfb" />
                    </Border>
                    <ContentPresenter HorizontalAlignment="Center"
                                      VerticalAlignment="Center" />
                    <VisualStateManager.VisualStateGroups>
                        <!-- 保留你原来的悬浮、按压、禁用状态 -->
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBase"
                                                                   Storyboard.TargetProperty="Fill">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="yellow" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBase"
                                                                   Storyboard.TargetProperty="Fill">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="ForestGreen" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBase"
                                                                   Storyboard.TargetProperty="Fill">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="DarkOliveGreen" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <!-- 添加ToggleButton专属的选中状态组 -->
                        <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Unchecked" />
                            <VisualState x:Name="Checked">
                                <Storyboard>
                                    <!-- 设置选中时的背景色 -->
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBase"
                                                                   Storyboard.TargetProperty="Fill">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="LightSeaGreen" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <!-- 设置选中时的文字颜色 -->
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
                                                                   Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0"
                                                                Value="White" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Indeterminate" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

3. 简化后台代码

因为ToggleButton的GroupName已经自动处理了单选互斥,你不需要再写按钮重置逻辑,只需要在点击事件中处理业务逻辑即可:

private void buttonsRegion_click(object sender, RoutedEventArgs e)
{
    var selectedToggle = sender as ToggleButton;
    if (selectedToggle?.IsChecked == true)
    {
        // 这里处理选中后的业务操作,比如获取选中项的值
        string selectedContent = selectedToggle.Content.ToString();
        // ... 你的业务代码
    }
}

说明

普通Button确实没有Selected状态,你手动添加的VisualState不会被控件触发,因为控件本身没有对应的状态切换逻辑。而ToggleButton不仅自带选中状态,还支持分组互斥,完全匹配你需要的单选按钮组需求,且样式可以统一复用给不同的按钮组(只需给不同组设置不同的GroupName即可)。

内容的提问来源于stack exchange,提问作者Mateusz Marczewski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:47:32