当前位置:网站首页>WPF 实现内阴影
WPF 实现内阴影
2022-08-11 11:32:00 【yanjinhua】
前言
本文经原作者授权以原创方式二次分享,欢迎转载、分享。
原文作者:dino.c
原文链接:https://www.cnblogs.com/dino623/p/inner-shadows-in-wpf.html
在
WPF中,我们通常用DropShadow做阴影效果,但都是做外阴影。内阴影(Inner Shadow)的话其实也不是不可以,就是有些曲折。这篇文章介绍几种做内引用的做法。文章涉及到以下概念;
UIElement.ClipToBounds 属性 (System.Windows)
UIElement.Clip 属性 (System.Windows)
VisualBrush 类 (System.Windows.Media)
1)ClipToBounds
<Border>
<Border.Clip>
<RectangleGeometry Rect="0,0,100,100" />
</Border.Clip>
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Border.Effect>
<ContentControl HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Clip " />
</Border>
上面是一个普通的加上 DropShadowEffect 的 Border。要做内部阴影的话就只是将外部阴影裁剪掉,在 Border 上简单地加上 ClipToBounds="True" 就可以实现这个效果;

ClipToBounds 属性用于指示是否剪切此元素的内容(或来自此元素的子元素的内容)使其适合包含元素的大小。
但如果 Border 有圆角(最近微软向圆角势力屈服了,Windows 11 到处都是圆角)的话,那这个方案就有问题了,因为它不能裁剪圆角;

3)Clip
为了可以裁剪圆角内容,还是老老实实用 Clip 来裁剪,不过这就需要自己计算尺寸及圆角半径;
<Border>
<Border.Clip>
<RectangleGeometry RadiusX="8"
RadiusY="8"
Rect="0,0,100,100" />
</Border.Clip>
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Border.Effect>
<ContentControl HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Clip " />
</Border>
这个方案的坏处很明显,因为要写死尺寸,真的要用这方案的话最好封装一下在 SizeChanged事件中重新计算裁剪区域;
4)OpacityMask
<Grid Width="100"
Height="100"
Margin="10">
<Rectangle x:Name="Rectangle2"
Fill="White"
RadiusX="8"
RadiusY="8" />
<Border Margin="0">
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Border.Effect>
<ContentControl HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="OpacityMask" />
</Border>
<Grid.OpacityMask>
<VisualBrush Stretch="None" Visual="{Binding ElementName=Rectangle2}" />
</Grid.OpacityMask>
</Grid>
这个方案用另一个元素的 VisualBrush 来做 OpacityMask,胜在够灵活,就是 XAML 要写多一些。
5)更粗的内阴影
上面这些 Border 都应用了这个样式;
<Style TargetType="Border">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="Margin" Value="10" />
<Setter Property="BorderBrush" Value="SkyBlue" />
<Setter Property="BorderThickness" Value="1" />
</Style>
理所当然的,它们制造出来的阴影都是以这个1像素的边框为基础,如果需要更大更粗的内阴影,可以使用一个负数的 Margin 配合同样粗细的 BorderThickness 实现。以 OpacityMask 的方案为例,用下面的代码可以做个又粗又大的内阴影;
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
ShadowElement.Margin = new Thickness(-e.NewValue);
ShadowElement.BorderThickness = new Thickness(e.NewValue);
(ShadowElement.Effect as DropShadowEffect).BlurRadius = e.NewValue * 2;
}

边栏推荐
猜你喜欢
随机推荐
Summary of darknet structures
关于数据权限的设计
挑战52天背完小猪佩奇(第02天)
TiSpark 原理之下推丨TiDB 工具分享
【毕业设计】老人心率脉搏血压体征监测手表 - stm32 单片机 嵌入式 物联网
Flutter经验整理
资本市场做好为工业互联网“买单”的准备了吗?
Jmeter性能测试
scala 高级
阿里云 Hologres助力好未来网校实时数仓降本增效
『独家』互联网 BAT 大厂 Android高级工程师面试题:174道题目让你做到面试无忧
2.MySQL ---- 修改数据库的字符集(日常小技巧)
Common operations in Typora tables
同城是美团电商的解法吗?
什么是架构基本概念和架构本质
go语言学习:并发编程(定时器/select/并发安全锁)
学习笔记【nlp中的sample和beam_search】
Flutter 教程之 Kotlin 多平台与 Flutter,为您的应用选择哪一个
Flutter 教程之 在 Flutter 中生成 JSON 模型,在 Flutter GetX 中过滤列表和延迟搜索
The ceiling-level microservice boss summed up this 451-page note to tell you that microservices should be learned this way



![[10点公开课]:AV1编码器的优化及其在流媒体和实时通讯中的应用](/img/86/a6cd309cd66eb37159fcb8ae3338b1.png)





