XAML 为什么使用自定义样式的WPF ToggleButton在悬停后显示未选中的颜色,即使它仍处于选中状态?

3b6akqbq  于 2023-08-01  发布在  其他
关注(0)|答案(1)|浏览(135)

本质上,我们有一个自定义样式的ToggleButton,其中包括未选中、选中和鼠标悬停状态的不同颜色。ToggleButton在被单击后正确显示选中状态的颜色。但是,当鼠标悬停在处于选中状态的ToggleButton上时,颜色会按预期更改,但是一旦鼠标移开,颜色会恢复到未选中状态的颜色,即使ToggleButton仍处于选中状态。
这是我的costum风格代码:

<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">
                            <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"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="CheckedMouseOver">
                                <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="#848383" Duration="0:0:0.2"/>
                                </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>

字符串
我将非常感谢,如果有人能帮助我与这件事,因为我还不是很熟悉自定义按钮样式

oxalkeyp

oxalkeyp1#

将Background设置为多个VisualStateGroups的目标。因此,其颜色将由这些VisualStateGroups中最后执行的情节串联板确定。您可以通过侦听每个情节串联图板的Completed事件来检查它。
查看普通ToggleButton的内部代码(忽略你神秘的CheckedMouseOver),CommonStatesVisualStateGroup的VisualState是由ButtonBase类的ChangeVisualState方法管理的。而CheckStatesVisualStateGroup通过ToggleButton类的ChangeVisualState方法进行管理。后者覆盖前者,并在方法顶部内部调用前者。因此,当调用ToggleButton的ChangeVisualState方法时,CommonStatesCheckStatesVisualStateGroups都将被设置。
在此ChangeVisualState方法中,调用VisualStateManager.GoToState方法来设置VisualState。我在使用VisualStateManager管理状态中找到了关于此方法的一个值得注意的解释。
如果控件已处于指定的状态,则GoToState不执行任何操作并返回true。
因此,考虑到IsChecked属性已经设置为true,因此CheckStatesVisualStateGroup的VisualState已经Checked的情况,当IsMouseOver属性更改并调用ChangeVisualState方法时,VisualStateManager.GoToState方法将不会对CheckStatesVisualStateGroup采取任何操作,因为其VisualState已经Checked。因此,CommonStatesVisualStateGroup中的故事板将是最后执行的故事板。
总之,不应将同一属性作为多个VisualStateGroups的目标。如果要根据MouseOver和Checked/Unchecked状态更改相同的属性,请创建一个自定义VisualStateGroup,它包含所有这些状态并自行管理它们。

相关问题