根据状态

时间:2016-06-20 11:59:33

标签: c# button uwp visualstatemanager

我正在使用UWP在C#中制作简单的Tic Tac Toe游戏。

我想添加一些效果,这样当鼠标悬停在一个单元格上时,它会显示符号的重影。但是如果已经放置了一个符号,它应该略微淡化符号。

实现这一目标的好方法是什么?

  

所需效果的示例:
  enter image description here
  顶部中心是符号放置,鼠标未结束。
  中心符号放置,鼠标悬停。
  中心右侧是符号未放置,鼠标悬停。
  其他单元格未放置符号,鼠标未结束。

目前,我有一个ControlTemplate定义如下:

<VisualStateGroup x:Name="CommonStates">
    <VisualState x:Name="NormalSolid" >
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PlayerIcon">
                <EasingDoubleKeyFrame KeyTime="0" Value="0.75"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="PointerOverSolid">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PlayerIcon">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.75"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="Normal" >
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PlayerIcon">
                <EasingDoubleKeyFrame KeyTime="0" Value="0.25"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
    <VisualState x:Name="PointerOver">
        <Storyboard>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="PlayerIcon">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0.25"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </VisualState>
</VisualStateGroup>

然后,它会像这样改变:

private void GameButton_PointerExited(object sender, PointerRoutedEventArgs e)
{
    GameButton button = sender as GameButton;
    VisualStateManager.GoToState(button, "Normal" + (!this.ShapePlaced ? "" : "Solid"), true);

}

private void GameButton_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    GameButton button = sender as GameButton;
    VisualStateManager.GoToState(button, "PointerOver" + (!this.ShapePlaced ? "" : "Solid"), true);
}

(其中GameButton是Button的简单子类,而PlayerIcon是表示绘制形状的形状)

但这会导致点击+拖动按钮的问题,以及不可靠。是否可以将两组状态(放置形状与未放置)放在不同的VisualStateGroup中,并根据它的当前状态切换“活动”组?

基本上,我需要2个普通状态,2个PointerOver状态,以及在它们之间切换的方法。

1 个答案:

答案 0 :(得分:2)

您可以根据自己的喜好修改默认的按钮样式。它已经定义了所有状态和转换,因此您不需要在后面的代码中使用事件。

<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
<Setter Property="Padding" Value="8,4,8,4"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="Button">
            <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal">
                            <Storyboard>
                                <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="PointerOver">
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Pressed">
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Disabled">
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}"/>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

在Visual Studio 2015中获取此样式(以及任何控件的默认样式)的最简单方法是使用&#39;文档大纲&#39;工具窗口。在窗口的树形视图中选择控件,右键单击并选择Edit Template - &gt;编辑副本。这将显示控件的默认样式,您可以对其进行修改并将其应用回控件。