在设计与开发 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. bzoj:1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏

    Description 奶牛们又在玩一种无聊的数字游戏.输得很郁闷的贝茜想请你写个程序来帮她在开局时预测结果.在游戏的开始,每头牛都会得到一个数N(1<=N<=1,000,000).此时奶 ...

  2. UE4 保存为bitmap

    TArray<FColor> colorData;    colorData.Init(FColor(0, 0, 255, 255), 1920 * 1080);    for (int ...

  3. 【搬运】Tea算法Java实现工具类

    最近在做数据加密,目标是实现平台app的数据安全性,所以准备使用AES+Base64进行加密,适逢一个特长的json串AES加密不了,于是在谷歌了各种算法,判断是否合用,参见 各种加密算法比较 一文中 ...

  4. vue-cli创建的项目中引入第三方库报错 'caller', 'calle', and 'arguments' properties may not be...

    http://blog.csdn.net/sophie_u/article/details/76223978 以在vue中引入mui第三方库为例: 虽然针对vue,有单独的vue-mui库可以使用,但 ...

  5. PHP 获得当前页面所有变量常量的值

    get_defined_vars() - 返回由所有已定义变量所组成的数组,这个函数在二次开发的时候用起来非常给力: get_defined_constants();可以返回当前的所有常量 zend的 ...

  6. 邓_phpcms_二次开发_留言板

    ================================================================= •在 phpcms/modules 目录下创建文件夹,并将其命名为g ...

  7. 【编程技巧】addSubview和insertSubview的区别

    addSubview 是将view加到所有层的最顶层 相当于将insertSubview的atIndex参数设置成view.subviews count 即 [view addSubview:onev ...

  8. CCF系列之窗口(201403-2)

    试题编号: 201403-2时间限制: 1.0s 内存限制: 256.0MB 问题描述 在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域.窗口的边界上的点也属于该窗口 ...

  9. ASP.NET导出word实例

    ASP.NET导出word实例 最近遇到一个题目就是如何在asp.net中将数据导出到word中,由于数据是动态的,所以需要在后台拼出想要的的格式,翻遍了网页找出了一个比较满意的代码,感谢那位高手.代 ...

  10. tomcat 部署war项目

    前提是 jdk环境已配好 把项目war包放到tomcat的webapps目录下 启动tomcat: 这里我把8080端口修改成了80 IP也修改了 如果没修改直接输入localhost:8080/te ...