Extensions in UWP Community Toolkit - Visual Extensions
概述
UWP Community Toolkit Extensions 中有一个为可视元素提供的扩展 - VisualExtensions,本篇我们结合代码详细讲解 VisualExtensions 的实现。
VisualExtensions 为可视元素提供了一种简单的在 XAML 中修改通用属性的方法,这些通用属性包括 AnchorPoint,CenterPoint,Offset,Opacity,RotationAngle,RotationAngleInDegrees,RotationAxis,Scale,Size 和 NormalizedCenterPoint。 接下来看看官方示例的截图:

Doc: https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/extensions/visualextensions
Namespace: Microsoft.Toolkit.Uwp.UI.Extensions; Nuget: Microsoft.Toolkit.Uwp.UI;
开发过程
代码分析
VisualExtensions 的处理逻辑在 VisualExtensions.cs 类中,下面我们先来看看类结构:

首先看一下类中定义的附加属性:
- AnchorPoint - 获取或设置 UIElement 的 Visual.AnchorPoint 属性,string 类型;改变时触发 OnAnchorPointChanged 事件;
- CenterPoint - 获取或设置 UIElement 的 Visual.CenterPoint 属性,string 类型;改变时触发 OnCenterPointChanged 事件;
- Offset - 获取或设置 UIElement 的 Visual.Offset 属性,string 类型;改变时触发 OnOffsetChanged 事件;
- Opacity - 获取或设置 UIElement 的 Visual.Opacity 属性,double 类型;改变时触发 OnOpacityChanged 事件;
- RotationAngle - 获取或设置 UIElement 的 Visual.RotationAngle 属性,double 类型,单位是弧度;改变时触发 OnRotationAngleChanged 事件;
- RotationAngleInDegrees - 获取或设置 UIElement 的 Visual.RotationAngleInDegrees 属性,double 类型,单位是角度;改变时触发 OnRotationAngleInDegreesChanged 事件;
- RotationAxis - 获取或设置 UIElement 的 Visual.RotationAxis 属性,string 类型;改变时触发 OnRotationAxisChanged 事件;
- Scale - 获取或设置 UIElement 的 Visual.Scale 属性,string 类型;改变时触发 OnScaleChanged 事件;
- Size - 获取或设置 UIElement 的 Visual.Size 属性,string 类型;改变时触发 OnSizeChanged 事件;
- NormalizedCenterPoint - 获取或设置 UIElement 的 Visual.CenterPoint 属性在 0.0 - 1.0 之间标准化的值,string 类型;改变时触发 OnNormalizedCenterPointChanged 事件;
除去 OnNormalizedCenterPointChanged 事件,其他事件的处理逻辑都是简单的进行了 Set 方法处理,我们来看一下 OnNormalizedCenterPointChanged 的处理:
OnNormalizedCenterPointChanged 的主要处理逻辑在 SetupNormalizedCenterPoint(args, element):
解除 element 的 SizeChanged 事件绑定;把 normalizedValue 转为 Vector3 类型,然后设置 element VIsual 的 CenterPoint,根据 ActualSize 和 normalizedValue 的换算关系;最后重新绑定 element 的 SizeChanged 事件;
private static void SetupNormalizedCenterPoint(DependencyPropertyChangedEventArgs e, FrameworkElement element)
{
element.SizeChanged -= KeepCenteredElementSizeChanged;
if (e.NewValue is string normalizedValue)
{
var vectorValue = normalizedValue.ToVector3();
var visual = GetVisual(element);
visual.CenterPoint = );
element.SizeChanged += KeepCenteredElementSizeChanged;
}
}
来看一下 KeepCenteredElementSizeChanged 事件的处理逻辑,和 SetupNormalizedCenterPoint(args, element) 方法的处理基本相同,都是在使用 normalizedValue 设置 element Visual 的 CenterPoint;
private static void KeepCenteredElementSizeChanged(object sender, SizeChangedEventArgs e)
{
var element = sender as FrameworkElement;
var normalizedValue = GetNormalizedCenterPoint(element);
var vectorValue = normalizedValue.ToVector3();
var visual = GetVisual(element);
visual.CenterPoint = );
}
我们看到很多的属性都是 string 类型,而实际操作中需要用到各种类型的 Vector,要求 string 的格式为 "0,0", "0,0,0", "0,0,0,0" 这样的用逗号隔开的格式,类似 Margin 的格式,来看一下转换的方法:
因为 string 转换为 Vector2 Vector3 和 Vector4 的处理类似,我们以 ToVector2(str) 为例来解释一下:
- 处理前先做一些基本格式的检查,如长度过短,带有 <> 字符的情况;
- Split() 方法分割字符串,根据分割后的段数,如果为 1,则使用它创建 Vector2;如果为 2,则使用两个值创建 Vector2;
public static Vector2 ToVector2(this string str)
{
try
{
var strLength = str.Count();
)
{
throw new Exception();
}
] == ] == '>')
{
str = str.Substring(, strLength - );
}
string[] values = str.Split(',');
var count = values.Count();
Vector2 vector;
)
{
vector = ]));
}
)
{
vector = ]), ]));
}
else
{
throw new Exception();
}
return vector;
}
catch (Exception)
{
throw new FormatException($"Cannot convert {str} to Vector2. Use format \"float, float\"");
}
}
调用示例
我们给 Border 设置了 Visual Extensions,包括缩放,旋转,透明度等,可以看到运行图中和设置一致;
<Border Height="100"
Width="100"
Background="Purple"
extensions:VisualExtensions.CenterPoint="50,50,0"
extensions:VisualExtensions.Opacity="0.5"
extensions:VisualExtensions.RotationAngleInDegrees="80"
extensions:VisualExtensions.Scale="2, 0.5, 1"
extensions:VisualExtensions.NormalizedCenterPoint="0.5, 0.5, 0" />

总结
到这里我们就把 UWP Community Toolkit Extensions 中的 VisualExtensions 的源代码实现过程和简单的调用示例讲解完成了,希望能对大家更好的理解和使用这个扩展有所帮助。欢迎大家多多交流,谢谢!
最后,再跟大家安利一下 UWPCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通过微博关注最新动态。
衷心感谢 UWPCommunityToolkit 的作者们杰出的工作,Thank you so much, UWPCommunityToolkit authors!!!
Extensions in UWP Community Toolkit - Visual Extensions的更多相关文章
- Extensions in UWP Community Toolkit - FrameworkElement Extensions
概述 UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkElement Extensions,本篇我们结合 ...
- Extensions in UWP Community Toolkit - Overview
概述 UWP Community Toolkit 中有一个 Extensions 的集合,它们可以帮助开发者实现很多基础功能,省去自己造轮子的过程,本篇我们先来看一下 Extensions 的功能都 ...
- Extensions in UWP Community Toolkit - Mouse Cursor
概述 UWP Community Toolkit Extensions 中有一个为 Mouse 提供的扩展 - Mouse Cursor Extensions,本篇我们结合代码详细讲解 Mouse C ...
- Extensions in UWP Community Toolkit - SurfaceDialTextbox
概述 UWP Community Toolkit Extensions 中有一个为TextBox 提供的 SurfaceDial 扩展 - SurfaceDialTextbox,本篇我们结合代码详细讲 ...
- Extensions in UWP Community Toolkit - ViewExtensions
概述 UWP Community Toolkit Extensions 中有一个为 View 提供的扩展 - View Extensions,本篇我们结合代码详细讲解 View Extensions ...
- Extensions in UWP Community Toolkit - WebViewExtensions
概述 UWP Community Toolkit Extensions 中有一个为 WebView 提供的扩展 - WebViewExtensions,本篇我们结合代码详细讲解 WebView Ext ...
- Extensions in UWP Community Toolkit - ListViewExtensions
概述 UWP Community Toolkit Extensions 中有一个为 ListView 提供的扩展 - ListViewExtensions,本篇我们结合代码详细讲解 ListView ...
- New UWP Community Toolkit
概述 UWP Community Toolkit 是一个 UWP App 自定义控件.应用服务和帮助方法的集合,能够很大程度的简化和指引开发者的开发工作,相信广大 UWPer 并不陌生. 下面是截取自 ...
- Animations in UWP Community Toolkit - Overview
概述 UWP Community Toolkit 中有一个 Animations 的集合,它们可以帮助开发者实现很多的动画,本篇我们先来看一下 Animations 的功能都有哪些,再后面会针对每一 ...
随机推荐
- 笔记:Spring Boot 项目构建与解析
构建 Maven 项目 通过官方的 Spring Initializr 工具来产生基础项目,访问 http://start.spring.io/ ,如下图所示,该页面提供了以Maven构建Spring ...
- vuex2中使用mapMutations/mapActions报错解决方法 BabelLoaderError: SyntaxError: Unexpected token
在尝鲜vuex2时,发现vuex2增加了 mapGetters 和 mapActions 的方法,借助stage2的 Object Rest Operator 特性,可以写出下面代码:methods: ...
- Linux中SVN的备份与恢复
linux中SVN备份有三种方式 1.svnadmin dump 是官方推荐的备份方式,优点是比较灵活,可以全量备份也可以增量备份,并提供版本恢复机制. 缺点是版本数过大,增长到数万以上,那么dump ...
- Mysql 一次性备份导出/导入恢复所有数据库
有木有遇到过这种情况?电脑或者服务器需要重装系统?可是你电脑上存着n多个网站的数据库,怎么办?把数据库文件夹拷贝出来,重装系统之后再拷回去?如果你使用了InnoDB引擎,恐怕那样做会出麻烦的,一个一个 ...
- Python+reuqests自动化接口测试
1.最近自己在摸索Python+reuqests自动化接口测试,要实现某个功能,首先自己得有清晰的逻辑思路!这样效率才会很快! 思路--1.通过python读取Excel中的接口用例,2.通过pyth ...
- JavaScript(第十七天)【浏览器检测】
由于每个浏览器都具有自己独到的扩展,所以在开发阶段来判断浏览器是一个非常重要的步骤.虽然浏览器开发商在公共接口方面投入了很多精力,努力的去支持最常用的公共功能:但在现实中,浏览器之间的差异,以及不同浏 ...
- JavaScript(第十三天)【内置对象】
学习要点: 1.Global对象 2.Math对象 ECMA-262对内置对象的定义是:"由ECMAScript实现提供的.不依赖宿主环境的对象,这些对象在ECMAScript程序执行之前就 ...
- 软工实践项目需求分析(团队)修改版get√-黄紫仪
日常前言:随笔距离文档大体完成已经过去了2天+(因为中间插了一波结对作业),所以目测感受没有那时候清晰(那时候烦的想打人了都--)需求分析那边去百度找了模板.emmmm好多东西感觉听都没听说过QAQ, ...
- 第2次作业:软件分析之Steam
1. 作业内容 1.1 介绍产品相关信息 你选择的产品是? 我选择的分析的软件为STEAM 为什么选择该产品作为分析? 在上述列表中的产品,除了王者荣耀,其他几项都是平时我使用较为频繁的软件,所以最初 ...
- 安利给班里的大家一个chrome的GitHub插件-----gayhub
title: 一个好用的Github插件--gayhub date: 2017-09-20 15:41:36 tags: --- 别跑, 这真是正经插件. 效果, 一图流: 具体效果在项目地址很详细 ...