WPF 初识依赖属性

依赖属性的意义和作用

  • 核心模块
  • 内存共享,节省空间
  • 数据绑定、样式、模板、动画。。。。
  • 如果没有依赖属性,这个框架就是一个控件框架 相当于Winform

依赖属性的基本定义

基本过程:声明、注册、包装

在需要写依赖属性的类中,继承DependencyObject,或者DependencyObject以下的类都行:

声明

public static readonly DependencyProperty ValueProperty;

注意:

声名 DependencyProperty

约定:名字命名为:名字+Property

readonly 只能被赋值一次,不能被二次修改

注意:readonly这里的只读是限制注册的,不包含里面的值,所以可以动态赋值SetValue

注册

基本的三个参数: 属性名称、属性类型、所属类型(所使用的类的名称)

ValueProperty = DependencyProperty.Register("Value",typeof(double),typeof(DependencyPropertyStudy));

包装

将依赖属性,包装成普通属性,修改和创建

必须继承DependencyObject及以上的类,才可以写GetValue和SetValue:

 public double Value{get { return (double)GetValue(ValueProperty); }set{SetValue(ValueProperty, value);}}

代码片段:propdp

输入propdp + tab 自动生成

和上面注册是一样的,不过多了一个默认值(PropertyMetadata),加粗的部分是需要自定义的,根据自己的需求来。

 public int MyProperty{get { return (int)GetValue(MyPropertyProperty); }set { SetValue(MyPropertyProperty, value); }}// Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...public static readonly DependencyProperty MyPropertyProperty =DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));

依赖属性的主要参数与回调参数

默认值

ValueProperty = DependencyProperty.Register("Value",typeof(double),typeof(DependencyPropertyStudy));
属性值变化回调:
ValueProperty = DependencyProperty.Register("Value",typeof(double),typeof(DependencyPropertyStudy),new PropertyMetadata(1d,new PropertyChangedCallback(OnValueChanged)));// 属性值变化回调参数
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{// 静态回调 本方法体的非静态方法(d as DependencyPropertyStudy).Refresh();
}

属性值变化的时候,进入此回调函数e.NewValue 将被修改。

如果调用成功 这里将之后对应的依赖值发生了变化

当两次值一样的时候,不触发

验证回调:
ValueProperty = DependencyProperty.Register("Value",typeof(double),typeof(DependencyPropertyStudy),new PropertyMetadata(1d),new ValidateValueCallback(OnValueValidation));/// <summary>
/// 对数据的判断结果 编译能触发限制报错信息
/// 需要强制回调的时候,就不要给验证信息False 否则不走强制回调
/// </summary>
/// <param name="v">依赖属性所接受到的最新的值</param>
/// <returns>对数据的判断结果</returns>
private static bool OnValueValidation(object v)
{//if((double)v > 2000d)//    return false;return true;
}
强制回调
ValueProperty = DependencyProperty.Register("Value",typeof(double),typeof(DependencyPropertyStudy),new PropertyMetadata(1d,new PropertyChangedCallback(OnValueChanged),new CoerceValueCallback(OnValueCoerce)));// 强制回调参数
// 如果值超限,可以强制改回需要的值范围private static object OnValueCoerce(DependencyObject d, object v){if ((double)v > 255d)return 255d;if ((double)v < 0d)return 0d;return v;}

完整代码:三个回调一起

 ValueProperty = DependencyProperty.Register("Value",typeof(double),typeof(DependencyPropertyStudy),new PropertyMetadata(1d,new PropertyChangedCallback(OnValueChanged),new CoerceValueCallback(OnValueCoerce)),new ValidateValueCallback(OnValueValidation));// 属性值变化回调:处理的是监听属性值的变化private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){// 如果调用成功 这里将之后对应的依赖值发生了变化// 当两次值一样的时候,不触发// 静态回调 本方法体的非静态方法(d as DependencyPropertyStudy).Refresh();}/// <summary>/// 对数据的判断结果 编译能触发限制报错信息/// </summary>/// <param name="v">依赖属性所接受到的最新的值</param>/// <returns>对数据的判断结果</returns>private static bool OnValueValidation(object v){//if((double)v > 2000d)//    return false;return true;}// 强制回调参数private static object OnValueCoerce(DependencyObject d, object v){if ((double)v > 255d)return 255d;if ((double)v < 0d)return 0d;return v;}

执行顺序:

验证回调(首先给个默认值验证) --> 加载方法(load) --> 强制回调 --> 属性变化回调 --> 验证回调

元数据:FrameworkPropertyMetadataOptions

 public double ColumnSpace{get { return (double)GetValue(ColumnSpaceProperty); }set { SetValue(ColumnSpaceProperty, value); }}// Using a DependencyProperty as the backing store for ColumnSpace.  This enables animation, styling, binding, etc...public static readonly DependencyProperty ColumnSpaceProperty =DependencyProperty.Register("ColumnSpace",typeof(double), typeof(XHPanel),//new PropertyMetadata(0d,new PropertyChangedCallback(OnColumnSpaceChanged))// AffectsArrange: 影响排列  AffectsMeasure:影响测量 // 如果有多个用"|"分开new FrameworkPropertyMetadata(0d,FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));

此元数据使用在自定义控件的时候,修改属性时刷新UI是使用

扩展:FrameworkPropertyMetadataOptions 的属性:
None:未指定任何选项;依赖属性使用 WPF 属性系统的默认行为。
AffectsMeasure:更改此依赖属性的值会影响布局组合的测量过程。
AffectsArrange:更改此依赖属性的值会影响布局组合的排列过程。  
AffectsParentMeasure:更改此依赖属性的值会影响父元素上的测量过程。 
AffectsParentArrange:更改此依赖属性的值会影响父元素上的排列过程。  
AffectsRender:更改此依赖属性的值会影响呈现或布局组合的某一方面(不是测量或排列过程)。 
Inherits:此依赖属性的值将由子元素继承。
OverridesInheritanceBehavior:此依赖属性的值跨越分隔的树以实现属性值继承。
NotDataBindable:不允许将数据绑定到此依赖属性。
BindsTwoWayByDefault:此依赖属性上的数据绑定的 System.Windows.Data.BindingMode 默认为 System.Windows.Data.BindingMode.TwoWay。
Journal:此依赖属性的值应由日记记录进程或在由统一资源标识符 (URI) 导航时进行保存或存储。
SubPropertiesDoNotAffectRender:此依赖属性值上的子属性不会影响呈现的任何方面。

依赖属性的继承

允许元素树中的子元素从最近的父元素获取特定属性的值

由于父元素也可能通过属性值继承获得其属性值,因此系统可能递归回页面根

父亲依赖属性代码:

public int Test{get { return (int)GetValue(TestProperty); }set { SetValue(TestProperty, value); }
}// Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty TestProperty =DependencyProperty.Register("Test", typeof(int), typeof(XHPanel),new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.Inherits));

子类继承代码:

关键字:父类.依赖属性.AddOwner(类型,默认值)

 public int Test{get { return (int)GetValue(TestProperty); }set { SetValue(TestProperty, value); }}// 依赖属性的继承 继承于XHPanel 的 TestProperty// 允许元素树中的子元素从最近的父元素获取特定属性的值// 由于父元素也可以通过属性值继承获得其属性值,因此系统可能地归回页面根public static readonly DependencyProperty TestProperty =XHPanel.TestProperty.AddOwner(typeof(DependencyPropertyStudy),new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.Inherits));

演示:XAML代码

<local:XHPanel Test="12" ColumnSpace="20" RowSpace="20" Visibility="Collapsed"><local:DependencyPropertyStudy x:Name="dps" />
</local:XHPanel>
<Button Width="200" Height="30"Content="测试依赖属性继承" FontSize="20" Click="Button_Click"/>

按钮事件代码:

private void Button_Click(object sender, RoutedEventArgs e)
{// 此时子没设置Test 属性,看是否可以弹出继承父的TestMessageBox.Show(this.dps.Test.ToString());
}

效果:

以上就是所有的依赖属性的基础使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3223662.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Clickhouse的联合索引

Clickhouse 有了单独的键索引&#xff0c;为什么还需要有联合索引呢&#xff1f;了解过mysql的兄弟们应该都知道这个事。 对sql比较熟悉的兄弟们估计看见这个联合索引心里大概有点数了&#xff0c;不过clickhouse的联合索引相比mysql的又有些不一样了&#xff0c;mysql 很遵循最…

谷粒商城 - 编写一个自定义校验注解

目录 开始 未来实现效果 第一步&#xff1a;编写自定义校验注解 第二步&#xff1a;编写自定义校验器 第三步&#xff1a;编写配置文件 效果演示 开始 未来实现效果 编写一个 ListValue 注解&#xff0c;可以实现功能有&#xff1a; 限定字段的值&#xff0c;例如指定只…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【密钥协商(ArkTS)】

密钥协商(ArkTS) 以协商密钥类型为X25519 256&#xff0c;并密钥仅在HUKS内使用为例&#xff0c;完成密钥协商。 开发步骤 生成密钥 设备A、设备B各自生成一个非对称密钥&#xff0c;具体请参考[密钥生成]或[密钥导入]。 密钥生成时&#xff0c;可指定参数HUKS_TAG_DERIVE…

【BUG】RestTemplate发送Post请求后,响应中编码为gzip而导致的报错

BUG描述 20240613-09:59:59.062|INFO|null|810184|xxx|xxx||8|http-nio-xxx-exec-1|com.xxx.jim.xxx.XXXController.?.?|MSG接收到来自xxx的文件请求 headers:[host:"xxx", accept:"text/html,application/json,application/xhtmlxml,application/xml;q0.9,*…

Redis 实现的延时队列组件

最近看开源看到一个好用的延时队列组件&#xff0c;已经上生产。代码量很少&#xff0c;主要就是利用Redis监听过期键实现的。然后搞点策略模式柔和柔和。利用Spring Start 封装了一下&#xff0c;全是俺掌握的知识&#xff0c;稍微研究了下就搞懂了。觉得挺有用的&#xff0c;…

2024.7.9作业

1、提示并输入一个字符串&#xff0c;统计该字符串中字母、数字、空格以及其他字符的个数 #include <stdio.h> #include <string.h> int main(int argc,const char *argv[]) { char arr[30]{0}; int zm0,kg0,sz0,qt0; printf("请输入字符串&…

utf8mb4和utf8的不同、若依框架,代码生成器,gitee,前端vue的下载、修复和启动(寻求大佬帮助若依框架三、2.3)

2024.7.9 一、数据库的排序和统一问题。utf8mb4和utf8的不同1.1 发现问题1.2 解决问题-在idea中用sql生成器&#xff0c;生成sql语句&#xff0c;然后在里面修改1.3 utf8和utf8mb4的区别 二、若依前后端框架。代码生成器&#xff08;还没研究懂&#xff0c;但有三个方案&#x…

微软清华提出全新预训练范式,指令预训练让8B模型实力暴涨!实力碾压70B模型

现在的大模型训练通常会包括两个阶段&#xff1a; 一是无监督的预训练&#xff0c;即通过因果语言建模预测下一个token生成的概率。该方法无需标注数据&#xff0c;这意味着可以利用大规模的数据学习到语言的通用特征和模式。 二是指令微调&#xff0c;即通过自然语言指令构建…

Python基础-成年人判断(if条件语句联系)

注意输入的年龄需要转化为字符串 代码&#xff1a; print("欢迎来到游乐场&#xff1a;儿童免费&#xff0c;成人收费") age int(input("请输入你的年龄:")) if age>18:print("你已经成年&#xff0c;需要补票10元") # 四个空格缩进print…

使用Mplayer实现MP3功能

核心功能 1. 界面设计 项目首先定义了一个clearscreen函数&#xff0c;用于清空屏幕&#xff0c;为用户界面的更新提供了便利。yemian函数负责显示主菜单界面&#xff0c;提供了包括查看播放列表、播放控制、播放模式选择等在内的9个选项。 2. 文件格式支持 is_supported_f…

gpt-4o看图说话-根据图片回答问题

问题&#xff1a;中国的人口老龄化究竟有多严重&#xff1f; 代码下实现如下&#xff1a;&#xff08;直接调用openai的chat接口&#xff09; import os import base64 import requests def encode_image(image_path): """ 对图片文件进行 Base64 编码 输入…

Nacos2.X 配置中心源码分析:客户端如何拉取配置、服务端配置发布客户端监听机制

文章目录 Nacos配置中心源码总流程图NacosClient源码分析获取配置注册监听器 NacosServer源码分析配置dump配置发布 Nacos配置中心源码 总流程图 Nacos2.1.0源码分析在线流程图 源码的版本为2.1.0 &#xff0c;并在配置了下面两个启动参数&#xff0c;一个表示单机启动&#…

pytest-yaml-sanmu(六):YAML数据驱动测试

如果说 pytest 中哪些标记使用得最多&#xff0c;那无疑是 parametrize 了&#xff0c; 它为用例实现了参数化测试的能力&#xff0c;进而实现了数据驱动测试的能力。 1. 使用标记 parametrize 的使用需要提高两个内容&#xff1a; 参数名 参数值 pytest 在执行用例时&…

【LeetCode刷题笔记】LeetCode.11.盛最多水的容器

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多算法知识专栏&#xff1a;算法分析&#x1f525; 给大家跳段街舞感谢…

020-GeoGebra中级篇-几何对象之点与向量

本文概述了在GeoGebra中如何使用笛卡尔或极坐标系输入点和向量。用户可以通过指令栏输入数字和角度&#xff0c;使用工具或指令创建点和向量。在笛卡尔坐标系中&#xff0c;示例如“P(1,0)”&#xff1b;在极坐标系中&#xff0c;示例如“P(1;0)”或“v(5;90)”。文章还介绍了点…

Python大数据分析——决策树和随机森林

Python大数据分析——决策树和随机森林 决策树决策树节点字段的选择信息熵条件熵信息增益信息增益率 基尼指数条件基尼指数基尼指数增益 决策树函数 随机森林函数 决策树 图中的决策树呈现自顶向下的生长过程&#xff0c;深色的椭圆表示树的根节点&#xff1b;浅色的椭圆表示树…

Raylib 实现超大地图放大缩小与两种模式瓦片地图刷新

原理&#xff1a; 一种刷新模式&#xff1a; 在宫格内整体刷新&#xff0c;类似九宫格移动到边缘&#xff0c;则九宫格整体平移一个宫格&#xff0c;不过这里是移动一个瓦片像素&#xff0c;实际上就是全屏刷新&#xff0c;这个上限是 笔记本 3060 70帧 100*100个瓦片每帧都…

思维+并查集,1670C - Where is the Pizza?

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1670C - Where is the Pizza? 二、解题报告 1、思路分析 考虑两个数组a&#xff0c;b的每个位置只能从a&#xff0c;b中挑一个 不妨记posa[x]为x在a中位置&#xff0c;posb同理 我们假如位置i挑选a[i]&a…

Java--instanceof和类型转换

1.如图&#xff0c;Object&#xff0c;Person&#xff0c;Teacher&#xff0c;Student四类的关系已经写出来了&#xff0c;由于实例化的是Student类&#xff0c;因此&#xff0c;与Student类存在关系的类在使用instanceof时都会输出True&#xff0c;而无关的都会输出False&…

小试牛刀--对称矩阵压缩存储

学习贺利坚老师对称矩阵压缩存储 数据结构实践——压缩存储的对称矩阵的运算_计算压缩存储对称矩阵 a 与向量 b 的乘积-CSDN博客 本人解析博客 矩阵存储和特殊矩阵的压缩存储_n阶对称矩阵压缩-CSDN博客 版本更新日志 V1.0: 对老师代码进行模仿 , 我进行名字优化, 思路代码注释 …