WPF切换按钮样式受到悬停的影响

时间:2017-12-26 06:44:54

标签: c# wpf

我已将自定义样式应用于带控制模板的切换按钮。我有不同的背景颜色和边框默认状态,检查状态和鼠标悬停。问题是,当我将鼠标悬停在已检查状态上时,即使实际检查了切换按钮,WPF也会重置样式,就好像未选中按钮(默认状态外观)一样。

这是我的代码

<Style x:Key="MenuItem" TargetType="ToggleButton">
    <Setter Property="Background" Value="Transparent"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Cursor" Value="Hand"/>
        </Trigger>
    </Style.Triggers>
</Style>

<ControlTemplate x:Key="MenuButton" TargetType="{x:Type ToggleButton}">

    <Border x:Name="border" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderThickness="4,0,0,0">
        <StackPanel x:Name="MenuItemContainer" Orientation="Horizontal" Height="46" Margin="14,0,0,0" Background="Transparent">
            <TextBlock x:Name="icon" Grid.Column="0" VerticalAlignment="Center" FontFamily="{StaticResource FontAwesome}"  Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Tag}" Margin="0,0,6,0"/>
            <TextBlock x:Name="menuText" VerticalAlignment="Center" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Property=ContentControl.Content}"/>
        </StackPanel>

        <VisualStateManager.VisualStateGroups>

            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
                        <ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="border">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <SolidColorBrush Color="{StaticResource ColorMenuItemBg}" />
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="border">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <SolidColorBrush Color="{StaticResource ColorMenuItemBorderHover}"/>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal"/>
            </VisualStateGroup>

            <VisualStateGroup x:Name="CheckStates">
                <VisualState x:Name="Checked">
                    <Storyboard>
                        <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="border">
                            <EasingThicknessKeyFrame KeyTime="0" Value="4,0,0,0"/>
                        </ThicknessAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="border">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <SolidColorBrush Color="{StaticResource ColorMenuItemBorder}"/>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
                        <ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/>

                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="border">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <SolidColorBrush Color="{StaticResource ColorMenuItemBg}"/>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Unchecked"/>
            </VisualStateGroup>


        </VisualStateManager.VisualStateGroups>
    </Border>
</ControlTemplate>

<StackPanel>
            <ToggleButton Tag="&#xf015;" Content="Home" Template="{StaticResource MenuButton}" Style="{StaticResource MenuItem}" />

            <ToggleButton Tag="&#xf1fe;" Content="Reporting" Template="{StaticResource MenuButton}" Style="{StaticResource MenuItem}"/>
</StackPanel>

如果您点击一个切换按钮,您将看到它将获得绿色边框和不同的背景颜色,但是如果您将鼠标悬停在它上面并保留它,它似乎将显示为默认按钮。

我在这里缺少什么?

提前谢谢你!

1 个答案:

答案 0 :(得分:1)

您在模板中定义了两个VisualtStateGroups。这样,您的ToggleButton将始终具有两个活动状态(每组一个)。问题是您在两个不同的组中从VisualStates设置相同的对象属性。当您检查ToggleButton并且鼠标离开按钮时,控件会为每个组更新其活动的VisualState。由于您从两个组中的活动状态设置 Border.Background Border.BorderBrush ,因此获取的最后一个状态获胜(在您的情况下为CommonStates / Normal)。

要解决此问题,请尽量避免从多个组中设置相同的属性。例如,您可以在MouseOver-State中设置Stackpanel的背景,而不是边框​​背景。这样,如果鼠标离开,ToggleButton会保持检查状态,因为“CommonState / Normal”-State不会重置边框的背景。

                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
                                <ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/>

                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="MenuItemContainer">
                                    <DiscreteObjectKeyFrame KeyTime="0">
                                        <DiscreteObjectKeyFrame.Value>
                                            <SolidColorBrush Color="{StaticResource ColorMenuItemBg}" />
                                        </DiscreteObjectKeyFrame.Value>
                                    </DiscreteObjectKeyFrame>
                                </ObjectAnimationUsingKeyFrames>

                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Normal"/>
                    </VisualStateGroup>

希望这有用!