《深入浅出WPF》读书笔记之——属性

本文深入解析依赖属性的概念,包括其节省内存、支持绑定的特点,以及在WPF中的注册、使用和优先级规则。同时,对比了依赖属性与附加属性的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实例方法在内存中只有一个拷贝

CLR属性并不会增加内存的负担。属性仅仅是一个语法糖(syntax sugar),对类中字段的封装

 

依赖属性

  • 依赖属性是一种自己没有值,并能通过binding从数据源获取值(依赖在别人身上)的属性。

  • 拥有依赖属性的对象被称为依赖对象

  • 只有继承DependencyObject的类才可以拥有依赖属性

  • 优点

    • 节省内存开销

    • 属性值可以通过binding依赖在其它对象之上

 

依赖属性的声明

  • 注册依赖属性

    • 使用public static readonly 三个关键词声明

    • 依赖属性名称一般使用Property结尾

    • 使用DependencyProperty.Register注册

    • 依赖属性包装器

    • 严格来讲依赖属性的类型永远都是DependencyProperty。如上例中,string只是依赖属性的注册类型,但通常工作常称为依赖属性的类型

public static readonly DependencyProperty MyPropertyProperty
public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register("MyProperty",  typeof(string), typeof(MainWindow), new  PropertyMetadata(string.Empty));
        public string MyProperty
        {
            get { return (string)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }

依赖属性的机制

  • 所有的注册方法都是对私有方法RegisterCommon的调用,原型如下:

private static DependencyProperty RegisterCommon(string name,  Type propertyType, Type ownerType, PropertyMetadata  defaultMetadata, ValidateValueCallback validateValueCallback)
  • 所有的依赖属性都保存在一个hasttable中

private static Hashtable PropertyFromName = new Hashtable();
  • 在hashtable中使用name和所属类的类型组合生成的key做为在hashtable中的key(name的hashcode和所属类的类型的hashcode异或)

FromNameKey key = new FromNameKey(name, ownerType);
            public FromNameKey(string name, Type ownerType)
            {
                _name = name;
                _ownerType = ownerType;
                _hashCode = _name.GetHashCode() ^  _ownerType.GetHashCode();
            }
  • 在DependencyObject中维护一个依赖属性有效值的数组

private EffectiveValueEntry[] _effectiveValues;

 

  • 在GetValue方法中从这个数组中获取值

entry = _effectiveValues[entryIndex.Index];

 

  • 在SetValue中从添加或更新对应的值

依赖属性读取的优先级

依赖属性的对属性的读取是有优先级的,优先级依次为

  • WPF属性系统强制值

  • 由动画过程控制的值

  • 本地变量值(存储在_effectiveValues数组中)

  • 由上级元素的Template设置的值

  • 由隐式样式(Implicit Style)设置的值

  • 由样式触发器(Style Trigger)设置的值

  • 由模板触发器(Template Trigger)设置的值

  • 由样式设置器(Style Setter)设置的值

  • 由默认样式(DefaultStyle)设置的值,其实就是由主题(Theme)指定的样式

  • 从上级元素继承而来的值

  • 默认值(依赖属性的元数据metadata)

 

附加属性

  • 附加属性是依赖对象在某一个特定环境中(如Grid中),由于某种需求被附加的属性(Grid.Row等),

  • 附加属性往往定义在依赖对象“从属”的那个对象

  • 在使用Binding时和依赖属性没有任何区别

  • 声明方式:

    • 类型依然是依赖属性

    • 包装器和依赖属性有所区别

      • 是类的静态方法

      • 读取由Get和Set两个方法,而非属性包装器

      • 附加属性的使用针对类型而非类的实例,

    • 注册时也是调用RegisterCommon方法

        public static string GetMyProperty(DependencyObject obj)
        {
            return (string)obj.GetValue(MyPropertyProperty);
        }
        public static void SetMyProperty(DependencyObject obj,  string value)
        {
            obj.SetValue(MyPropertyProperty, value);
        }
        // Using a DependencyProperty as the backing store for  MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty  MyPropertyProperty =
            DependencyProperty.RegisterAttached("MyProperty",  typeof(string), typeof(MainWindow), new  PropertyMetadata(string.Empty));

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值