Extensions in UWP Community Toolkit - FrameworkElement Extensions
概述
UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkElement Extensions,本篇我们结合代码详细讲解 FrameworkElement Extensions 的实现。
FrameworkElement Extensions 为 FrameworkElement 提供了一种简单的绑定实际尺寸的方式,扩展利用 EnableActualSizeBinding 来指定是否允许实时绑定实际尺寸中的 ActualWidth 和 ActualHeight。 接下来看看官方示例的截图:

Doc: https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/extensions/frameworkelementextensions
Namespace: Microsoft.Toolkit.Uwp.UI.Extensions; Nuget: Microsoft.Toolkit.Uwp.UI;
开发过程
代码分析
FrameworkElement Extensions 的功能实现比较简单,在 FrameworkElementExtensions.cs 类中;先看一下类的结构:

我们看到,类中定义了三个依赖属性:
- EnableActualSizeBindingProperty - boolean,标志是否允许实际尺寸绑定;属性改变时触发 OnEnableActualSizeBindingtPropertyChanged;
- ActualHeightProperty - double,实际尺寸的高度; 默认值 double.NaN;
- ActualWidthProperty - double,实际尺寸的宽度;默认值 double.NaN;
而这三个依赖属性分别对应的 get 和 set 方法分别是:
- GetEnableActualSizeBinding(obj) 和 SetEnableActualSizeBinding(obj, value)
- GetActualHeight(obj) 和 SetActualHeight(obj, value)
- GetActualWidth(obj) 和 SetActualWidth(obj, value)
下面看一下实际绑定和 EnableActualSizeBinding 的处理代码:
在 OnEnableActualSizeBindingtPropertyChanged(sender, args) 方法处理中,可以看到当 EnableActualSizeBinding 变为 True 时,强制刷新一次实际尺寸,且开始响应 SizeChanged 事件,处理同样是刷新实际尺寸属性;而当 EnableActualSizeBinding 变为 False 时,去掉 SizeChanged 事件的监听;
这样的结果就是,当 EnableActualSizeBinding 变为 False 时,获取到的 ActualHeight 和 ActualWidrh 一直都是变为 False 时最后一个值,不管尺寸怎么改变都不会被更新和监听;
而通过扩展设置的绑定,和直接设置 ActualHeight 和 ActualWidth 的绑定的区别就是,直接设置的方式,对于 Width 和 Height 未指定的情况绑定无效,且不会更新,而扩展的方式可以获取初始尺寸且可以实时更新;
private static void OnEnableActualSizeBindingtPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
var baseElement = sender as FrameworkElement;
if (baseElement == null)
{
return;
}
if ((bool)args.NewValue)
{
// Size may have changed while this was disabled, so we force an updated once user enables it
UpdateActualSizeProperties(baseElement, null);
// Subscribe to event
baseElement.SizeChanged += UpdateActualSizeProperties;
}
else
{
// Unsubscribe from event
baseElement.SizeChanged -= UpdateActualSizeProperties;
}
}
在下面的 UpdateActualSizeProperties(sender, args) 方法中,可以看到绑定目标的 ActualHeight 和 ActualWidth 在改变时,会实时赋值,这样绑定的属性就能得到实时的更新。
private static void UpdateActualSizeProperties(object sender, RoutedEventArgs routedEventArgs)
{
var baseElement = sender as FrameworkElement;
if (baseElement == null)
{
return;
}
// Update only if needed
var currentHeight = GetActualHeight(baseElement);
if (currentHeight != baseElement.ActualHeight)
{
SetActualHeight(baseElement, baseElement.ActualHeight);
}
// Update only if needed
var currentWidth = GetActualWidth(baseElement);
if (currentWidth != baseElement.ActualWidth)
{
SetActualWidth(baseElement, baseElement.ActualWidth);
}
}
代码简单分析如上,大家在实际项目中可以对这个类进行扩展,比如把 Opacity,Color 等也作为可以实时绑定的值,实现方式和 ActualHeight ActualWidth 很类似,大家可以自行扩展,然后把扩展后的类提 PR 到 UWPCOmmunityToolkit Github 中。
调用示例
我们创建了三个 Rectangle,第一个是绑定目标,第二和第三个去绑定第一个的实际尺寸;可以看到因为第二个红色矩形使用 ActualHeight 和 ActualWidth 直接进行绑定,所以并没有绑定到正确的值;而第三个浅蓝色矩形的初始绑定值是正确的;而在第一个矩形的尺寸随着 GridSplitter 变化时,红色矩形没有任何变化,而浅蓝色矩形会跟随变化更新尺寸;这和我们预期的结果是一致的。
<StackPanel x:Name="RootGrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Padding="48">
<Grid Height="300">
<Grid.RowDefinitions>
<RowDefinition MinHeight="100" MaxHeight="300" />
<RowDefinition Height="11" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" MaxWidth="800" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0" extensions:FrameworkElementExtensions.EnableActualSizeBinding="True"
Fill="Blue" Stroke="Gray" x:Name="TargetObject" StrokeThickness="1"/>
<!--Column Grid Splitter-->
<controls:GridSplitter Width="11" Background="Gray" GripperCursor="Default" HorizontalAlignment="Left" Grid.Column="1"
ResizeDirection="Auto" ResizeBehavior="BasedOnAlignment" CursorBehavior="ChangeOnGripperHover" GripperForeground="White"/>
<!--Row Grid Splitter-->
<controls:GridSplitter Grid.Row="1" Background="Gray" Height="11" HorizontalAlignment="Stretch">
<controls:GridSplitter.Element>
<Grid>
<TextBlock HorizontalAlignment="Center" IsHitTestVisible="False" VerticalAlignment="Center" Text=""
Foreground="White" FontFamily="Segoe MDL2 Assets"/>
</Grid>
</controls:GridSplitter.Element>
</controls:GridSplitter>
</Grid>
<Rectangle Margin="12,12" HorizontalAlignment="Left"
Height="{Binding ElementName=TargetObject, Path=ActualHeight}"
Width="{Binding ElementName=TargetObject, Path=ActualWidth}"
Fill="Red" Stroke="Gray" StrokeThickness="1"/>
<Rectangle Margin="12,12" HorizontalAlignment="Left"
Height="{Binding ElementName=TargetObject, Path=(extensions:FrameworkElementExtensions.ActualHeight)}"
Width="{Binding ElementName=TargetObject, Path=(extensions:FrameworkElementExtensions.ActualWidth)}"
Fill="LightBlue" Stroke="Gray" StrokeThickness="1"/>
</StackPanel>


总结
到这里我们就把 UWP Community Toolkit Extensions 中的 FrameworkElement Extensions 的源代码实现过程和简单的调用示例讲解完成了,希望能对大家更好的理解和使用这个扩展有所帮助。欢迎大家多多交流,谢谢!
最后,再跟大家安利一下 UWPCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通过微博关注最新动态。
衷心感谢 UWPCommunityToolkit 的作者们杰出的工作,Thank you so much, UWPCommunityToolkit authors!!!
Extensions in UWP Community Toolkit - FrameworkElement Extensions的更多相关文章
- Extensions in UWP Community Toolkit - Visual Extensions
概述 UWP Community Toolkit Extensions 中有一个为可视元素提供的扩展 - VisualExtensions,本篇我们结合代码详细讲解 VisualExtensions ...
- 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 的功能都有哪些,再后面会针对每一 ...
随机推荐
- C语言与C++语言之间关系
很多时候我们对于C和C++的区别不是很清楚,以至于弄混的情况并不少见.那C语言和C++语言到底是怎么回事呢? 首先,我们来看下百度百科对语言和C++语言描述,相对而说也还算是比较权威的. C语言 C语 ...
- Problem : 1196 ( Lowest Bit )
第一次一次通过,逻辑太简单... #include<iostream> using namespace std; void main() { int n; while(cin>> ...
- Starting a Gradle Daemon, 5 busy and 1 incompatible and 1 stopped Daemons could not be reused, use --status for details FAILURE: Build failed with an exception. * What went wrong: Could not dispatch
执行gradle build出的问题,查看hs_err_pid11064.log日志文件发现,是电脑的RAM不足导致
- 为什么需要RPC,而不是简单的HTTP接口
转载自:http://www.oschina.net/question/271044_2155059?sort=default&p=1#answers 目前有很多Java的RPC框架,有基于J ...
- es6学习笔记--新数据结构Set,Map以及WeakSet,WeakMap
在javascript中,存储数据的方式大部分就是以数组或者对象形式存储的,es6出现了4种新集合Set,Map,WeakSet,WeakMap来存储数据,简化了编程. 集合--Set 类似于数组,但 ...
- 转:命令passwd报错因inode节点处理记录
命令passwd报错因inode节点处理记录 原文:http://blog.sina.com.cn/s/blog_506ed9e6010106kj.html 故障现象: 1.修改密码时报错 ...
- C语言第七次博客作业--一二维数组
一.PTA实验作业 题目1:找鞍点 1. 本题PTA提交列表 2. 设计思路 定义n,i,j,ii,jj,a[7][7],flag,max 输入n for i=0 to i=n for j=0 to ...
- Gauge----自动化测试工具
* Gauge是一个自动化测试工具,主要是通过.spec 文件指定执行的步骤,然后由Java代码去测试 安装: * 安装插件 Gauge--install-all *在IDEA中安装Gauge插件 基 ...
- 利用github协作开发步骤
项目使用IDEA开发,IDEA上可以加载很多的插件(而且下载很快),安装github插件,安装git 首先一个成员需要创建好代码库,这个代码库存放项目,所有的开发提交代码都是向这个库提交,在githu ...
- 【漏洞】PHPCMS_V9.6.0 前台注册GETSHELL
首先准备一台公网服务器,在上面新建一个一句话的txt文件.如下: 接着打开目标网站,点击注册,填写信息后点击提交,拦截该数据包. 将其中post提交的数据替换成我们的poc,poc如下: siteid ...