概述

UWP Community Toolkit  中有一个为 Frmework Element 提供投影效果的控件 - DropShadowPanel,本篇我们结合代码详细讲解  DropShadowPanel 的实现。

DropShadowPanel 提供的阴影效果有很多应用场景,比如给文本提供阴影,可以让文本在背景变化时可以明显显示,比如地图上的标尺文本;应用在图形或图片时,可以设置阴影效果,另外它有很多参数可以调整,如阴影偏移,颜色,透明度和阴影模糊半径等,14393 开始支持,下面看看官方示例的截图:

Source: https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Controls/DropShadowPanel

Doc:https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/controls/dropshadowpanel

Namespace: Microsoft.Toolkit.Uwp.UI.Controls; Nuget: Microsoft.Toolkit.Uwp.UI.Controls;

开发过程

代码分析

我们先来看看 DropShadowPanel 控件的类构成:

  • DropShadowPanel.Properties.cs - DropShadowPanel 控件部分类的依赖属性类
  • DropShadowPanel.cs - DropShadowPanel 控件部分类的定义和处理方法
  • DropShadowPanel.xaml - DropShadowPanel 控件的样式文件

1. DropShadowPanel.Properties.cs

DropShadowPanel 控件部分类的依赖属性类,定义了以下依赖属性:

  • Color - drop shadow 的颜色,变化时会触发 OnColorChanged(d, e)
  • BlurRadius - drop shadow 的模糊半径,变化时会触发 OnBlurRadiusChanged(d, e)
  • OffsetX - drop shadow 的 x 轴方向偏移,变化时触发 OnOffsetXChanged(d, e)
  • OffsetY - drop shadow 的 y 轴方向偏移,变化时触发 OnOffsetYChanged(d, e)
  • OffsetZ - drop shadow 的 z 轴方向偏移,变化时触发 OnOffsetZChanged(d, e)
  • ShadowOpacity - drop shadow 的阴影透明度,变化时触发 OnShadowOpacityChanged(d, e)

2. DropShadowPanel.cs

DropShadowPanel 控件的定义和处理逻辑,类继承自 ContentControl;先来看看构造方法:

确定系统版本支持满足条件后,创建一个 Compositor 和 dropShadow,创建 shadowVisual,并用 dropShadow 给它赋值;

public DropShadowPanel()
{
    this.DefaultStyleKey = typeof(DropShadowPanel);

    if (IsSupported)
    {
        Compositor compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

        _shadowVisual = compositor.CreateSpriteVisual();

        _dropShadow = compositor.CreateDropShadow();
        _shadowVisual.Shadow = _dropShadow;
    }
}

接着来看一下上面 DropShadowPanel.Properties.cs 中属性的变化触发事件,实际的处理方法都在 DropShadowPanel.cs 类中,处理过程就是把 newValue 赋值给 dropShadow;

而在 OnSizeChanged(s, e) 事件触发时,以及初始化时,主要处理逻辑是 UpdateShadowSize() 方法:

方法处理中,获取需要设置投影的 Content,得到实际显示宽度和高度,赋值给 shadowVisual;作为 dropShadow 的显示宿主;

private void UpdateShadowSize()
{
    if (_shadowVisual != null)
    {
        Vector2 newSize = , );
        if (Content is FrameworkElement contentFE)
        {
            newSize = new Vector2((float)contentFE.ActualWidth, (float)contentFE.ActualHeight);
        }

        _shadowVisual.Size = newSize;
    }
}

更一个主要的处理方法是 UpdateShadowMask(),负责更新投影的 mask:

根据需要设置投影的 Content 类型,Image,Shape,TextBlock 或 ImageExBase,使用 GetAlphaMask() 来得到 alphaMask,赋值给 dropShadow 的 mask 属性,作为投影效果的显示效果;配合上面的 UpdateShadowSize() 方法,以及 Opacity,Offset 等属性,正确显示投影效果;

private void UpdateShadowMask()
{
    if (!IsSupported)
    {
        return;
    }

    if (Content != null)
    {
        CompositionBrush mask = null;

        if (Content is Image)
        {
            mask = ((Image)Content).GetAlphaMask();
        }
        else if (Content is Shape)
        {
            mask = ((Shape)Content).GetAlphaMask();
        }
        else if (Content is TextBlock)
        {
            mask = ((TextBlock)Content).GetAlphaMask();
        }
        else if (Content is ImageExBase imageExBase)
        {
            imageExBase.ImageExInitialized += ImageExInitialized;

            if (imageExBase.IsInitialized)
            {
                imageExBase.ImageExInitialized -= ImageExInitialized;

                mask = ((ImageExBase)Content).GetAlphaMask();
            }
        }

        _dropShadow.Mask = mask;
    }
    else
    {
        _dropShadow.Mask = null;
    }
}

3. DropShadowPanel.xaml

DropShadowPanel 控件的样式文件,我们来看 Template 部分:投影效果的实现,是使用一个 Border 放置在实际内容控件的后面,通过 Border 中对内容的显示和位置调整来实现投影。

<Style TargetType="controls:DropShadowPanel">
    <Setter Property="IsTabStop"
        Value="False" />
    <Setter Property="HorizontalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:DropShadowPanel">
                <Grid Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                    VerticalAlignment="{TemplateBinding VerticalAlignment}">
                    <Border x:Name="ShadowElement"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

调用示例

下面的示例中,我们定义了两个相同的 TextBlock,其中一个应用了 DropShadow,一个未应用,可以看出,应用了 DropShadow 的一个,文本明显会有模糊的黑色阴影;

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel Orientation="Vertical" VerticalAlignment="Center">
<controls:DropShadowPanel BlurRadius="10" ShadowOpacity="0.8"
                                OffsetX="0" OffsetY="0" Color="Black"
                                VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBlock FontSize="20"  TextWrapping="Wrap">
        The DropShadowPanel Control allows the creation of a drop shadow effect for any Xaml FrameworkElement in the markup.
        You can control the following property of the drop shadow effect : Offset, Color, Opactity and Blur Radius.
        NOTE: Windows Anniversary Update (10.0.14393.0) is needed to support correctly this effect.
    </TextBlock>
    </controls:DropShadowPanel>
        <TextBlock TextWrapping="Wrap" FontSize="20" Margin="0,10,0,0">
        The DropShadowPanel Control allows the creation of a drop shadow effect for any Xaml FrameworkElement in the markup.
        You can control the following property of the drop shadow effect : Offset, Color, Opactity and Blur Radius.
        NOTE: Windows Anniversary Update (10.0.14393.0) is needed to support correctly this effect.
        </TextBlock>
    </StackPanel>
</Grid>

总结

到这里我们就把 UWP Community Toolkit 中的 DropShadowPanel 控件的源代码实现过程和简单的调用示例讲解完成了,希望能对大家更好的理解和使用这个控件有所帮助。欢迎大家多多交流,谢谢!

最后,再跟大家安利一下 UWPCommunityToolkit 的官方微博:https://weibo.com/u/6506046490大家可以通过微博关注最新动态。

衷心感谢 UWPCommunityToolkit 的作者们杰出的工作,Thank you so much, UWPCommunityToolkit authors!!!

New UWP Community Toolkit - DropShadowPanel的更多相关文章

  1. New UWP Community Toolkit

    概述 UWP Community Toolkit 是一个 UWP App 自定义控件.应用服务和帮助方法的集合,能够很大程度的简化和指引开发者的开发工作,相信广大 UWPer 并不陌生. 下面是截取自 ...

  2. New UWP Community Toolkit - XAML Brushes

    概述 上一篇 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾.接下来会针对每个重要更新,结合 SDK 源代码和调用代码详细讲解. 本篇我们 ...

  3. New UWP Community Toolkit - Markdown

    概述 前面 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 MarkdownTextBlock 和 MarkdownDoc ...

  4. New UWP Community Toolkit - Staggered panel

    概述 前面 New UWP Community Toolkit 文章中,我们对 2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 Staggered panel,本篇我们结合代码详细讲解  St ...

  5. New UWP Community Toolkit - Carousel

    概述 New UWP Community Toolkit  V2.2.0 的版本发布日志中提到了 Carousel 的调整,本篇我们结合代码详细讲解  Carousel 的实现. Carousel 是 ...

  6. New UWP Community Toolkit - RadialProgressBar

    概述 UWP Community Toolkit  中有一个圆形的进度条控件 - RadialProgressBar,本篇我们结合代码详细讲解  RadialProgressBar 的实现. Radi ...

  7. New UWP Community Toolkit - RadialGauge

    概述 New UWP Community Toolkit  V2.2.0 的版本发布日志中提到了 RadialGauge 的调整,本篇我们结合代码详细讲解  RadialGauge 的实现. Radi ...

  8. New UWP Community Toolkit - RangeSelector

    概述 前面 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 RangeSelector,本篇我们结合代码详细讲解一下 Ra ...

  9. New UWP Community Toolkit - ImageEx

    概述 UWP Community Toolkit  中有一个图片的扩展控件 - ImageEx,本篇我们结合代码详细讲解  ImageEx 的实现. ImageEx 是一个图片的扩展控件,包括 Ima ...

随机推荐

  1. 微信小程序之换肤的功能

    pc或者移动端实现换肤功能还是比较简单的,大致就是需要换肤的css,还有正常的css:把当前皮肤类型存入本地:然后通过js读取并判断当前应该加载哪套css. 由于微信小程序没有操作wxss的api,所 ...

  2. 基于Redis的简单分布式锁的原理

    参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的 ...

  3. 初探WebSocket

    初探WebSocket node websocket socket.io 我们平常开发的大部分web页面都是主动'拉'的形式,如果需要更新页面内容,则需要"刷新"一个,但Slack ...

  4. Scala编程快速入门系列(一)

    目    录 一.Scala概述 二.Scala数据类型 三.Scala函数 四.Scala集合 五.Scala伴生对象 六.Scala trait 七.Actor 八.隐式转换与隐式参数 九.Sca ...

  5. 与JavaWeb有关的故事(web请求与Java I/O)

    作为一名后端屌丝程序员,对算法.并发.性能乐此不疲.但是,随着年龄和阅历的增加,显然叶落而不知秋的心态是不太能混了.尤其是,某T面试官在明知我是后端,且明确表示对HTTP协议不太熟的情况下,强行让我解 ...

  6. jQuary学习の一の初期准备

    jQuery 的功能概括: 1.html 的元素选取 2.html的元素操作 3.html dom遍历和修改 4.js特效和动画效果 5.css操作 6.html事件操作 7.ajax异步请求方式 通 ...

  7. linux学习之路--(四)文件,目录管理

    1.mkdir:创建空目录 -p: -v:verbose mkdir -pv /mnt/test/x/m  /mnt/test/y mkdir -pv /mnt/test/{x/m,y} 命令行展开: ...

  8. USB协议基础知识笔记

    usb协议 功能层: 控制传输.中断传输.块传输(批量传输).同步传输 设备层:管理USB设备.分配地址.读取设备描述符 总线接口层:采用NRZI编码-反向非归零编码(0将前一个电平翻转,1不翻转) ...

  9. Mac下使用终端连接远程使用ssh协议的git服务器

    最近换了台新电脑, MacBook pro,拿到新电脑之后小小心喜了一下(终于解脱windows的束缚拥抱mac啦), 然后就开始苦逼的安装各种开发环境了. 之前在windows上使用tortoise ...

  10. [POJ 3635] Full Tank?

    题目 Description 已知每个点的加油站的油价单价(即点权),每条路的长度(边权). 有q个询问,每个询问包括起点s.终点e和油箱容量c. 问从起点走到终点的最小花费.如果不可达输出impos ...