当前位置: 首页 > news >正文

WPF中依赖属性的底层和普通属性的底层有什么不一样

WPF中依赖属性的底层

在 WPF 中,依赖属性(Dependency Property)是 WPF 属性系统的核心,它支持功能强大的特性(如数据绑定、动画、样式等)。其底层实现是围绕 DependencyObject 类展开的。以下是 WPF 中依赖属性底层机制的关键点:

1. 依赖属性的注册与标识

注册过程

依赖属性是通过静态方法 DependencyProperty.Register 注册的。注册过程生成一个唯一的 DependencyProperty 标识符,用于标识该属性。

  • 注册时需要提供以下信息:

    1. 属性名(字符串形式)。
    2. 属性类型
    3. 所属类型(属性所属的类)。
    4. 元数据PropertyMetadata),可包含默认值、回调等信息。
  • 生成的 DependencyProperty 是一个静态字段,所有依赖属性的访问和操作都依赖它。

示例

public static readonly DependencyProperty MyProperty =DependencyProperty.Register("MyProperty",              // 属性名称typeof(int),               // 属性类型typeof(MyClass),           // 所属类new PropertyMetadata(0));  // 默认元数据

在底层,WPF 通过这个标识符将依赖属性映射到 DependencyObject 的属性存储系统中。

2. 依赖属性的存储系统

属性值存储

依赖属性值不直接存储在对象实例的字段中,而是存储在 DependencyObject 的全局属性存储系统中。

  • WPF 使用一个高效的内部数据结构(EffectiveValueEntry)来存储属性值。这种机制允许多个对象共享默认值,并在需要时动态计算和存储值。
  • 内存优化
    如果某个依赖属性使用的是默认值,那么属性存储系统中不会显式存储该值,而是通过查找元数据获取默认值。

3. 依赖属性的值计算

WPF 使用一个复杂的 优先级系统 来计算依赖属性的最终值。不同来源的值按照优先级规则合并。

值的来源与优先级

以下是依赖属性值的主要来源(按优先级从高到低):

  1. 本地值:通过 SetValue 显式设置的值。
  2. 动画:如果该属性正在动画化,动画值会覆盖本地值。
  3. 绑定:通过数据绑定设置的值。
  4. 样式和模板
    • 样式中的 Setter
    • 样式中的 Trigger
  5. 继承值:某些依赖属性可以从逻辑树中的父元素继承。
  6. 默认值:通过元数据指定的默认值。

示例

当获取依赖属性值时,WPF 会按优先级从高到低依次检查这些来源,找到最高优先级的值作为最终值。

4. 依赖属性的回调机制

依赖属性支持两种回调:

  1. PropertyChangedCallback:当属性值发生变化时触发。
  2. CoerceValueCallback:允许动态调整属性值。

示例

public static readonly DependencyProperty MyProperty =DependencyProperty.Register("MyProperty",typeof(int),typeof(MyClass),new PropertyMetadata(0, OnMyPropertyChanged));private static void OnMyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{// 属性值变化时的逻辑
}

回调机制是 WPF 属性系统的核心特性,允许开发者在属性值变化时执行自定义逻辑。

5. 依赖属性的性能优化

惰性加载(Lazy Loading)

WPF 的依赖属性系统对属性存储进行了优化:

  • 如果属性值未显式设置,则不会占用额外的存储空间。
  • 属性值使用时才动态计算。

批量更新

为了提高性能,WPF 使用了一个批处理机制(DependencyObject 的内部变更通知队列),避免频繁触发 UI 更新。

6. 依赖属性的继承

某些依赖属性(如 DataContext)支持从逻辑树中父元素自动继承值。这是通过 FrameworkPropertyMetadataInherits 标志实现的。

示例

FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits);
DependencyProperty.Register("MyInheritedProperty", typeof(string), typeof(MyClass), metadata);

继承机制的底层依赖于 WPF 的逻辑树结构,值会从父元素传播到子元素。

7. 依赖属性与 CLR 属性的关系

依赖属性通常会通过包装 CLR 属性进行访问。CLR 属性的 gettersetter 调用 GetValueSetValue 方法。

示例

public int MyProperty
{get { return (int)GetValue(MyPropertyProperty); }set { SetValue(MyPropertyProperty, value); }
}

8. 依赖属性与附加属性

附加属性(Attached Property)是依赖属性的一种特殊形式,允许将属性附加到其他类的实例上。其底层仍使用 DependencyProperty 系统,但通过静态方法访问。

示例

public static readonly DependencyProperty MyAttachedProperty =DependencyProperty.RegisterAttached("MyAttached",typeof(int),typeof(MyClass),new PropertyMetadata(0));public static int GetMyAttached(DependencyObject obj)
{return (int)obj.GetValue(MyAttachedProperty);
}public static void SetMyAttached(DependencyObject obj, int value)
{obj.SetValue(MyAttachedProperty, value);
}

9. 底层类的作用

  • DependencyObject
    所有支持依赖属性的类的基类,提供 GetValueSetValue 方法,以及属性存储和变更通知机制。

  • DependencyProperty
    静态标识符类,用于标识依赖属性。

  • PropertyMetadata
    定义依赖属性的元数据,包括默认值和回调方法。

  • FrameworkPropertyMetadata
    PropertyMetadata 的扩展,支持 WPF 框架特性(如继承、AffectsRender 等)。

总结

依赖属性是 WPF 属性系统的核心,其底层机制基于 DependencyObject 的高效存储和动态值计算能力。通过统一的存储系统、优先级规则和回调机制,依赖属性为 WPF 提供了数据绑定、样式、动画等高级功能,同时在性能和灵活性之间达成了平衡。

相关文章:

WPF中依赖属性的底层和普通属性的底层有什么不一样

WPF中依赖属性的底层 在 WPF 中,依赖属性(Dependency Property)是 WPF 属性系统的核心,它支持功能强大的特性(如数据绑定、动画、样式等)。其底层实现是围绕 DependencyObject 类展开的。以下是 WPF 中依赖…...

【Qt】drawText字体大小问题探究

背景 软件的一个功能是: 打开图片在图片上绘制序号,序号的样式是圆圈内包含数字将带有序号的图片打印出来 实现思路也很简单,在屏幕上显示时重写paintEvent函数,利用QPainter完成图片和序号的绘制。打印时只需要将QPainter对应…...

Mapbox-GL 的源码解读的一般步骤

Mapbox-GL 是一个非常优秀的二三维地理引擎,随着智能驾驶时代的到来,应用也会越来越广泛,关于mapbox-gl和其他地理引擎的详细对比(比如CesiumJS),后续有时间会加更。地理首先理解 Mapbox-GL 的源码是一项复…...

【C++】高级分析 switch 语句的应用

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯switch 语句的基本用法语法结构核心要点实例演示正确实现 期望输出错误实现错误输出 💯if 与 switch 语句的实现比较使用 if 语句使用 switch 语句比较分析 &am…...

活动预告 | Surface 来了#11:Windows 11 AI+ PC,释放 AI 办公设备的无限潜能

课程介绍 欢迎来到 Surface 来了第 11 期节目。 今年 5 月底,微软推出了专为 AI 体验而设计的全新 Windows PC 品类:Windows 11 AI PC。 微软通过 Windows 11 AI PC,进一步强调了 NPU 在运行设备端 AI 功能的重要性。并要求符合这一品类的…...

php基础:正则表达式

1.正则表达式 正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、匹配、查找及替换操作。到目前为止,我们前面所用过的精确(文本)匹配也是一种正则表达式。 在PHP中,正则表达式一般是由正规字…...

go语言压缩[]byte数据为zlib格式的时候,耗时较多,应该怎么修改?

在Go语言中使用compress/flate包来实现Zlib格式的压缩时,如果发现压缩耗时较多,可以考虑以下几个优化方向: ### 1. 压缩级别 默认情况下,compress/flate包中的NewWriter函数使用的是默认压缩级别(BestSpeed和BestComp…...

[机器学习]AdaBoost(数学原理 + 例子解释 + 代码实战)

AdaBoost AdaBoost(Adaptive Boosting)是一种Boosting算法,它通过迭代地训练弱分类器并将它们组合成一个强分类器来提高分类性能。 AdaBoost算法的特点是它能够自适应地调整样本的权重,使那些被错误分类的样本在后续的训练中得到…...

深入了解Spring

目录 Spring基础 什么是Spring框架? Spring 包含的模块有哪些? Core Container AOP Data Access/Integration Spring Web Messaging Spring Test Spring,Spring MVC,Spring Boot 之间什么关系? Spring基础 什么是Spring框架? Sp…...

jar 包如何下载

maven官网:https://mvnrepository.com/ 点击搜索,找对应搜索结果点击...

ESlint代码规范,手动与自动修复

规范说明 规则参考 - ESLint - 插件化的 JavaScript 代码检查工具 规范说明 ​ ​ 可看到是main.js文件报错分别是第三行第30个字符,以及第七行第一个字符 后面则是规范说明,可以根据说明查找相应的规范 一.手动修正 ctrl f 可以搜索 二.自动修正 …...

利用编程获得money?

在当今数字化时代,编程技能为人们开辟了众多赚钱途径。无论你是编程新手还是经验丰富的开发者,都能在广阔的市场中找到适合自己的盈利方式。以下是一份详细的用编程赚钱指南。 一、自由职业平台 像 Upwork、Freelancer 和 Fiverr 等知名自由职业平台&am…...

设计规规范:【App 配色】

文章目录 引言I App 配色组成色彩象征 & 联想II 知识扩展设计流程图UI设计交互设计UI交互设计引言 设计规范,保持设计一致性,提高设计效率。宏观上对内统一,管理与合作变得容易。 按类型管理颜色、文本样式、图标、组件(symbol)。 蓝湖设计规范云 https://lanhuapp.co…...

react 使用 PersistGate 白屏解决方案

我在全局添加 PersistGate 组件后报错了 报错信息如下: Uncaught Error: A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped wi…...

F5中获取客户端ip地址(client ip)

当F5设备对其原始设置上的所有IP地址使用NAT时,连接到poo成员(nodes、backend servers)的出站连接将是NAT IP地址。 pool 成员(nodes、backend servers)将无法看到真实的客户端 ip地址,因为看到的是F5上的…...

Maven(生命周期、POM、模块化、聚合、依赖管理)详解

目录 Maven构建项目的生命周期 Maven的常用命令 POM 依赖管理 依赖导入 依赖范围设置 依赖版本维护 依赖传递 依赖冲突 解决依赖冲突的方法 使用maven提供的依赖调节原则 排除依赖,排除依赖的jar包 锁定版本 项目模块化 Maven项目的继承 Maven项目…...

电力场景绝缘子缺陷识别分割数据集labelme格式1099张3类别

数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):1099 标注数量(json文件个数):1099 标注类别数:3 标注类别名称:["brokenpart","brokeninsulator…...

【k8s集群应用】Kubernetes 容器编排系统

文章目录 Kubernetes 容器编排系统背景与发展Kubernetes 基本概念Kubernetes 集群架构与组件Kubernetes 核心组件Master 组件配置存储中心Node 组件 Kubernetes核心概念1. Pod2. Pod控制器3. Label与Label选择器4. Service5. Ingress6. Volume7. Name与Namespace K8S创建Pod资源…...

Unity3D仿星露谷物语开发2之工程初始化

1、依赖包安装 进入【Window -> Package Manager】 安装如下插件: 1)Cinemachine 它是一套专门控制Unity Camera的模块,适用于各种游戏场景中物体的移动变化,解决了许多关于摄像机间的复杂控制,混合&#xff0c…...

Kafka篇之参数优化进而提高kafka集群性能

1. Kafka性能优化分类 Kafka集群的性能优化涉及多个方面,包括硬件资源、网络、配置文件参数等。 调优目标通常是为了提高吞吐量、减少延迟、提升稳定性和故障恢复能力。 以下是Kafka集群调优的常见策略,以及调优后的配置文件示例。 1. 硬件资源调优 C…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

GraphRAG优化新思路-开源的ROGRAG框架

目前的如微软开源的GraphRAG的工作流程都较为复杂,难以孤立地评估各个组件的贡献,传统的检索方法在处理复杂推理任务时可能不够有效,特别是在需要理解实体间关系或多跳知识的情况下。先说结论,看完后感觉这个框架性能上不会比Grap…...

动态规划-1035.不相交的线-力扣(LeetCode)

一、题目解析 光看题目要求和例图,感觉这题好麻烦,直线不能相交啊,每个数字只属于一条连线啊等等,但我们结合题目所给的信息和例图的内容,这不就是最长公共子序列吗?,我们把最长公共子序列连线起…...