C# WPF切换按钮样式受悬停影响

C# WPF切换按钮样式受悬停影响,c#,wpf,C#,Wpf,我已将自定义样式应用于带有控件模板的切换按钮。对于默认状态、选中状态和鼠标悬停,我有不同的背景颜色和边框。问题是,当我将鼠标悬停在选中状态上时,WPF会将样式重置为“按钮未选中”为默认状态外观,即使实际上选中了“切换”按钮 这是我的密码 <Style x:Key="MenuItem" TargetType="ToggleButton"> <Setter Property="Background" Value="Transparent"/> <Styl

我已将自定义样式应用于带有控件模板的切换按钮。对于默认状态、选中状态和鼠标悬停,我有不同的背景颜色和边框。问题是,当我将鼠标悬停在选中状态上时,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>
如果你点击一个切换按钮,你会看到它将得到绿色边框和不同的背景颜色,但是如果你将鼠标悬停在它上面并离开它,它似乎会显示为默认按钮

我错过了什么


提前谢谢你

您在模板中定义了两个VisualStateGroup。这样,您的ToggleButton将始终具有两个活动状态,每组一个。问题在于,您正在两个不同的组中从VisualState设置相同的对象属性。当您选中一个ToggleButton且鼠标离开该按钮时,控件将为每个组更新其活动的VisualState。由于您将Border.Background和Border.BorderBrush设置为两个组中的活动状态,因此在您的案例中,应用的最后一个状态将赢得CommonStates/Normal

要解决此问题,请尝试避免从多个组设置相同的属性。例如,可以将Stackpanel的背景设置为鼠标悬停状态,而不是边框背景。这样,如果鼠标离开,切换按钮将保持选中状态,因为CommonState/Normal状态不会重置边框的背景

                    <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>

希望这是有帮助的

非常感谢。您不仅解决了这个问题,而且还解释了WPF在不同视觉状态组中的行为!请您向我解释一下,拥有多个可视状态组是一种不好的做法,还是只需要小心不要设置相同的属性值?最好的做法是什么?你是韦克洛姆!在模板中有多个VisualState组是非常好的。事实上,如果您查看wpf控件的默认样式,大多数都定义了3个或更多状态组。只要确保它们的状态没有设置相同的属性。