[UWP]使用Reveal

C#

浏览数:123

2019-5-16

AD:资源代下载服务

1. 前言

之前在 如何使用Fluent Design System 这篇文章里已经简单介绍过Reveal的用法,这篇再详细介绍其它内容。

2. 自定义RevealButtonStyle

我觉得常用ItemsControl都已经自动应用了Reveal,用就是了。

没有默认应用Reveal的控件,UWP也为其中一部分提供了可用的Reveal样式。

只需简单地应用Style即可:

<Button Content="Button Content" Style="{StaticResource ButtonRevealStyle}"/>

其它用法官方文档也有很详细的教程,一时也想不到能玩出什么花样。。

但既然Reveal最大的作用是为一组元素提示其可操作区域,那么对无边框按钮来说Reveal就很重要了。UWP没有提供无边框按钮的Reveal样式,可以自己实现一个:

<Style TargetType="Button">
    <Setter Property="Background"
            Value="{ThemeResource ButtonRevealBackground}" />
    <Setter Property="Foreground"
            Value="{ThemeResource ButtonForeground}" />
    <Setter Property="BorderBrush"
            Value="{ThemeResource ButtonRevealBorderBrush}" />
    <Setter Property="BorderThickness"
            Value="{ThemeResource ButtonRevealBorderThemeThickness}" />
    <Setter Property="Margin"
            Value="3" />
    <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="20" />
    <Setter Property="UseSystemFocusVisuals"
            Value="True" />
    <Setter Property="FocusVisualMargin"
            Value="-3" />
    <Setter Property="Height"
            Value="50" />
    <Setter Property="Width"
            Value="50" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid x:Name="RootGrid">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <VisualState.Setters>
                                    <Setter Target="RootGrid.(RevealBrush.State)"
                                            Value="PointerOver" />
                                    <Setter Target="BackgroundElement.Fill"
                                            Value="{ThemeResource ButtonRevealBackgroundPointerOver}" />
                                    <Setter Target="BackgroundElement.Stroke"
                                            Value="{ThemeResource ButtonRevealBorderBrushPointerOver}" />
                                    <Setter Target="ContentPresenter.Foreground"
                                            Value="{ThemeResource ButtonForegroundPointerOver}" />
                                </VisualState.Setters>
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <VisualState.Setters>
                                    <Setter Target="RootGrid.(RevealBrush.State)"
                                            Value="Pressed" />
                                    <Setter Target="BackgroundElement.Fill"
                                            Value="{ThemeResource ButtonRevealBackgroundPressed}" />
                                    <Setter Target="BackgroundElement.Stroke"
                                            Value="{ThemeResource ButtonRevealBorderBrushPressed}" />
                                    <Setter Target="ContentPresenter.Foreground"
                                            Value="{ThemeResource ButtonForegroundPressed}" />
                                </VisualState.Setters>
                                <Storyboard>
                                    <PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <VisualState.Setters>
                                    <Setter Target="BackgroundElement.Fill"
                                            Value="{ThemeResource ButtonRevealBackgroundDisabled}" />
                                    <Setter Target="BackgroundElement.Stroke"
                                            Value="{ThemeResource ButtonRevealBorderBrushDisabled}" />
                                    <Setter Target="ContentPresenter.Foreground"
                                            Value="{ThemeResource ButtonForegroundDisabled}" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Ellipse Stroke="{TemplateBinding BorderBrush}"
                             StrokeThickness="2"
                             Fill="Transparent"
                             x:Name="BackgroundElement" />
                    <ContentPresenter x:Name="ContentPresenter"
                                      Content="{TemplateBinding Content}"
                                      ContentTransitions="{TemplateBinding ContentTransitions}"
                                      ContentTemplate="{TemplateBinding ContentTemplate}"
                                      Padding="{TemplateBinding Padding}"
                                      HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                      AutomationProperties.AccessibilityView="Raw" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这个样式实现了一个圆形的无边框按钮。看起来各种Reveal的Brush等资源都已高度封装好,不容易自定义。实际运行起来赏心悦目,这种效果,我很喜欢:

刚开始真的觉得这是程序员为了炫技而产生的效果,实际上配合Acrylic用起来整个不仅整个UI闪闪发光(很多人就是喜欢这个效果),而且提示可操作区域的解决方案中Reveal是目前我最满意的一个。像上面那个无边框按钮,它可以比幽灵按钮更进一步的简约,但鼠标接近时又可以清清楚楚提示哪些地方是可以操作的。

3. 注意事项

Reveal虽然很美好,用起来也很多讲究,重复一次以前提过的注意事项:

  • 只应该在可操作的元素上使用Reveal。
  • 不要在孤立的元素上使用Reveal。
  • 不要在大面积的元素上使用Reveal。
  • 静态元素(例如文字和背景)不应该使用Reveal。
  • 不应该让Reveal干扰重要的信息。

也就是说在List或一组按钮上使用才是正确用法。别一时兴起将SystemControlBackgroundAccentRevealBorderBrush之类的用在背景。

其它事项如Reveal没有生效及版本兼容性,可见之前的文章:如何使用Fluent Design System (下)

4. 结语

光照一直是设计师梦寐以求的元素,但不要因为可以用就去乱用,要适可而止(讲到我自己都觉得自己很婆婆妈妈了)。

5. 参考

Reveal highlight

6. 源码

Fluent Design System Sample

作者:dino.c