在WPF中,依赖属性和附加属性之间有什么区别
发布网友
发布时间:2022-04-08 01:51
我来回答
共2个回答
懂视网
时间:2022-04-08 06:12
比如:我们查看DataGridColumnHeader的Content依赖属性
1.我们用到的windbg的命令有:!do, !da -details, .formats 2.利用!do查看依赖对象的成员变量, 找到具体依赖属性的地址0:000> !do 00000000039a71d8Name: System.Windows.Controls.Primitives.DataGridColumnHeaderMethodTable: 000007fee7e58090EEClass: 000007fee7885bd8Size: 384(0x180) bytesFile: C:WindowsMicrosoft.NetassemblyGAC_MSILPresentationFrameworkv4.0_4.0.0.0__31bf3856ad364e35PresentationFramework.dllFields: MT Field Offset Type VT Attr Value Name000007fef3f2eb00 4000db0 8 ...eading.Dispatcher 0 instance 0000000002dd4e68 _dispatcher000007fef3f3bb88 4001321 10 ...endencyObjectType 0 instance 000000000308a530 _dType000007fef7825ac8 4001322 18 System.Object 0 instance 0000000000000000 _contextStorage000007fef3f3e898 4001323 20 ...ctiveValueEntry[] 0 instance 00000000042efb08 _effectiveValues000007fef7847b70 4001324 28 System.UInt32 1 instance 3680277 _packedData000007fef3f33708 400131f 7c0 ...ependencyProperty 0 static 0000000002dd5ef0 DirectDependencyProperty---------------------省略部分----000007fef3f33708 40002ca 950 ...ependencyProperty 0 static 0000000002dfd820 ContentProperty0000000000000000 40002cb 958 0 static 0000000002dfd908 HasContentPropertyKey000007fef3f33708 40002cc 960 ...ependencyProperty 0 static 0000000002dfd948 HasContentProperty000007fef3f33708 40002cd 968 ...ependencyProperty 0 static 0000000002dfdb00 ContentTemplateProperty000007fef3f33708 40002ce 970 ...ependencyProperty 0 static 0000000002dfdc80 ContentTemplateSelectorProperty
3.利用!do命令查看依赖属性的成员变量值, 比如:0:000> !do 0000000002dfd820Name: System.Windows.DependencyPropertyMethodTable: 000007fef3f33708EEClass: 000007fef3dd7550Size: 88(0x58) bytesFile: C:WindowsMicrosoft.NetassemblyGAC_MSILWindowsBasev4.0_4.0.0.0__31bf3856ad364e35WindowsBase.dllFields: MT Field Offset Type VT Attr Value Name000007fef7826970 400133c 8 System.String 0 instance 0000000002dfd630 _name000007fef78282f8 400133d 10 System.Type 0 instance 0000000002d444b0 _propertyType000007fef78282f8 400133e 18 System.Type 0 instance 0000000002dfab80 _ownerType000007fef3f312a8 400133f 20 ....PropertyMetadata 0 instance 0000000002dfd7c0 _defaultMetadata000007fef3f31088 4001340 28 ...dateValueCallback 0 instance 0000000000000000 _validateValueCallback000007fef3f3e750 4001341 30 ...ndencyPropertyKey 0 instance 0000000000000000 _readOnlyKey000007fef4194818 4001342 40 System.Int32 1 instance 4194530 _packedData000007fef3f3e408 4001343 48 ....InsertionSortMap 1 instance 0000000002dfd868 _metadataMap000007fef3f30fc8 4001344 38 ...erceValueCallback 0 instance 0000000000000000 _designerCoerceValueCallback000007fef7825ac8 400133b 808 System.Object 0 static 0000000002d72000 UnsetValue000007fef3f3c6c0 4001345 800 ...ty, WindowsBase]] 1 static 0000000012d5bb10 RegisteredPropertyList000007fef7831c38 4001346 810 ...ections.Hashtable 0 static 0000000002d6f3d8 PropertyFromName000007fef782c858 4001347 5c8 System.Int32 1 static 868 GlobalIndexCount000007fef7825ac8 4001348 818 System.Object 0 static 0000000002d6f430 Synchronized000007fef78282f8 4001349 820 System.Type 0 static 0000000002d68808 NullableType
4.利用.formats 得到依赖属性, 分2步 1)利用.formats 0n得到_packedData十六进制 2) 去掉高位,Decimal描述的就是依赖属性在依赖对象中的存储索引
如下:0:000> .formats 0n4194530Evaluate expression: Hex: 00000000`004000e2 Decimal: 4194530 Octal: 0000000000000020000342 Binary: 00000000 00000000 00000000 00000000 00000000 01000000 00000000 11100010 Chars: .....@.. Time: Wed Feb 18 21:08:50 1970 Float: low 5.87779e-039 high 0 Double: 2.07237e-3170:000> .formats 00e2Evaluate expression: Hex: 00000000`000000e2 Decimal: 226 Octal: 0000000000000000000342 Binary: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 11100010 Chars: ........ Time: Thu Jan 01 08:03:46 1970 Float: low 3.16693e-043 high 0 Double: 1.11659e-321
可知ContentProperty依赖属性在DataGridColumnHeader中的索引为226
5. 根据第4步的index,从第2步依赖对象的_effectiveValues 得到依赖属性的具体值,分3步: 1)利用!da -details 查看_effectiveValues 数组所有元素的值 2)查看每个元素,根据_propertyIndex (即第4步得到的Decimal值)确定依赖属性 3)利用!do命令查看元素的_value成员的值
比如:
0:000> !da -details 00000000042efb08Name: System.Windows.EffectiveValueEntry[]MethodTable: 000007fef3f3e898EEClass: 000007fef3e0c8a0Size: 408(0x198) bytesArray: Rank 1, Number of elements 24, Type VALUETYPEElement Methodtable: 000007fef3f36120[0] 00000000042efb18 Name: System.Windows.EffectiveValueEntry MethodTable: 000007fef3f36120 EEClass: 000007fef3dd8c90 Size: 32(0x20) bytes File: C:WindowsMicrosoft.NetassemblyGAC_MSILWindowsBasev4.0_4.0.0.0__31bf3856ad364e35WindowsBase.dll Fields: MT Field Offset Type VT Attr Value Name 000007fef7825ac8 400136e 0 System.Object 0 instance 0000000002e1c5d8 _value 000007fef7830940 400136f 8 System.Int16 1 instance 3 _propertyIndex 000007fef41949d0 4001370 a System.Int16 1 instance 2 _source
--------------------------------省略部分------------------------------
[15] 00000000042efc08 Name: System.Windows.EffectiveValueEntry MethodTable: 000007fef3f36120 EEClass: 000007fef3dd8c90 Size: 32(0x20) bytes File: C:WindowsMicrosoft.NetassemblyGAC_MSILWindowsBasev4.0_4.0.0.0__31bf3856ad364e35WindowsBase.dll Fields: MT Field Offset Type VT Attr Value Name 000007fef7825ac8 400136e 0 System.Object 0 instance 00000000042efca0 _value 000007fef7830940 400136f 8 System.Int16 1 instance 226 _propertyIndex 000007fef41949d0 4001370 a System.Int16 1 instance 65 _source
可知ContentProperty为_effectiveValues的第16个元素, 其值存储在_value中
0:000> !do 00000000042efca0 Name: System.Windows.ModifiedValueMethodTable: 000007fef3f40d58EEClass: 000007fef3e0d000Size: 48(0x30) bytesFile: C:WindowsMicrosoft.NetassemblyGAC_MSILWindowsBasev4.0_4.0.0.0__31bf3856ad364e35WindowsBase.dllFields: MT Field Offset Type VT Attr Value Name000007fef7825ac8 4001387 8 System.Object 0 instance 0000000000000000 _baseValue000007fef7825ac8 4001388 10 System.Object 0 instance 0000000000000000 _expressionValue000007fef7825ac8 4001389 18 System.Object 0 instance 0000000000000000 _animatedValue000007fef7825ac8 400138a 20 System.Object 0 instance 0000000002d93618 _coercedValue
6.根据第5步中的成员_coercedValue得到依赖属性的具体值,大功告成!
0:000> !do 0000000002d93618Name: System.StringMethodTable: 000007fef7826970EEClass: 000007fef73aeec8Size: 36(0x24) bytesFile: C:WindowsMicrosoft.NetassemblyGAC_64mscorlibv4.0_4.0.0.0__b77a5c561934e089mscorlib.dllString: 导入数据源Fields: MT Field Offset Type VT Attr Value Name000007fef782c858 40000ed 8 System.Int32 1 instance 5 m_stringLength000007fef782b398 40000ee c System.Char 1 instance 5bfc m_firstChar000007fef7826970 40000ef 10 System.String 0 shared static Empty >> Domain:Value 00000000007f85a0:0000000002d41420 <<
版权声明:本文为博主原创文章,欢迎转载,仅请署名
Windbg调试WPF的依赖属性
标签:wpf dependencyproperty dependencyobject windbg 依赖属性
热心网友
时间:2022-04-08 03:20
依赖的由来:
在面向对象的世界里,属性大量存在,比如Button,就大约定义了70-80个属性来描述其状态。那么属性的不足又在哪里呢?
当然,所谓的不足,要针对具体环境来说。拿Button来讲,它的继承树是Button->ButtonBase->ContentControl->Control->FrameworkElement->UIElement->Visual->DependencyObject->…
每次继承,父类的私有字段都被继承下来。当然,这个继承是有意思的,不过以Button来说,大多数属性并没有被修改,仍然保持着父类定义时的默认值。通常情况,在整个Button对象的生命周期里,也只有少部分属性被修改,大多数属性一直保持着初始值。每个字段,都需要占用4K等不等的内存,这里,就出现了期望可以优化的地方:
因继承而带来的对象膨胀。每次继承,父类的字段都被继承,这样,继承树的低端对象不可避免的膨胀。
大多数字段并没有被修改,一直保持着构造时的默认值,可否把这些字段从对象中剥离开来,减少对象的体积
有了以上的背景,依赖就出现了,微软设计了DependencyProperty类, 里面有着 public static DependencyProperty Register(string name, Type propertyType, Type ownerType, object defaultValue)方法来注册属性。然后又定义了一个DependencyObject的基类来消费这个属性。这样继承自DenpendencyObject的类就可以注册自己的依赖属性,属性是自己注册的,其实严格的说并不是自己的,所以节省了空间。注册的属性在DependencyProperty里面通过一个hash( internal static Dictionary<object, DependencyProperty> RegisteredDps = new Dictionary<object, DependencyProperty>())来维护。注册过的属性都存在这个hash里面。自此依赖我感觉的由来就清楚了,不是自己的属性,而是此属性要依赖于DependencyProperty的。
依赖解释好了,那属性呢?其实属性就是对外暴漏接口罢了,注册依赖属性后就是给依赖属性赋值(set),或者问依赖属性取值(get),这些操作封装到了DependencyObject类里面,所有用过的属性的值都通过 List<EffectiveValueEntry> _effectiveValues = new List<EffectiveValueEntry>()来存储和维护。这样就不会污染最初的默认value。这里也就实现了某个属性变化的过程都可以DependencyObject里面的effectiveValues找到痕迹,这样也就支持了动画。获取和赋值都是通过EffectiveValueEntry这个入口来获得的。就此依赖属性设计好了。
这样的设计听好了,但是我们想要求子类也有自己的默认属性,比如很多控件都有Name属性,但有时候并不希望大家的默认值是一样的,但是有共用同一个DP。这该怎么解决呢?
要想支持不同的默认值,那么内部就要维护一个对应不同DependencyObjectType的一个List,可以根据传入的DependencyObject的类型来读取它对应的默认值。DP内需要维护一个自描述的List,按照微软的命名规则,添加新的类型属性元数据(PropertyMetadata)。其实在DependencyProperty里面添加了private List<PropertyMetadata> _metadataMap = new List<PropertyMetadata>();来维护元数据,实现对默认值的修改。
附加属性之我见:说白了就是依赖属性的改造,只是封装不同,区别在于附加二字,其实就是有些对象不具备某些属性,有些对象具备这些属性,那么具备这些依赖属性的对象就可以某些属性附加到不具备这些属性的对象上。比如人没有年级,班级的属性,而学校有年级班级的属性,但是当人在学校学习的时候就具备了班级年级的属性,这个时候学校这个对象就可以附加给人这个对象班级年级的属性。这就是附加属性。
回想下依赖属性,依赖属性是对一个对象来说的,这个对象可以注册依赖属性,以后这个对象就具备了这个属性。而附加属性是对两个对象来说的,一个是附加对象,一个是被附加对象。是不是可以这样理解,附加对象给被附加对象注册了一个依赖属性罢了。但这个依赖属性依靠附加对象操作。自己的理解不知道正确与否。
在WPF中,依赖属性和附加属性之间有什么区别
附加属性之我见:说白了就是依赖属性的改造,只是封装不同,区别在于附加二字,其实就是有些对象不具备某些属性,有些对象具备这些属性,那么具备这些依赖属性的对象就可以某些属性附加到不具备这些属性的对象上。比如人没有年级,班级的属性,而学校有年级班级的属性,但是当人在学校学习的时候就具备了班...
C#/WPF高手进!关于依赖属性、附加属性等声明方式以及静态构造函数、静态...
WPF里的依赖属性 都是 继承 自 DependencyObject。对于 依赖属性 和 附加依赖属性的 那个静态量,你可以当做一个Key。在 DependencyObject 的内部有一个 类似与字典的东西,通过当前这个Key去取里面的取,得到你最终的属性值。你可以去微软官网上查看源码。定义依赖属性的时候,一般我们都会定义一个 属性...
简单点说:wpf中依赖项属性与普通属性的异同
不是。依赖属性是要注册的,而且通常都是改变时候会触发类的响应。class a { int r;这是个属性,但是改变的时候不会发生什么,只是r的值变了。但是如果是一个控件的长,它改变的时候就会直接在ui表现出来,会立刻改变空间的长,这就是依赖属性,这样理解比较形象。} ...
wpf重写ui什么意思
在wpf里重写UI可以完成两件事:1、添加附加属性 2、添加额外的事件 3、改变UI外观 可能这么说有点太抽象了,我来举个例子说明下:比方说就拿一个方块来说,我现在有个需求就是在连击三下的时候实现一个什么逻辑。那么程序员就可以重写这个方块,在继承类里创建 自己的事件。然后在使用的时候就可以...
WPF专业编程指南目录
第2章深入解析XAML语言,它是一种界面描述语言,包括根元素、命名空间、代码分离技术等。子元素、依赖属性、附加属性以及各种标记扩展,如静态资源扩展、动态资源扩展等,都逐一讲解。本章以详细的实例展示了XAML的使用。第3章聚焦WPF排版,讲解了堆积面板、WrapPanel、DockPanel和Grid的基本概念与应用。如何...
...里面,附加依赖项 和 附加库目录的使用有什么区别?
3附加依赖项 是指输入项,如某个.LIB文件。附加库目录 是你用 #pragma comment(lib,"a.lib")的时候;此时就搜索a.lib的路径列表就包含这个路径。若是要链接一个lib,直接把它添加到附加依赖项 和 把它所在的目录添加到附加库目录里面有什么区别?添加到附加依赖项 :你的LIB文件被真正包含进来了。...
无双大蛇3附加属性怎么选介绍_无双大蛇3附加属性怎么选是什么
除了这五种常见属性,其他如进击猛袭等属性在测试中效果一般,可能因武器面板较低而表现不佳。一些可能会导致PS4性能问题的属性,如奥丁的C4满蓄力,也不被推荐。玩家可以根据自己的实际需求和游戏体验来决定是否使用。总的来说,选择武器属性时,应优先考虑“斩”和“炎”,而其他属性则视具体情况而定...
JSP.NET 和ASP.NET有什么区别
HTML代码主要负责描述信息的显示样式,而程序代码则用来描述处理逻辑.普通的 HTML页面只依赖于Web服务器,而ASP ,PHP,JSP页面需要附加的语言引擎分析和执行程序代码.程序代码的执行结果被重新嵌入到HTML代码中,然后一起发送给浏览器.ASP ,PHP,JSP三者都是面向Web服务器的技术,客户端浏览器不需要任何附加的...
...适合什么类型的英雄,这三个装备之间有什么区别?吸血...
属性需要开发才能达到最大化。死亡后附加属性会削减三分之一。破败:优点,多元化,多变,后期输出颇为可观,有控制有额外吸血技能,有攻速加成,散件不贵,出装较为平滑,小件前期就能有额外技能缺点,攻击加成最低,最贵,出装繁琐,前期难堪大用,惨遭削弱。除非个别英雄没有人会在前期出这玩意。后期需求也不大。九头蛇:...
请问高手如何区分百货商场与购物中心的区别 两者之间不同点有哪些?
一、客群定位不同 传统百货均有明确的客群定位,而划分定位的依据主要是收入和阶层,因此高端百货、中高端百货、低端百货的定位与百货内商品品类的价格定位基本一致,因此客单价、提袋率等是衡量百货公司业绩的重要指标之一,而购物中心却对这些指标的依赖度不同。购物中心的客群定位是以年龄、喜好、消费...