WPF入门教程系列十一——依赖属性(一)

1、依赖属性基本介绍 编程

  本篇开始学习WPF的另外一个重要内容依赖属性。函数

     你们都知道WPF带来了不少新的特性,其中一个就是引入了一种新的属性机制——依赖属性。依赖属性出现的目的是用来实现WPF中的样式、自动绑定及实现动画等特性。依赖属性的出现是WPF这种特殊的呈现原理派生出来的,与.NET普通属性不一样的是,依赖属性的值是依靠多个提供程序来判断的,而且其具备内建的传递变动通知的能力。学习

     依赖属性基本应用在了WPF的全部须要设置属性的元素。依赖属性根据多个提供对象来决定它的值 (能够是动画、父类元素、绑定、样式和模板等),同时这个值也能及时响应变化。动画

     依赖属性就是能够本身没有值,并可以经过Binding从数据源获 取值(依赖在别人身上)的属性。拥有依赖属性的对象被称为“依赖对象”。依赖项属性的重点在于“依赖”二字,既然是依赖了,也就是说:依赖项属性的值的改变过程必定与其它对相关,不A依赖B就B依赖A,或者相互依赖。spa

 

     说白了,所谓依赖,主要应用在如下地方:双向绑定

     一、双向绑定。有了这个,依赖项属性不用写额的代码,也不用实现什么接口,它自己就俱备双向绑定的特性,好比,我把员工对象的姓名绑定到摇文本框,一旦绑定,只要文本框中的值发生改变,依赖项属性员工姓名也会跟着变化,反之亦然;orm

     二、触发器。这个东西在WPF中很重要,好比,一个按钮背景是红色,我想让它在鼠标停留在它上面是背景变成绿色,而鼠标一旦移开,按钮恢复红色。对象

若是在传统的Windows编程中,你必定会想办法弄一些事件,或者委托来处理,还要写一堆代码。告诉你,有了依赖项属性,你将一行代码都不用写,全部的处理均由WPF属性系统自动处理。而触发器只是临时改变属性的值,当触完成时,属性值自动被“还原”。blog

     三、附加属性。附加属性也是依赖项属性,它能够把A类型的的某些属性推迟到运行时根据B类型的具体状况来进行设置,并且能够同时被多个类型对象同时维护同一个属性值,但每一个实例的属性值是独立的。继承

     四、A属性改变时,也同时改变其它属性的值,如TogleButton按下的同时,弹出下拉框。

 

     与传统的CLR属性和面向对象相比依赖属性有不少新颖之处,其中包括:

      一、新功能的引入:加入了属性变化通知,限制、验证等等功能,这样就可使咱们更方便的实现咱们的应用,同时也使代码量大大减小了,许多以前不可能的功能均可以轻松的实现了。
      二、 节约内存:在WinForm等项目开发中,你会发现UI控件的属性一般都是赋予的初始值,为每个属性存储一个字段将是对内存的巨大浪费。WPF依赖属性 容许对象在被建立的时候并不包含用于存储数据的空间(即字段所占用的空间)、只保留在须要用到数据的时候可以得到默认值。借用其它对象的数据或者实 时分配空间的能力----这种对象称为依赖对象而他这种实时获取数据的能力则依靠依赖属性来实现。在WPF开发中,必须使用依赖对象做为依赖属性的宿主, 使两者结合起来,才能造成完整的Binding目标被数据所驱动。。
      三、支持多个提供对象:咱们能够经过多种方式来设置依赖属性的值。同时其内部能够储存多个值,配合Expression、Style、Animation等能够给咱们带来很强的开发体验。
  在.NET当中,对于属性是你们应该很熟悉,封装类的字段,表示类的状态,编译后被转化为对应的get和set方法。属性能够被类或结构等使用。 一个简单的属性以下,也是咱们经常使用的写法:

 

public class Student

    {

        string m_Name;

 

        public string Name

        {

            get { return m_Name; }

            set { m_Name = value; }

        }

        static Student()

        {

       

        }

 

 

    }

 

     依赖属性与普通的.NET属性的区别是普通的.NET属性定义只须要定义其set和get区块的赋值与设置。那么依赖属性应该怎么定义呢?依赖属性和属性到底有什么区别和联系呢?其实依赖属性的实现也很简单,按如下步骤作就能够了:

     第一步: 让本身的类继承自 DependencyObject基类。在WPF中,几乎全部的UI元素都继承自DependencyObject,这个类封装了对依赖属性的存储及 访问等操做,使用静态类型与依赖属性的内部存储机制相关。WPF处理依赖属性再也不像普通.NET属性那样将属性值存储到一个私有变量中,而是使用一个字典 型的变量来存放用户显示设置的值。

     第二步:依赖属性的定义必须使用 public static 声明一个 DependencyProperty的变量,而且有一个Property做为后缀,该变量才是真正的依赖属性 。例以下面的代码定义了一个依赖属性NameProperty:

 

 public static readonly DependencyProperty NameProperty;

 

     第三步:在静态构造函数中向属性系统注册依赖属性,并获取对象引用。依赖属性是经过调用DependencyProperty.Register静态方法建立,该方法须要传递一个属性 名称,这个名称很是重要,在定义控件Style和Template的时候,Setter的Property属性填入的值就是注册依赖属性时使用的名称。propertyType指明了依赖属性实际的类型,ownerType指明了是哪一个类注册了此依赖属性,最后typeMetadata存放了一些依赖属 性的元信息,包括依赖属性使用的默认值,还有属性值发生变动时的通知函数。例如,下面的代码注册了依赖属性。

 

NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student),  new PropertyMetadata("名称", OnValueChanged));

 

     第四步:在前面的三步中,咱们完成了一个依赖属性的注册,那么咱们怎样才能对这个依赖属性进行读写呢?答案就是提供一个依赖属性的实例化包装属性,经过这个属性来实现具体的读写操做。和CLR属性不一样,依赖属性不是直接对私有变量的操纵,而是经过GetValue()和SetValue()方法来操做属性值的,可使用标准的.NET属性定义语法进行封装,使依赖属性能够像标准属性那样来使用,代码以下。

  public string Name

        {

            get { return (string)GetValue(NameProperty); }

            set { SetValue(NameProperty, value); }

        }

 

 

根据前面的四步操做,咱们就能够写出下面的代码:

 

public class Student : DependencyObject 

    {

        //声明一个静态只读的DependencyProperty字段

        public static readonly DependencyProperty NameProperty;

 

        static Student()

        {

            //注册咱们定义的依赖属性Name

            NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student),

                new PropertyMetadata("名称", OnValueChanged));

        }

 

        private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)

        {

            //当值改变时,咱们能够在此作一些逻辑处理

        }

 

        //属性包装器,经过它来读取和设置咱们刚才注册的依赖属性

        public string Name

        {

            get { return (string)GetValue(NameProperty); }

            set { SetValue(NameProperty, value); }

        }

 

}

 

 

     总结:咱们通常.NET属性是直接对类的一个私有属性进行封装,因此读取值的时候,也就是直接读取这个字段;而依赖属性则是经过调用继承自DependencyObject的GetValue()和SetValue来进行操做,它实际存储在DependencyProperty的一个IDictionary的键-值配对字典中,因此一条记录中的键(Key)就是该属性的HashCode值,而值(Value)则是咱们注册的DependencyProperty。

相关文章
相关标签/搜索