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

自定义样式WPF ToggleButton选中态移出鼠标后显示未选中颜色问题

解决WPF ToggleButton选中状态鼠标移开后颜色异常问题

自定义了带样式的WPF ToggleButton,设置了未选中、选中及鼠标悬停的不同颜色。点击后能正确显示选中状态颜色,但鼠标悬停在已选中的按钮上,移开鼠标后,按钮颜色变回未选中状态,尽管实际仍处于选中状态。

问题原因

  • CommonStates中的MouseOver状态会直接覆盖Border的背景色,鼠标离开回到Normal状态时,没有根据当前IsChecked值恢复对应颜色;
  • 自定义的CheckedMouseOver状态不属于WPF默认的视觉状态组,无法被自动触发,导致选中状态下的悬停逻辑失效。

修复方案

修改视觉状态逻辑,确保CheckStates的状态在鼠标离开后能正确保留,同时让状态组合自动生效。以下是修复后的完整样式代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Style TargetType="ToggleButton" x:Key="ToggleButtonTheme">
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <Grid>
                    <Grid.Resources>
                        <Storyboard x:Key="ToggleOnAnimation">
                            <DoubleAnimation Storyboard.TargetName="SlideButton"
                                             Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                             To="12" Duration="0:0:0.1"/>
                        </Storyboard>
                        <Storyboard x:Key="ToggleOffAnimation">
                            <DoubleAnimation Storyboard.TargetName="SlideButton"
                                             Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                             To="-12" Duration="0:0:0.1"/>
                        </Storyboard>
                    </Grid.Resources>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Disabled"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    To="#848383" Duration="0:0:0.1"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CheckStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition From="*" To="Checked" GeneratedDuration="0:0:0.2"/>
                                <VisualTransition From="*" To="Unchecked" GeneratedDuration="0:0:0.2"/>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Unchecked">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="SlideButton"
                                                     Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                                     To="-12" Duration="0:0:0.1"/>
                                    <ColorAnimation Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    To="#a3a2a2" Duration="0:0:0.2"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Checked">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="SlideButton"
                                                     Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                                     To="12" Duration="0:0:0.1"/>
                                    <ColorAnimation Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
                                                    To="#474646" Duration="0:0:0.2" FillBehavior="HoldEnd"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="Border"
                            Background="#a3a2a2"
                            CornerRadius="12"
                            BorderThickness="0">
                        <Grid>
                            <ContentPresenter HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              Margin="5"/>
                            <Border x:Name="SlideButton"
                                    Background="White"
                                    CornerRadius="13"
                                    BorderThickness="0"
                                    Width="16" Height="16">
                                <Border.RenderTransform>
                                    <TranslateTransform X="0"/>
                                </Border.RenderTransform>
                            </Border>
                        </Grid>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</ResourceDictionary>

关键修改点

  1. 给Checked状态的ColorAnimation添加FillBehavior="HoldEnd",确保动画结束后保持目标颜色,不会因为回到Normal状态而重置;
  2. 添加VisualStateGroup.Transitions,保证状态切换时的动画平滑执行,避免状态冲突;
  3. 移除无效的CheckedMouseOver状态,WPF会自动组合CommonStates和CheckStates的状态:当按钮处于Checked+MouseOver时,悬停颜色会覆盖选中颜色;鼠标离开后回到Checked+Normal,选中状态的颜色会被正确保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:37:02