如何实现边缘按钮指针事件?

时间:2018-03-12 00:44:09

标签: xaml button uwp microsoft-edge

Edge Buttons

我只在边缘按钮中看到过这种按钮样式,并想知道如何实现它。所以有两种不同的效果(据我所知)。首先,当按下按钮时,它们内部的内容会缩小(与Windows提供的默认效果不同),然后在按下时,按钮内部会出现一个黑暗的非离散边框,几乎让人感觉到它的深度。

1 个答案:

答案 0 :(得分:1)

这个问题是一个挑战!

我的第一个想法是使用UWP Community Toolkit DropShadowPanel创建阴影并将其剪辑到按钮的矩形。不幸的是,这不能很好地工作,因为我必须在需要有可见边框的Rectangle上设置阴影,这对于我们有一个很好的混合无边框按钮的目的来说并不是很好。此外,DropShadowPanel阴影并没有提供足够强大的阴影效果,足以使按钮在Edge中看起来像。

我使用Visual Studio并将其附加到Edge浏览器以查看浏览器实际使用的控件。 Live Tree Visualizer透露了这一点:

SpartanXAML.InnerShadowControl

SpartanXAML.InnerShadowControl?好的,我们没有。让我们解决这个问题。

我解雇了Photoshop。创建一个64x64的方形图像,在表面上放置一个透明的矩形图层并设置其Inner Glow,如此截图所示:

Inner Glow

导出后,我得到了以下PNG:

Glow

看起来很像Edge按钮上的内部阴影!

现在让我们创建一个使用此图片的自定义按钮样式!

<Style TargetType="Button" x:Key="EdgeButtonStyle">
    <Setter Property="Background" Value="#f5f5f5" />
    <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
    <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
    <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
    <Setter Property="Padding" Value="8" />
    <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="FocusVisualMargin" Value="-3" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="RootGrid" Width="64" Height="64" 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.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#c1c1c0" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>

                            <VisualState x:Name="Pressed">

                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#c1c1c0" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Scale" Storyboard.TargetProperty="ScaleX">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0.8" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Scale" Storyboard.TargetProperty="ScaleY">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0.8" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerShadow" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                    </ObjectAnimationUsingKeyFrames>

                                </Storyboard>
                            </VisualState>

                            <VisualState x:Name="Disabled">

                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>

                    </VisualStateManager.VisualStateGroups>


                    <ContentPresenter x:Name="ContentPresenter"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Content="{TemplateBinding Content}"
            ContentTransitions="{TemplateBinding ContentTransitions}"
            ContentTemplate="{TemplateBinding ContentTemplate}"
            Padding="{TemplateBinding Padding}"
            HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
            VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
            AutomationProperties.AccessibilityView="Raw">
                        <interactivity:Interaction.Behaviors>
                            <behaviors:Scale x:Name="Scale"
                                    ScaleX="1"
                                    ScaleY="1"
                                    CenterX="32"
                                    CenterY="32"
                                    Duration="100"
                                    Delay="0"
                                    EasingType="Default"
                                    AutomaticallyStart="True"/>
                        </interactivity:Interaction.Behaviors>
                    </ContentPresenter>

                    <Image Source="/Assets/InnerShadowGray.png" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed" x:Name="InnerShadow" />

                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这是一个冗长的列表,所以我只想指出最有趣的事情:

  • 从按钮
  • 中删除了所有边框
  • 将背景设置为#f5f5f5并将背景悬停至#c1c1c0以匹配Edge
  • 将宽度和高度设置为64
  • 添加Image作为RootGrid中的最后一个控件,这是阴影图像,默认为Collapsed,仅在按下指针时显示
  • 使用UWP社区工具包(Microsoft.Toolkit.Uwp.UI.Controls NuGet包)Scale行为来创建简单,易于控制的动画。这需要将xmlns:interactivity="using:Microsoft.Xaml.Interactivity"xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors" XML命名空间添加到文件的根元素
  • 使用PointerDownThemeAnimation行为将自定义动画替换为默认Scale,以使动画更加重要并均匀缩放,而不会使内容发生偏差

现在让我们按下我们的新按钮进行试乘!

<Button Style="{StaticResource EdgeButtonStyle}" HorizontalAlignment="Center">
    <Image Source="Assets/Windows.png" />
</Button>

结果:

Result