UWP基础教程 - XAML依赖属性和附加属性
前面两章介绍了XAML的命名空间、元素和属性的概念,从本篇开始接下来会介绍XAML的高级特性,本篇主要会介绍两个概念:
- 依赖属性(Dependency Properties)
- 附加属性(Attached Properties)
依赖属性
英文称为Dependency Properties,是XAML特有的属性系统。在传统.Net应用开发中,CLR属性是面向对象编程的基础,主要提供对私有字段的访问封装,开发人员可以使用get和set访问器实现读写属性操作。在UWP应用开发中,依赖属性和CLR属性类似,同样提供一个实例级私有字段的访问封装,通过GetValue和SetValue访问器实现属性的读写操作。依赖属性最重要的一个特点是属性值依赖于一个或者多个数据源,提供这些数据源的方式也可以不同,例如,通过数据绑定提供数据源,通过动画,模板资源,样式等方式提供数据源等,在不同的方式数据源下,依赖属性可以实时对属性值进行改变。也正是因为依赖多数据源的缘故,所以称之为依赖属性。
依赖属性可以通过多种不同类型的数据源进行赋值,其赋值顺序的不同影响着属性值的改变。为了能够获取准确的依赖属性值,需要了解不同数据源的优先级别,如下图:
- 从图中可以看到,应用动画占有对以来属性控制的最高优先级,简单理解,无论动画代码定义在当前页面内,还是定义在模板代码内,动画都将获得对页面内依赖属性的最优先控制权。
- 次一级的是依赖属性本地化操作,分别包括其中包括依赖属性赋值,数据绑定,资源引用等。依赖属性使用方式和CLR属性使用类似,可以使用以下格式对依赖属性进行赋值操作:
元素对象.依赖属性 = 属性值
例如:按钮控件中,宽度属性属于依赖属性,其赋值方法是:Button.Width = 160;
- 第三优先级是数据模板和控件模板对依赖属性的控制;
- 第四是样式控制器对依赖属性的控制优先级;
- 最弱的是属性默认值,也就是使用GetValue和SetValue对属性默认的赋值。 开发人员可以通过对依赖属性不同优先级的控制,操作页面属性值,使控件或者页面达到需求运行效果。
我们来看个例子
<Style x:Key="TextBlockStyle1" TargetType="TextBlock">
<Setter Property="Foreground" Value="Red"/>
</Style>
上面的例子我定义了一个TextBlock的样式,将Foreground设置为Red,也就是红色
<Button>
<TextBlock Style="{StaticResource TextBlockStyle1}" Text="陈仁松XAML教程"/>
</Button>
这里的TextBlock使用了样式TextBlockStyle1那么现实出来的Button字体是红色。如果给在TextBlock中也添加属性Foreground,如下图代码,那么Button的字体则会变为白色。
<Button>
<TextBlock Foreground="White" Style="{StaticResource TextBlockStyle1}" Text="陈仁松XAML教程"/>
</Button>
根据前文讲述的依赖属性执行优先级,按钮控件本地赋值优先于控件样式,所以以上代码中,忽略了TextBlockStyle1样式,使用本地的样式赋值。
附加属性
附加属性(Attached Properties),该属性是一种特殊的依赖属性,同时也是XAML中特有的属性之一。其语法调用格式如下:
<控件元素对象 附加元素对象.附加属性名 = 属性值 />
我们可以通过以下几个实例理解附加属性,例如,在布局控件Canvas中定义一个按钮控件,而按钮本身没有任何属性可以控制其在布局控件Canvas中的位置,而在Canvas中,定义了两个依赖属性作为按钮控件的附加属性,帮助按钮控制在Canvas中的位置,其代码如下:
<Canvas>
<TextBlock Canvas.Top="10" Canvas.Left="10" Text="陈仁松XAML教程"/>
</Canvas>
在控件中,使用了“Canvas.附加属性”,效果如同按钮控件从布局控件中继承了Left和Top两个属性值,这时尽管这两个属性仍旧属于Canvas控件,但是属性值已经附加到了按钮控件上,并产生了效果。
另外一个附加属性的实例是TooltipService工具提示服务控件,默认控件生成,不具备动态提示功能,而如果在控件中附加了TooltipService.ToolTip
属性,就可以生成动态显示指定提示内容的效果。例如:
<Button ToolTipService.ToolTip="附加属性测试">
<TextBlock Foreground="White" Style="{StaticResource TextBlockStyle1}" Text="陈仁松XAML教程"/>
</Button>
和Canvas控件的Canvas.Left
和Canvas.Top
道理相同,按钮控件中并没有ToolTip属性,只是附加或者可以理解为“继承”了ToolTipService类,生成以上效果。
从上面的代码可以看出,附加属性主要目的是为了简化代码,增强XAML代码对元素对象的控制。通过对已知类属性的“继承”或者“附加”,在元素对象上实现特有的效果。
附加属性的例子还有很多如Storyboard.TargetProperty
、Grid.Row
、'Grid.Cloumn’等等,当然你也可以选择自定义一个附加属性。
class RotationManager : DependencyObject
{
public static double GetAngle(DependencyObject obj)
{
return (double)obj.GetValue(AngleProperty);
}
public static void SetAngle(DependencyObject obj, double value)
{
obj.SetValue(AngleProperty, value);
}
public static readonly DependencyProperty AngleProperty =
DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(RotationManager), new PropertyMetadata(0.0, OnAngleChanged));
private static void OnAngleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var element = obj as UIElement;
if (element != null)
{
element.RenderTransformOrigin = new Point(0.5, 0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}
}
上面演示了一个附加属性类的写法,你可以在Xaml中使用如下代码:
local:RotationManager.Angel = "30"
这样控件就能进行旋转30度
附加属性
的用处很广,如下拉刷新
、动画
、延迟加载
这些效果都能使用附加属性的方式来实现。
本章就介绍到这里,有什么问题欢迎留言讨论。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter基础widgets教程-cupertinoActivityIndicator篇
- Flutter基础widgets教程-Align篇
- 深入理解Linux内核进程上下文切换
- 面对疾风吧!io_uring 优化 nginx 实战演练
- 奇技淫巧:在 ssh 里面把服务器的文本复制到本地电脑
- 【计算机网络】学习笔记,第一篇:概述(谢希仁版)
- 【Objective-C】Objective-C语言的动态性
- Python解构与封装
- 关于内网穿透:NPS神器
- 【填坑系列】Python习题集
- Facebook 新一代 React 状态管理库 Recoil
- Adminer 简单的利用
- Xserver免脱壳解密APP
- Flask 入门系列教程(三)
- 数据分析入门系列教程-微博热点