概述

UWP Community Toolkit Extensions 中有一个为可视元素提供的扩展 - VisualExtensions,本篇我们结合代码详细讲解 VisualExtensions 的实现。

VisualExtensions 为可视元素提供了一种简单的在 XAML 中修改通用属性的方法,这些通用属性包括 AnchorPoint,CenterPoint,Offset,Opacity,RotationAngle,RotationAngleInDegrees,RotationAxis,Scale,Size 和 NormalizedCenterPoint。  接下来看看官方示例的截图:

Source: https://github.com/Microsoft/UWPCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI/Extensions/Visual/VisualExtensions.cs

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的更多相关文章

  1. Extensions in UWP Community Toolkit - FrameworkElement Extensions

    概述 UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkElement Extensions,本篇我们结合 ...

  2. Extensions in UWP Community Toolkit - Overview

    概述 UWP Community Toolkit  中有一个 Extensions 的集合,它们可以帮助开发者实现很多基础功能,省去自己造轮子的过程,本篇我们先来看一下 Extensions 的功能都 ...

  3. Extensions in UWP Community Toolkit - Mouse Cursor

    概述 UWP Community Toolkit Extensions 中有一个为 Mouse 提供的扩展 - Mouse Cursor Extensions,本篇我们结合代码详细讲解 Mouse C ...

  4. Extensions in UWP Community Toolkit - SurfaceDialTextbox

    概述 UWP Community Toolkit Extensions 中有一个为TextBox 提供的 SurfaceDial 扩展 - SurfaceDialTextbox,本篇我们结合代码详细讲 ...

  5. Extensions in UWP Community Toolkit - ViewExtensions

    概述 UWP Community Toolkit Extensions 中有一个为 View 提供的扩展 - View Extensions,本篇我们结合代码详细讲解 View Extensions  ...

  6. Extensions in UWP Community Toolkit - WebViewExtensions

    概述 UWP Community Toolkit Extensions 中有一个为 WebView 提供的扩展 - WebViewExtensions,本篇我们结合代码详细讲解 WebView Ext ...

  7. Extensions in UWP Community Toolkit - ListViewExtensions

    概述 UWP Community Toolkit Extensions 中有一个为 ListView 提供的扩展 - ListViewExtensions,本篇我们结合代码详细讲解 ListView  ...

  8. New UWP Community Toolkit

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

  9. Animations in UWP Community Toolkit - Overview

    概述 UWP Community Toolkit  中有一个 Animations 的集合,它们可以帮助开发者实现很多的动画,本篇我们先来看一下 Animations 的功能都有哪些,再后面会针对每一 ...

随机推荐

  1. Ubuntu 14.04下Hadoop2.4.1集群安装配置教程

    一.环境 系统: Ubuntu 14.04 64bit Hadoop版本: hadoop 2.4.1 (stable) JDK版本: OpenJDK 7 台作为Master,另3台作为Slave. 所 ...

  2. MYSQL数据库学习十三 使用MySQL常用函数

    13.1 字符串函数 对于针对字符串位置的操作,第一个位置被标记为1. 函数 功能 CONCAT(str1,str2...strn) 连接字符串str1.str2....strn INSERT(str ...

  3. Linux下mysql的常用操作

    Linux下mysql的常用操作: 显示数据库 show databases; 选择数据库 use 数据库名; 显示数据库中的表 show tables; 显示数据表的结构 describe 表名; ...

  4. Know your weapons Ⅱ

    本次内容主要讲述使用UWP相关技术可以实现的软件上的一些功能,这里以Netease-Cloud Music(下称Cloud Music)为例讲述,这款音乐软件我个人一直在用,毕竟人们生活离不开音乐,说 ...

  5. Spring MVC核心技术

    目录 异常处理 类型转换器 数据验证 文件上传与下载 拦截器 异常处理 Spring MVC中, 系统的DAO, Service, Controller层出现异常, 均通过throw Exceptio ...

  6. Entity Framework——并发策略

    使用EF框架遇到并发时,一般采取乐观并发控制. 1支持并发检验 为支持并发检验,需要对实体进行额外的设置.默认情况下是不支持并发检验的.有以下两种方式: 方式名称 说明 时间戳注解/行版本 使用Tim ...

  7. java并发包——阻塞队列BlockingQueue及源码分析

    一.摘要 BlockingQueue通常用于一个线程在生产对象,而另外一个线程在消费这些对象的场景,例如在线程池中,当运行的线程数目大于核心的线程数目时候,经常就会把新来的线程对象放到Blocking ...

  8. 分区表SQL调优/优化(Tuning)时容易“被欺骗”的场景之一

    近几天没有用户找到,除了看看书,就是上网浏览点东西,好不惬意.可惜好景不长,正在享受悠闲惬意的日子时,一个用户的工作人员QQ找到我,说他们在统计一些数据,但一个SQL特别慢,或者说就从来没出过数据,我 ...

  9. sqlplus 的安装和配置

    sqlplus :  oracle公司提供用户操作oracle数据库的工具. 安装所需的包:  1.oracle 客户端    2.sqlplus工具 官方下载地址  http://www.oracl ...

  10. %f使用时的注意事项

    1不是所有定义都用int,使用浮点函数需要把int改成float才能正常工作 2保留一位小数时要打入%0.1f,保留两位小数时要打入%0.2f,而不是%0.01f