Silverlight 依赖属性与附加属性

依赖属性(Dependency Property)

依赖属性是存储于基类DependencyObject中的一个键值配对字典中的。它并没有存储在所属的类中,所以不会每次都去重新创建一个属性默认值占用内存。

 

#region 设置一个X坐标属性       
 public double X       
 {            
get { return (double)GetValue(XProperty); }            
set { SetValue(XProperty, value); }        }       
 // 创建一个名为X的依赖属性,并且设置这个依赖属性X变化的时候,让rectangle1控件位置也变化。       
 public static readonly DependencyProperty XProperty =            
DependencyProperty.Register("X", typeof(double), typeof(Rectan), new PropertyMetadata(OnXChanged));  
      private static void OnXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)    
    {            Rectan rec = d as Rectan;          
  rec.rectangle1.SetValue(Canvas.LeftProperty, e.NewValue);    
    }       
#endregion
注意在OnXChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)函数中处理在依赖属性变化时进行的操作。在本例中改变rectangle1矩形框的位置。注册好了依赖属性之后我们可以通过XAML方式和CS代码方式来控制自定义控件类的依赖属性分别如下:

        XAML方式控制依赖属性:

  <uc:Rectan  X="15"  x:Name="Uil" Width="105" Height="45"  HorizontalAlignment="Left" VerticalAlignment="Top"></uc:Rectan>

 

      this.Ikd.SetValue(Rectan.XProperty, 150.0);   
          

在这里主要是通过DependencyProperty.Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);函数注册依赖属性的。在OnXChanged()函数中我们可以处理当属性值变化的时候需要进行的逻辑操作。

       
// 摘要:
       
//     使用属性的指定属性名称、属性类型、所有者类型和属性元数据注册依赖项属性。
       
// 参数:
       
//   name:
       
//     要注册的依赖项对象的名称。
       
//   propertyType:
       
//     属性的类型。
       
//   ownerType:
       
//     正注册依赖项对象的所有者类型。
       
//   typeMetadata:
       
//     属性元数据实例。实例中可以包含一个 System.Windows.PropertyChangedCallback 实现引用。
       
// 返回结果:
       
//     一个依赖项对象标识符,应使用它在您的类中设置 public static readonly 字段的值。随后可以在您自己的代码以及任何第三方用户代码中使用该标识符在将来引用该依赖项属性,用于某些操作,比如以编程方式设置该属性的值,或是在代码中附加
       
//     System.Windows.Data.Binding。

       
publicstatic DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);

 属性的存取

  和CLR属性不同,依赖属性不是直接对私有变量的操纵,而是通过GetValue和SetValue的方法来操作属性值的

寻值逻辑

  CLR属性在获取值的时候是直接读取成员变量值返回的,而依赖属性在使用的时候是通过GetValue函数的调用来获取属性的值。实际上,GetValue内部做的事情可不止是简单的读取字典里头存放的值。他还有寻值逻辑。如下图所示:

 当你调用GetValue去读取一个依赖属性的值的时候,Silverlight的属性系统会首先从动画系统中查找当前是否有作用在此依赖属性上的动画,如果有,则返回此动画值。从这里也可以看出,依赖属性是Silverlight实现动画机制的基础。注意,如果动画已经停止了,并且没有设置FillBehavior=HoldEnd的话,那么Silverlight就不会返回此动画值。

  如果读不到动画值,那么Silverlight就会尝试读取本地值。本地值有几种类型,一种是用户通过代码或者Xaml直接设定的值。一种是通过资源绑定得到的值,最后一种是通过数据绑定得到的值。这些都被视为本地值。

如果还是读取不到,那么就继续尝试读取控件模板和样式中设置的值。

  如果所有这些值都读取失败,那么Silverlight属性系统就会返回该依赖属性的默认值。当我们注册依赖属性的时候,可以传入一个 PropertyMetaData对象,这个对象包含了此依赖属性的默认值和值变更通知回调函数。如果注册的时候没有传入默认值,则对于引用类型的依赖属性,返回null,对于字符串,返回String.Empty,对于值类型,则返回一个以默认值初始化的实例。

  这里需要对集合类型特别注意,由于通过PropertyMetaData传入的默认值是所有类实例共享的,因此,一定要在类构造函数中显式传入集合的实例。

可能正是因为Silverlight的依赖属性在获取值的时候需要从多个地方去读取值,而不是像CLR属性一样,直接从成员变量中读取值,所以才被称之为“依赖”属性。

 

附加属性(Attached Property)

附加属性是一种特殊的依赖属性,是全局依赖属性,它的注册方式是DependencyProperty.RegisterAttached();参数和依赖属性的注册参数相同。

 

 

posted @ 2011-12-08 14:04  好佳伙  阅读(864)  评论(0)    收藏  举报