前言

看了好久官方的Windows UI Dev Labs示例好久才有点心得,真是头大。(其实是英语幼儿园水平(⊙﹏⊙)b)

真的网上关于这个API的资料可以说几乎没有。

正文

  首先用这东西的添加WIN2D。其实这个API实现阴影的步骤和正儿八经使用WIN2D差不多,但是我自己感觉比用WIN2D简单,毕竟微软大法做了封装就是要简单粗暴。差不多的实现都是自定义控件,官方的也是。

  其实就这个API做阴影就是用了2个图层来实现的。

  上图是CorelDRAW里的阴影效果图,明显看出是2个图层的堆叠。

  so,用这个API来实现太简单了,只用控制下面几个属性就能完美实现了外加一个动画就搞定了。

前台XAML

  1. <Grid Background="White">
  2. <Canvas x:Name="ShadowHost"
  3. Margin=""/>
  4. <Image x:Name="CircleImage"
  5. Margin=""
  6. Source="Assets/3275.jpg" Canvas.ZIndex=""/>
  7. </Grid>

后退CS

  首先在构造函数中定义一个方法来实现阴影。

  1. public sealed partial class MainPage : Page
  2. {
  3. public MainPage()
  4. {
  5. this.InitializeComponent();
  6. DropShadow(ShadowHost, CircleImage);
  7. }
  8.  
  9. private void DropShadow(UIElement shadowHost, Image shadowTarget)
  10. {
  11. Visual hostVisual = ElementCompositionPreview.GetElementVisual(shadowHost);
  12. Compositor compositor = hostVisual.Compositor;
  13.  
  14. // 创建阴影
  15. var dropShadow = compositor.CreateDropShadow();
  16. dropShadow.Color = Color.FromArgb(, , , );
  17. dropShadow.BlurRadius = 20.0f;
  18. dropShadow.Offset = new Vector3(2.5f, 2.5f, 0.0f);
  19. dropShadow.Opacity = 50.0f;
  20. // 拿到要做阴影的元素的外形用来做阴影的形状,比如我这里是矩形,那这个阴影就是矩形阴影,是圆是扁就看这里了
  21. dropShadow.Mask = shadowTarget.GetAlphaMask();
  22.  
  23. // 创建一个视觉树来hold住阴影
  24. var shadowVisual = compositor.CreateSpriteVisual();
  25. shadowVisual.Shadow = dropShadow;
  26.  
  27. // 把自定义的阴影添加到视觉树
  28. ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);
  29.  
  30. // 用一个动画来保证阴影和视觉树同步,就是你变我也变,大家一起变。
  31. var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
  32. bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);
  33.  
  34. shadowVisual.StartAnimation("Size", bindSizeAnimation);
  35. }
  36. }

  TIPS:GetAlphaMask()这个方法只有3个控件实现了:Image、Shape、TextBlock当时我看到就懵逼了,那么多控件怎么才实现这3个?,最后想想貌似绝大多数控件最外层都是Shape里的各种形状。

是否是发现了,既然阴影是用2个图层来实现的,那么这是不是共同点,有了共同点是不是就有了用户控件和模版控件的表演上了?

用户控件和模版控件我以前一直都懵逼的。最近看了好多别人的代码,最近突然就悟了,真悟了。吗蛋这和平时写的窗口程序有毛线区别- -,以前看的各种相关自定义控件的文章都是很高大上,各种牛逼,然并卵看不懂。

  拿上面的阴影来说,要把他做成类库,在类库里定义一个用户控件,然后把上面的改造下就可以哪里需要哪里搬了。

  自定义控件最让我等小白懵逼的就是依赖属性,看到那一坨就怕- -。

  下面用阴影颜色来看看一个完整的依赖属性的定义。

1.

  1. /// <summary>
  2. /// 设置阴影的颜色
  3. /// 默认值为黑色
  4. /// </summary>
  5. public Color Color
  6. {
  7. get { return (Color)GetValue(ColorProperty); }
  8. set { SetValue(ColorProperty, value); }
  9. }
  10.  
  11. public static readonly DependencyProperty ColorProperty =
  12. DependencyProperty.Register(nameof(Color), typeof(Color), typeof(CompositionShadow), new PropertyMetadata(Colors.Black,OnBorederColorChaged));

2.

  1. private static void OnBorederColorChaged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  2. {
  3. ((CompositionShadow)d).OnBorederColorChaged((Color)e.NewValue);
  4. }

3.

  1. private void OnBorederColorChaged(Color newValue)
  2. {
  3. _dropShadow.Color = newValue;
  4. }

看看2、3步是不是劫完财、再劫个色的套路,反正我理解能力有限,听到回调根本无法第一时间想到具体的东西,完全没概念。

现在看到回调第一个想法就是畜生,劫财还劫色。

  现在要做的就是把上面的属性全撸成依赖属性。然后定义更新方法来更新SIZE、Mask、OFFset的变化就可以了。

  1. private void UpdateShadowMask()
  2. {
  3. if (_castingElement != null)
  4. {
  5. CompositionBrush mask = null;
  6. if (_castingElement is Image)
  7. {
  8. mask = ((Image)_castingElement).GetAlphaMask();
  9. }
  10. else if (_castingElement is Shape)
  11. {
  12. mask = ((Shape)_castingElement).GetAlphaMask();
  13. }
  14. else if (_castingElement is TextBlock)
  15. {
  16. mask = ((TextBlock)_castingElement).GetAlphaMask();
  17. }
  18.  
  19. _dropShadow.Mask = mask;
  20. }
  21. else
  22. {
  23. _dropShadow.Mask = null;
  24. }
  25. }
  26.  
  27. private void UpdateShadowOffset(float x, float y, float z)
  28. {
  29. _dropShadow.Offset = new Vector3(x, y, z);
  30. }
  31.  
  32. private void UpdateShadowSize()
  33. {
  34. Vector2 newSize = new Vector2(, );
  35. if (_castingElement != null)
  36. {
  37. newSize = new Vector2((float)_castingElement.ActualWidth, (float)_castingElement.ActualHeight);
  38. }
  39.  
  40. _shadowVisual.Size = newSize;
  41. }
  42.  
  43. private FrameworkElement _castingElement;
  44. private readonly DropShadow _dropShadow;
  45. private readonly SpriteVisual _shadowVisual;

总结

  其实上面的代码在微软爸爸的各种示例代码中都有。大家搜索下Windows UI dev labs这个GitHub上。全是Composition API的使用例子

[UWP小白日记-12]使用新的Composition API来实现控件的阴影的更多相关文章

  1. [UWP小白日记-9]页面跳转过度动画(二)

    又打算动手写了 [UWP小白日记-6]页面跳转过度动画 上次写的,这次随着学习的进度使用新的玩法. 最近在搞GIT的学习,结果把好好的项目玩坏,都不知道当时是怎么想的拿在写的APP来玩GIT,害我重写 ...

  2. win10 UWP 等级控件Building a UWP Rating Control using XAML and the Composition API | XAML Brewer, by Diederik Krols

    原文:Building a UWP Rating Control using XAML and the Composition API | XAML Brewer, by Diederik Krols ...

  3. 小白日记12:kali渗透测试之服务扫描(二)-SMB扫描

    SMB扫描 Server Message Block 协议.与其他标准的TCP/IP协议不同,SMB协议是一种复杂的协议,因为随着Windows计算机的开发,越来越多的功能被加入到协议中去了,很难区分 ...

  4. [UWP小白日记-8]一些零碎的东西

    设置启动窗口大小 直接上代码了没什么好解释的了,既然能设置最小,那铁定就能设置最大 public MainPage() { //设定窗口启动显示大小 ApplicationView.Preferred ...

  5. [UWP小白日记-6]页面跳转过度动画

    前言 在学习中发现页面导航默认是没有过度动画的,直接就导航过去太粗暴了( ̄へ ̄),于是打算上动画结果不言而喻自己进了坑完全不懂动画,然后就是各种疯狂(´・_・`)的搜索资料看了后终于有点头绪. 再后来 ...

  6. ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能

    在最新发布的ActiveReports 9报表控件中添加了多项新功能,以帮助你在更短的时间里创建外观绚丽.功能强大的报表系统,本文将重点介绍新增文档目录控件(TOC),通过拖拽操作便可添加报表目录. ...

  7. ActiveReports 报表控件V12新特性 -- 文本框和标签控件的浓缩

    ActiveReports是一款专注于 .NET 平台的报表控件,全面满足 HTML5 / WinForms / ASP.NET / ASP.NET MVC / WPF 等平台下报表设计和开发工作需求 ...

  8. 12款优秀的 JavaScript 日历和时间选择控件

    这些插件能够帮助  Web 开发人员更快速的实现各种精美的日历和时间选择效果. 1. The Coolest Calendar 界面非常漂亮的一款日期选择插件,有详细的使用文档,最新版本 1.5. 点 ...

  9. [UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)

    前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Enti ...

随机推荐

  1. 处理动态SQL语句的参数

    原文:处理动态SQL语句的参数 经常对SQL进行开发,写动态的SQL语句,是少之不了的,但是在使用动态语句中,常是因为有动态的参数的出现.参考下面代码示例: 正因为有了标记1的动态条件代码,而让SQL ...

  2. bitnami redmine安装、配置、备份、恢复(这篇文章靠谱)

    bitnami redmine安装.配置.备份.恢复 2012-12-17 12:33 2596人阅读 评论(0) 收藏 举报 1. 安装时语言选择英文,不可以选择中文,否则不能正常运行,可以在账户里 ...

  3. MVC应用程序实现文件库(FlexPaper)

    MVC应用程序实现文件库(FlexPaper) 很久之前Insus.NET在实现了<FlexPaper实现文档在线浏览>http://www.cnblogs.com/insus/archi ...

  4. C程序设计语言(第二版)习题:第一章

    第一章虽然感觉不像是个习题.但是我还是认真去做,去想,仅此而已! 练习 1-1 Run the "hello, world" program on your system. Exp ...

  5. 并行Linq(一)

    .Net 并行计算 ----并行Linq(一) 本文是.Net 并行计算 的第三篇 欢迎大家拍砖,阅读本文需要有LINQ基础,因为并行LINQ (PLinq) 其实是LINQ To Object 的并 ...

  6. C语言基础复习总结

    C语言基础复习总结 大一学的C++,不过后来一直没用,大多还给老师了,最近看传智李明杰老师的ios课程的C语言入门部分,用了一周,每晚上看大概两小时左右,效果真是顶一学期的课,也许是因为有开发经验吧, ...

  7. CLR的组成和运转

    CLR的组成和运转 clr基本 CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”.(例如:c#,c++/cli,vb,f#,ironpython,iron ...

  8. ie8下下拉菜单文字为空

    <html> <head> <title></title> <script type="text/javascript"> ...

  9. css兼容性问题的整理

    css兼容性问题的整理 1.文字本身的大小不兼容.同样是font-size:14px的宋体文字,在不同浏览器下占的空间是不一样的,ie下实际占高16px,下留白3px,ff下实际占高17px,上留白1 ...

  10. synchronized和volatile的使用

    synchronized和volatile的使用 一步一步掌握线程机制(三)---synchronized和volatile的使用 现在开始进入线程编程中最重要的话题---数据同步,它是线程编程的核心 ...