New UWP Community Toolkit - DropShadowPanel
概述
UWP Community Toolkit 中有一个为 Frmework Element 提供投影效果的控件 - DropShadowPanel,本篇我们结合代码详细讲解 DropShadowPanel 的实现。
DropShadowPanel 提供的阴影效果有很多应用场景,比如给文本提供阴影,可以让文本在背景变化时可以明显显示,比如地图上的标尺文本;应用在图形或图片时,可以设置阴影效果,另外它有很多参数可以调整,如阴影偏移,颜色,透明度和阴影模糊半径等,14393 开始支持,下面看看官方示例的截图:

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的更多相关文章
- New UWP Community Toolkit
概述 UWP Community Toolkit 是一个 UWP App 自定义控件.应用服务和帮助方法的集合,能够很大程度的简化和指引开发者的开发工作,相信广大 UWPer 并不陌生. 下面是截取自 ...
- New UWP Community Toolkit - XAML Brushes
概述 上一篇 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾.接下来会针对每个重要更新,结合 SDK 源代码和调用代码详细讲解. 本篇我们 ...
- New UWP Community Toolkit - Markdown
概述 前面 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 MarkdownTextBlock 和 MarkdownDoc ...
- New UWP Community Toolkit - Staggered panel
概述 前面 New UWP Community Toolkit 文章中,我们对 2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 Staggered panel,本篇我们结合代码详细讲解 St ...
- New UWP Community Toolkit - Carousel
概述 New UWP Community Toolkit V2.2.0 的版本发布日志中提到了 Carousel 的调整,本篇我们结合代码详细讲解 Carousel 的实现. Carousel 是 ...
- New UWP Community Toolkit - RadialProgressBar
概述 UWP Community Toolkit 中有一个圆形的进度条控件 - RadialProgressBar,本篇我们结合代码详细讲解 RadialProgressBar 的实现. Radi ...
- New UWP Community Toolkit - RadialGauge
概述 New UWP Community Toolkit V2.2.0 的版本发布日志中提到了 RadialGauge 的调整,本篇我们结合代码详细讲解 RadialGauge 的实现. Radi ...
- New UWP Community Toolkit - RangeSelector
概述 前面 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾,其中简单介绍了 RangeSelector,本篇我们结合代码详细讲解一下 Ra ...
- New UWP Community Toolkit - ImageEx
概述 UWP Community Toolkit 中有一个图片的扩展控件 - ImageEx,本篇我们结合代码详细讲解 ImageEx 的实现. ImageEx 是一个图片的扩展控件,包括 Ima ...
随机推荐
- CentOS7下安装MySQL的安装与配置(yum) (转)
原文链接:http://www.centoscn.com/mysql/2016/0626/7537.html 1.配置YUM源 在MySQL官网中下载YUM源rpm安装包:http://dev.mys ...
- 【learning】一种奇妙的网络流建模方式
吐槽 好吧这个是真的很妙qwq用来解方程组的网络流嗯不能更清真 正题 首先是大概描述 当一个方程组中所有的方程相加之后可以把所有的变量都消掉(也就是所有变量都出现一正一负可以抵消掉),我们会发现这个其 ...
- ORM Basic
ORM即object relational mapping 对象关系映射程序,可以在操作数据库的时候使用自有的语言而不必使用数据库的语言. 在python中,最强大的ORM框架就是SQLAlchemy ...
- mysql 数据库基本命令语句
mysql mariadb 客户端连接 mysql -uroot -p; 客户端退出exit 或 \q 显示所有数据库show databases;show schemas; 创建数据库create ...
- 什么是IPFS?(三)
前两篇介绍了IPFS的基本概念, 那么IPFS都可以用来做什么? 如果你认为仅仅是CDN, 永久的web? Are you kidding me ? IPFS可是要 --改变世界的... --变世界的 ...
- VMware 滴滴声解决
去除虚拟机tab时的滴滴声 # cat /etc/inputrc Set bell-style none 重启生效
- 如何在MD(d)和MT(d)工程间正确分配和释放动态内存
MD(d)和MT(d) MD(d)和MT(d)是windows下VC开发的两个编译选项,表示程序的运行时库编译选项. /MT是"multithread, static version&quo ...
- 笔记:Hibernate 数据库方言表
关系数据库 方言 DB2 org.hibernate.dialect.DB2Dialect DB2 AS/400 org.hibernate.dialect.DB2400Dialect DB2 OS/ ...
- spring-data-redis使用哨兵配置一主多从
redis自带的哨兵确实简化了高可用性的配置,使用起来也比较简单. 首先是spring-redis-sentinel.xml(文件名可以随意命名)配置文件: <?xml version=&quo ...
- 【Python】 压缩文件处理 zipfile & tarfile
[zipfile] 虽然叫zipfile,但是除了zip之外,rar,war,jar这些压缩(或者打包)文件格式也都可以处理. zipfile模块常用的一些操作和方法: is_zipfile(file ...