1. 概述

依赖属性(DependencyProperty)是UWP的核心概念,它是有DependencyObject提供的一种特殊的属性。由于UWP的几乎所有UI元素都是集成于DependencyObject的FramewordElement,并且这些UI元素的几乎所有属性及它们出现在XAML中的几乎所有属性都是依赖属性,所以可以说依赖属性是专门为UI设计的属性系统。

依赖属性的定义:

/// <summary>
/// 获取或设置Title的值
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
} /// <summary>
/// 标识 Title 依赖属性。
/// </summary>
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(MyPage), new PropertyMetadata(string.Empty));

如上述代码所示,和CLR属性不同依赖属性需要定义TitleProperty ,然后在属性包装器(Getter和Setter)中通过GetValue和SetValue函数操作属性值。

2. 使用的场景

UWP的依赖属性经过大幅简化(相对于WPF),更关注它的核心功能:使用绑定,通过多个输入计算属性值,属性值变化通知,节约内存使用。

2.1 绑定

通过属性包装器,依赖属性可以像CLR属性那样使用,也可以在XAML中通过绑定来使用,这是CLR属性不能提供的功能。

在XAML中使用:

<TextBlock x:Name="TextElement"
Text="{Binding Title}" />

在代码中使用:

var binding = new Windows.UI.Xaml.Data.Binding();
binding.Path = new PropertyPath("Title");
TextElement.SetBinding(TextBlock.TextProperty, binding);

2.2 通过多个输入计算属性值

在UWP中依赖属性通过多个输入源计算属性的值,从而使开发人员就避免了不必要的属性设置值或者处理属性值变更通知。以下列表从优先级由高到低列出了依赖属性的使用顺序。

  • 动画值 正在运行的动画,或具有 HoldEnd 行为的动画。若要进行动画处理,动画的目标属性必须是依赖项属性。
  • 本地值 在代码中直接为对象实例设置的属性值,或者在 XAML 中设置的属性值。

本地值可以通过调用ClearValue函数清除,从而使属性值还原成默认值(以我的经验来说,很少会用到)。

  • 模板属性 如果在某个模板(来自 ControlTemplate 或 DataTemplate)中创建一个元素,该元素就会拥有这些模板属性。
  • 样式设置器 Style中的Setter。
  • 继承值 元素可以从其在对象树中的父级继承依赖项属性的值。譬如开发人员不必为每个TextBlock设置FontSize,只需要为父容器设置FontSize即可套用到父容器中的所有TextBlock上。
  • 默认值 不是指数据类型的默认值,是指PropertyMetadata中指定的默认值。在上面Title的例子中,默认值是string.Empty。

2.3 属性值变化通知

使用依赖属性,不必再实现INotifyPropertyChanged即可在属性改变时通知UI更新。也可以在PropertyMeta中使用PropertyChangedCallback或DependencyObject.RegisterPropertyChangedCallback监视依赖属性的属性值改变。

2.4 节约内存使用

前面提到,UWP可以不必为所有值都设置值,UI元素的依赖属性可以从样式、继承值、默认值等计算出实际值,并不需要分配内存;如果设置了本地值,这个本地值将存储在HashTable中,之后从这个HashTable中读取。这是一种以时间换空间的做法。

假设一个Control自身及所继承的FrameworkElement等父类型中所有的属性加起来大概50个,它的控件模板中大概有3个FrameworkElement,所有属性都是double类型并且所有都不必要设置值,一个Control就可以节省50 * 3 * 8=1200字节的内存空间。我做过的系统最多同时在UI上放了10W个Control,那么就总共节省了大概100M内存。

这么极端的情况也才节省这点内存,作用好像也没那么大(难道我算错了?)。关于节约内存这点稍微了解下就好,有助于了解依赖属性的原理,并且面试的时候有可能有帮助。

3 依赖属性和CLR属性之间的选择

使用依赖属性的情况

  • 基本上所有继承DependencyObject的类中的属性都应该是依赖属性;
  • 需要使用Binding、Style或动画设置值的属性;
  • 需要监视属性值变化通知;
  • 内存真的真的不够用;

使用CLR属性的情况

  • 集合属性。在UWP中常见的集合属性,只有ItemsControl的ItemsSource等少数几个是依赖属性,其它大部分都是CLR属性,譬如Hub的Sections;
  • CPU性能敏感的场合。依赖属性是用时间换空间的概念,假如需要频繁读写而又不需要绑定,可以考虑使用CLR属性;

4. 依赖属性和线程

所有依赖属性都只能在UI线程上使用,否则会抛异常(“应用程序调用一个已为另一线程整理的接口。”)。不过如果使用Async模式的话通常会回避了线程的问题。

[UWP]依赖属性1:概述的更多相关文章

  1. [UWP]依赖属性2:使用依赖属性

    5. 完整的自定义依赖属性 5.1 定义 /// <summary> /// 标识 Title 依赖属性. /// </summary> public static reado ...

  2. win10 uwp 依赖属性

    本文告诉大家如何使用依赖属性,包括在 UWP 和 WPF 如何使用. 本文不会告诉大家依赖属性的好处,只是简单告诉大家如何使用 在 UWP 和 wpf ,如果需要创建自己的依赖属性,可以使用代码片,在 ...

  3. [UWP]为附加属性和依赖属性自定义代码段(兼容UWP和WPF)

    1. 前言 之前介绍过依赖属性和附加属性的代码段,这两个代码段我用了很多年,一直都帮了我很多.不过这两个代码段我也多年没修改过,Resharper老是提示我生成的代码可以修改,它这么有诚意,这次就只好 ...

  4. UWP &WP8.1 依赖属性和用户控件 依赖属性简单使用 uwp添加UserControl

    上面说 附加属性.这章节说依赖属性. 所谓依赖属性.白话讲就是添加一个公开的属性. 同样,依赖属性的用法和附加属性的用法差不多. 依赖属性是具有一个get,set的属性,以及反调函数. 首先是声明依赖 ...

  5. WPF依赖属性

    原文:http://www.cnblogs.com/xiongpq/archive/2010/06/29/1767905.html 概述: Windows Presentation Foundatio ...

  6. 重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试

    原文:重新想象 Windows 8 Store Apps (16) - 控件基础: 依赖属性, 附加属性, 控件的继承关系, 路由事件和命中测试 [源码下载] 重新想象 Windows 8 Store ...

  7. 背水一战 Windows 10 (67) - 控件(控件基类): DependencyObject - CoreDispatcher, 依赖属性的设置与获取, 依赖属性的变化回调

    [源码下载] 背水一战 Windows 10 (67) - 控件(控件基类): DependencyObject - CoreDispatcher, 依赖属性的设置与获取, 依赖属性的变化回调 作者: ...

  8. 08、通过自定义依赖属性,用 StateTrigger 修改全局主题样式

    在 Win 10 的 UWP 中,需要在 xaml 中,通过使用 StateTrigger 修改全局的文本大小.Background.画刷等依赖属性等主题样式.下面只针对字体大小进行描述,其它依赖属性 ...

  9. 【WPF学习笔记】之依赖属性

    概述: Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR) 属性的功能.这些服务通常统称为 WPF 属性系统.由 ...

随机推荐

  1. Alcatraz:插件管理

    安装: 终端粘贴 "curl -fsSL https://raw.github.com/alcatraz/Alcatraz/master/Scripts/install.sh | sh&qu ...

  2. java中关于编码的问题(字符转换流及字符缓冲流 )

    上次我们使用的是字节流,还有一种方式就是字符流,上次说过如何分辨使用哪种流,如果记事本可以读懂则使用字符流,否则使用字节流.使用字符流就需要牵扯到编码的问题,下面给出一种转化流的格式. OutputS ...

  3. 中文字符 unicode转utf-8函数 python实现

    unicode编码范围 00000000-0000007F的字符,用单个字节来表示: 00000080-000007FF的字符用两个字节表示 (中文的编码范围) 00000800-0000FFFF的字 ...

  4. OPENCV直方图与匹配

    直方图可以用来描述不同的参数和事物,如物体的色彩分布,物体的边缘梯度模版以及目标位置的当前假设的概率分布. 直方图就是对数据进行统计的一种方法,并且将统计值定义到一系列定义好的bin(组距)中,获得一 ...

  5. Redis详解

    转自:http://blog.csdn.net/eroswang/article/details/7080412 1.  MySql+Memcached架构的问题 1.MySQL需要不断进行拆库拆表, ...

  6. java.lang.UnsupportedClassVersionError: com/T : Unsupported major.minor version问题解决

    编译的时候jdk版本为1.8 2.运行的时候jdk版本为1.7 解决办法:将编译的jdk版本降为1.7,问题解决

  7. UE4上传图片到服务器

    客户端代码: void AHttpTestCharacter::MyHttpCall(FString Url){ // TexturePath contains the local file full ...

  8. BootStrap TreeView使用示例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. [题解]bzoj 3223 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3884  Solved: 2235[Submit][Sta ...

  10. Ubuntu Linux下设置IP的配置命令

    Ubuntu Linux下设置IP的配置命令 今天装了Ubuntu,但是发现不能上网,开始排查问题: 1.首先确定网络连接是否正确,所用的网线是否可以正常工作 2.查看网卡是否能正常工作,检测的方法如 ...