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

WPF——属性

一、属性

  • 类最初只有字段与函数,字段为一个变量,访问权限可以是private,protected,public。而将字段设为private,不方便外界对类数据的操作,但是将字段设为public又怕外界对数据进行非法操作,于是便为每个字段设计了set和get,在保证数据的合法性的同时支持外界对其进行操作。
  • 因为字段有了对应的访问接口,便升级成为了属性。注意类函数是静态的,只有一份,因此类实例增多时,类的字段变为属性的内存存储空间不会增加,即同个字段的{set;get;}使用的是同一份。
  • private int id;
    public int Id { set; get; }

二、依赖属性

1. 依赖属性的定义

  • 依赖属性就是一种可以自己没有值,并能通过使用Binding从数据源获得值(依赖在别人身上)的属性,而拥有依赖属性的对象被称为“依赖对象”。
  • 与传统的CLR属性相比,依赖属性的优点有:1.节省实例对内存的开销 2. 属性值可以通过Binding依赖在其他对象上。

2. 依赖属性对内存的使用

  • WPF允许依赖对象在被创建的时候并不包含用于存储数据的空间、只保留在需要用到数据时能够获得默认值、借用其他对象数据或实时分配空间的能力。
  • WPF中依赖对象的概念被DependdencyObject类实现,依赖属性的概念则由DependencyProperty类所实现。DependdencyObject通过GetValue和SetValue来获取和设置依赖属性的值。

3. 声明和使用依赖属性

public class Student:DependencyObject
{public static readonly DependencyProperty=DependencyProperty.Register("Name",typeof(string),typeof(Student));
}声明:
1. 依赖属性一定要在依赖对象DependencyObject内声明
2. 成员变量名称后面需要加Property以标识其为依赖属性
3. 需要同时被public static readonly三个修饰符修饰
4. 并非使用new操作符得到而是使用DependencyProperty.Register方法生成
  • 依赖属性是由public static readonly修饰的DependencyProperty实例,没有包装器(set;get)这个依赖属性依旧存在

  • 包装器的作用是以“实例属性”的形式向外界暴露依赖属性,这样依赖属性才能成为Binding的Path

  • 注册依赖属性使用的第二个参数是一个数据类型,这个数据类型也是包装器的数据类型

  • 在没有对依赖属性使用包装器时,外界只能通过类实例的GetValue()和SetValue()来对依赖属性进行值的设置与获取。

  • 若为依赖属性添加一个CRL属性外包装,则外界可以直接访问依赖属性。

public class Student:DependencyObject
{public string Name{get{ return (string}GetValue(NameProperty);}set{ SetValue(NameProperty,value);}}
}

值得注意的是,Student类虽然没有实现InoticePropertyChanged接口,但是当属性的值发送改变时与之关联的Binding对象依然可以得到通知,依赖属性默认带有这样的功能,因此会是很好的Binding数据源。

4. 依赖属性值存储的秘密

为什么依赖属性被public static readonly修饰?

  • 系统维护一个全局静态的依赖属性实例哈希表。
  • 依赖对象实例的属性名和宿主类型名生成hash code为Key,依赖对象实例为Value,被存入哈希表中。
  • 每个依赖属性实例会有一个GlobalIndex属性,系统通过该值的唯一性可以在哈希表中找到对应的EffectiveValueEntry来获取值。
  • 每个依赖对象实例都会维护一个EffectValueEntry[],存储不同的依赖属性实例的GlobalIndex,为检索到实例对应属性的值而存在。
  • 总的来说,static关键字所修饰的依赖属性对象其作用是用来检索真正的属性而不是存储值,被用来检索值的实际上是依赖属性的GlobalIndex属性。

依赖属性的值除了可能存储在默认值和EffectiveValueEntry[]外,还有很多途径可以获得,但是它们有优先级控制。
在这里插入图片描述

三、附加属性

1. 附加属性的定义

  • 附加属性是指一个属性本来不属于某个对象,但由于某种需求而被后来附加上。即把对象放入一个特定环境后对象才具有的属性(表现出来就是被环境赋予的属性)就被称为附加属性。
  • 比如说,TextBox在Grid下具有Grid.Column、Grid.Row等属性,在Canvas在具有Canvas.Top、Canvas.Left等属性,在DockPanel下具有DockPanel.Dock属性。需要注意的是,附加属性的真实所有者不是TextBox,而是Grid、Canvas、DockPanel。

2. 附加属性的声明

附加属性的作用就是将属性与数据类型(宿主)解耦,让数据类型的设计更加灵活,其本质就是依赖属性,二者仅在注册和包装器上有一点区别。声明附加属性与依赖属性及其相似,唯一的不同就是注册附加属性使用的是名为RegisterAttached的方法,但参数却与使用Register方法无异。

class School:DependencyObject
{public static int GetGrade(DependencyObject obj){return (int)obj.GetValue(GradeProperty);}public static void SetGrade(DependencyObject obj,int value){obj.SetValue(GradeProperty,value);}public static readonly DependencyProperty GradeProperty=DependencyProperty.RegisterAttached("Grade",typeof(int),typepf(School),new UIPropertyMetaData(0));
}

3.附加属性的使用

如何消费附加属性呢?直接使用宿主的GetPropertyName和SetPropertyName将值赋值给某个类对象。值仍然被保存在Human实例的EffectiveValueEntry数组里,只是用于在数组里检索值的依赖属性(即附加属性)并不以Human类为宿主而是寄宿在School类里。

private void Button_Click(object sender,RoutedEventArgs e)
{Human human=new Human();School.SetGrade(human,6);int grade=School.GetGrade(human);MessageBox,Show(grade.ToStrin());
}

4. 附加属性的依赖绑定

  • 最后,因为附加属性其本质是依赖属性,所以它的值也可以使用Binding依赖在其他对象的数据上。
    在这里插入图片描述

相关文章:

  • 案例分享:同为科技与军工项目合作
  • 多层感知器的进化:从基础到并行门控——深入探讨MLP变体的实现、优化与风险
  • 深度解析SD-WAN在企业组网中的应用场景
  • [18] Opencv_CUDA应用之 基于颜色的对象检测与跟踪
  • java -jar
  • 我理解的文本表示模型
  • 【SpringBoot3.x】自定义开发通用SDK
  • [FlareOn5]Ultimate Minesweeper
  • 教程:LVM操作讲解
  • 【Android】记录在自己的AMD处理器无法使用Android studio 虚拟机处理过程
  • CBA认证-业务架构师认证的尚方宝剑
  • 【Android面试八股文】你能说一说View绘制流程与自定义View注意点吗?
  • 【python】OpenCV——Color Correction
  • 处理导入Excel文件过大导致Zip bomb detected的问题
  • HTML 事件
  • ECMAScript6(0):ES6简明参考手册
  • Effective Java 笔记(一)
  • EOS是什么
  • Go 语言编译器的 //go: 详解
  • Javascript设计模式学习之Observer(观察者)模式
  • JavaScript新鲜事·第5期
  • js对象的深浅拷贝
  • PHP CLI应用的调试原理
  • 程序员最讨厌的9句话,你可有补充?
  • 对象管理器(defineProperty)学习笔记
  • 番外篇1:在Windows环境下安装JDK
  • 如何用vue打造一个移动端音乐播放器
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • kubernetes资源对象--ingress
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​​​​​​​​​​​​​​Γ函数
  • ​水经微图Web1.5.0版即将上线
  • ###项目技术发展史
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (六)Flink 窗口计算
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (十八)Flink CEP 详解
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)jQuery 基础
  • .jks文件(JAVA KeyStore)
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET框架设计—常被忽视的C#设计技巧
  • @Autowired标签与 @Resource标签 的区别
  • [.NET]桃源网络硬盘 v7.4
  • []sim300 GPRS数据收发程序
  • [AIGC] MySQL存储引擎详解
  • [BZOJ4010]菜肴制作
  • [C#]winform使用onnxruntime部署LYT-Net轻量级低光图像增强算法