WPF状态,在多个状态下设置相同属性的正确方法是什么

时间:2017-12-26 02:21:07

标签: c# wpf

我正在尝试设置切换按钮的样式,我希望所选状态的前景颜色和MouseOver状态为白色。

我的风格如下:

  <Window.Resources>
    <ControlTemplate x:Key="MenuButton" TargetType="{x:Type ToggleButton}">
        <Border x:Name="border" >
            <VisualStateManager.VisualStateGroups>

                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="MouseOver">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Cursor)" Storyboard.TargetName="MenuItemContainer">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Cursor>Hand</Cursor>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="menuText">
                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                            </ColorAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="icon">
                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                            </ColorAnimationUsingKeyFrames>
                        </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="#FF19AA8D"/>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="icon">
                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                            </ColorAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="menuText">
                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Unchecked"/>
                </VisualStateGroup>


            </VisualStateManager.VisualStateGroups>

            <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="&#xF009;" Margin="0,0,6,0"/>
                <TextBlock x:Name="menuText" VerticalAlignment="Center" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Property=ContentControl.Content}"/>
            </StackPanel>
        </Border>
    </ControlTemplate>
</Window.Resources>

这样可以正常工作,对于MouseOver和Selected状态,前景设置为白色。但是,在Expression Blend Designer中,我看到一条警告消息,其中显示&#34;为了避免不可预测的行为,您不应该在多个状态中更改对象属性...&#34;

我应该忽略这个警告还是有更好的方法来实现我想要实现的目标?

由于

1 个答案:

答案 0 :(得分:0)

是的,你应该关心这个警告。事实上,这种风格并没有正确行事。做以下测试:

1:将按钮设置为选中 - &gt;文字变成白色 - &gt;确定

2:移开鼠标 - &gt;文字保持白色 - &gt;确定

3:将鼠标移到按钮上 - &gt;文字保持白色 - &gt;确定

4:移开鼠标 - &gt;文本将返回到未经检查的默认颜色 - &gt;不行

换句话说,您不应该从两个不同的可视状态组修改同一控件的相同属性。仅仅因为最后的改变获胜。

您的案例中的解决方案可能是:

    <ControlTemplate x:Key="MenuButton" TargetType="{x:Type ToggleButton}">
        <Border x:Name="border" >
            <VisualStateManager.VisualStateGroups>

                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="MouseOver">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Cursor)" Storyboard.TargetName="MenuItemContainer">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Cursor>Hand</Cursor>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="menuTextMouseOver">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="iconMouseOver">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="menuText">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="icon">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                            </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="#FF19AA8D"/>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="icon">
                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                            </ColorAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="menuText">
                                <EasingColorKeyFrame KeyTime="0" Value="White"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Unchecked"/>
                </VisualStateGroup>


            </VisualStateManager.VisualStateGroups>

            <StackPanel x:Name="MenuItemContainer" Orientation="Horizontal" Height="46" Margin="14,0,0,0" Background="Transparent" >
                <TextBlock x:Name="iconMouseOver" Grid.Column="0" VerticalAlignment="Center" Foreground="White" FontSize="13" Text="the icon" Margin="0,0,6,0" Visibility="Collapsed"/>
                <TextBlock x:Name="menuTextMouseOver" VerticalAlignment="Center" Foreground="White" FontSize="13" Text="{TemplateBinding Property=ContentControl.Content}" Visibility="Collapsed"/>
                <TextBlock x:Name="icon" Grid.Column="0" VerticalAlignment="Center" Foreground="#a7b1c2" FontSize="13" Text="the icon" Margin="0,0,6,0"/>
                <TextBlock x:Name="menuText" VerticalAlignment="Center" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Property=ContentControl.Content}"/>
            </StackPanel>
        </Border>
    </ControlTemplate>