在设计与开发 WPF 自定义控件时,我们常常为会控件添加一些依赖属性以便于绑定或动画等。事实上,除了能够添加正常的依赖属性外,我们还可以为控件添加只读依赖属性(以下统称“只读属性”),以增加控件的灵活性。

这听起来有些矛盾。只读依赖属性,只能读不能写,却又怎么能提高控件的灵活性呢?想想我们常用的 IsMouseOver 等属性就可以理解,它们都是只读属性,但如果没有它们,想要控制样式将比较复杂。

所以,总结来说,只读属性的特点是:无法赋值,不能绑定,不能用于动画,不能验证等;而之所以使用它,主要目的是结合属性触发器 (Trigger) 来实现样式的切换

实践

比如,我们要创建一个 FilePicker 控件,用户通过它可以选择文件。那么,它至少包括一个 TextBlock(或 TextBox)和一个 Button,分别用于显示选择文件的路径和打开对话框。

现在我们想实现当用户选择了文件后,控件呈现某种样式。要这么做,我们就可以增加一个 IsFilePicked 只读属性,然后在 ControlTemplate 中添加 Trigger 来控制样式的变化。

1. 创建(定义与注册)

创建只读属性与创建普通依赖属性一样,包括定义、注册、与 CLR 属性包装这三步。不同的是要使用 DependencyProperty 的 RegisterReadOnly 方法来注册,这个方法会返回 DependencyPropertyKey 对象,它包含了对应只读属性的标识符,也就是与它关联的只读属性(通过 DependencyProperty 属性获得),并且对只读属性赋值也是通过它(注意:只读属性自身无法被赋值),代码如下:

        // 只读属性的定义与注册
private static DependencyPropertyKey IsFilePickedPropertyKey = DependencyProperty.RegisterReadOnly("IsFilePicked", typeof(bool), typeof(FilePicker), new PropertyMetadata(false)); public static DependencyProperty IsFilePickedProperty = IsFilePickedPropertyKey.DependencyProperty;

注意其中的命名,因为我们要创建的属性是 IsFilePicked,所以上面两个变量都是在这个名称后加了后辍,分别是 PropertyKey 和 Property,这是命名规范。

另外,我们在元数据的实例中给这个只读属性设置默认值为 false。

2. 包装

然后,将它以 CLR 属性的方式来包装,由于这是个只读属性,所以只需要 get 段就可以,代码如下:

        // 只读属性的包装
public bool IsFilePicked
{
get { return (bool)GetValue(IsFilePickedProperty); }
}

3. 通过 DependencyPropertyKey 赋值

在合适的位置(当用户选择过文件后),使用 SetValue 方法来赋值,SetValue 有两个重载,要为只读属性赋值,需使用第二个  SetValue(DependencyPropertyKey key, object value) ,代码如下:

     SetValue(IsFilePickedPropertyKey, true);

4. 应用

逻辑写好后,在模板中增加以下 XAML 代码,即可:

    <ControlTemplate.Triggers>
<Trigger Property="IsFilePicked" Value="True">
<!--显示绿色边框-->
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="2" />
</Trigger>
</ControlTemplate.Triggers>

总结

本文简单介绍了在 WPF 中如何创建以及使用只读依赖属性,合适地使用它,能够使我们更灵活地实现对自定义控件样式的控制。

WPF: 只读依赖属性的介绍与实践的更多相关文章

  1. WPF的依赖属性

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

  2. WPF的依赖属性和附加属性(用法解释较全)

    转:https://www.cnblogs.com/zhili/p/WPFDependencyProperty.html 一.引言 感觉最近都颓废了,好久没有学习写博文了,出于负罪感,今天强烈逼迫自己 ...

  3. WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性

    原文:WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性 如果你要自定义一个图片按钮控件,那么如何在主窗体绑定这个控件上图片的Source呢? ...

  4. wpf 的依赖属性只能在loaded 事件之后才能取到

    wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  InitializeComponent(); 之后取不到 wpf 的依赖属性只能在loaded 事件之后才能取到,在构造函数的  ...

  5. WPF 中依赖属性的继承(Inherits)

    WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点.例如,数据绑定中经常使用的DataContextProperty: var host ...

  6. WPF利用依赖属性和命令编写自定义控件

    以实例讲解(大部分讲解在代码中) 1,新建一个WPF项目,添加一个用户控件之后在用户控件里面添加几个控件用作测试, <UserControl x:Class="SelfControlD ...

  7. WPF之依赖属性和附加属性

     参考资料: 一站式WPF--依赖属性(DependencyProperty)一 一站式WPF--依赖属性(DependencyProperty)二         依赖属性之我见: 这两篇文章介绍的 ...

  8. WPF 自定义依赖属性

      原博客地址:http://www.cnblogs.com/DebugLZQ/archive/2012/11/30/2796021.html    DependencyObject和Dependen ...

  9. [转]WPF的依赖属性是怎么节约内存的

    WPF升级了CLR的属性系统,加入了依赖属性和附加属性.依赖属性的使用有很多好处,其中有两点是我认为最为亮眼的: 1)节省内存的开销; 2)属性值可以通过Binding依赖于其它对象上,这就使得我的数 ...

随机推荐

  1. 【Java学习笔记之二十三】instanceof运算符的用法小结

    instanceof运算符用法 运算符是双目运算符,左面的操作元是一个对象,右面是一个类.当左面的对象是右面的类创建的对象时,该运算符运算的结果是true,否则是false 说明: (1)一个类的实例 ...

  2. 51 Nod 1057 N的阶乘【Java大数乱搞】

    1057 N的阶乘 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 输入N求N的阶乘的准确值.   Input 输入N(1 <= N <= 10000) Ou ...

  3. lombok使用基础教程

    前言 lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码.在很多工具类的项目中都有这个功能.比如dagger. 通俗的说,lombok可以通过注解来标示生成getter settte ...

  4. 如何在SecureCRT中给linux上传和下载文件 安装redis

    首先建立文件 /download sz和rz命令无法用.则用以下1.和2.3步骤   需要上传或者下载,需要使用rz和sz命令.如果linux上没有这两个命令工具,则需要先安装.可以使用yum安装.运 ...

  5. <input type="text">和<textarea>的区别

    在我们开发时经常需要用到输入框,通常解决办法就是<input type="text">和<textarea>,那么这两个标签有什么区别呢?  一:<i ...

  6. 初窥React Native

    这两天在学习react native,被虐得布耀布耀的,运行一个hello world花了一天时间(手动捂脸). 由于是跟着官网走,所以一开始便是开发环境的搭建.其他的就不说了(详情见 React N ...

  7. JavaScript八张思维导图—操作符

    JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...

  8. js object 常用方法总结

    Object.assign(target,source1,source2,...) 该方法主要用于对象的合并,将源对象source的所有可枚举属性合并到目标对象target上,此方法只拷贝源对象的自身 ...

  9. Intellij idea 中修改java web代码 ,网页不同步

    问题可能出在  Intellij  idea 没有将源码保存在本地,浏览器访问了缓存而没有访问最新文件 用命令行查看了源码,同步了 接着禁止浏览器缓存,网页同步了 打开火狐浏览器 输入 about:c ...

  10. 邓_ Php·笔记本[照片]

    -------------------------------------------------------------------------------------------- [PHP] - ...