最近又要找工作,很多东西要复习。打算写下面试时的复习的东西做成一个系列,先从WPF开始

DependencyProperty

1. The diffirenc between DependencyProperty and CLR Property

 The CLR property is just a wrapper around private variables.

 The idea of DependencyProperty is to compute the value of property based on external inputs.

 

 Here is a simple prototype of DependyProperty

Public class DependencyProperty

{

    Internal static Dictionary<object, DependencyProperty> RegisteredDps=new Dictionary<object,DependencyProperty>();

    Internal string Name;

    Internal object Value;

    Internal object HashCode;

    Private DependencyProperty(string name,Type propertyType, Type ownerType, object defaultValue)

     {

          This.Name=name;

          This.Value=defaultValue;

          This.HashCode=name.GetHashCode^ownerType.GetHashCode;

    }

    Public static DependencyProperty Register(string name,Type propertyType, Type ownerType,object defaultValue)

    {

         DependencyProperty dp=new DependencyProperty(name,propertyType,ownerType,defaultValue);

         RegisterdDps.Add(dp.HashCode,dp);

        Return dp;

    }

}

 

Public class DependencyObject

{

     Public static readonly DependencyProperty NameProperty=DependencyProperty.Register(“name”,typeof(string),typeof(DependencyObject),string.empty);

 

     Public object GetValue(DependencyProperty dp)

     {

          Return DependencyProperty.RegistedDps[dp.HashCode].Value;

}

Public object SetValue(DependencyProperty dp,object value)

{

      DependencyProperty.RegistedDps[dp.HashCode].Value=value;

}

 

Public string Name

{

       get{return GetValue(NameProperty).ToString()}

      set{SetValue(NameProperty,value);}

}

}

All DependencyObjects share one DependencyProperty, if one object changed dp value, all the others will change.

So the DependencyObject Add effective conception

Improved DependencyObject with _effectiveValue

 

Public class DependencyProperty

{

     Internal static Dictionary<object, DependencyProperty> RegisteredDps=new Dictionary<object,DependencyProperty>();

   Internal string Name;

     Internal int Index;

   Internal object Value;

     Internal object HashCode;

   Private static int globalIndex=0;

  Private DependencyProperty(string name,Type propertyType, Type ownerType, object defaultValue)

     {

          This.Name=name;

          This.Value=defaultValue;

          This.HashCode=name.GetHashCode^ownerType.GetHashCode;

}

Public static DependencyProperty Register(string name,Type propertyType, Type ownerType,object defaultValue)

{

      DependencyProperty dp=new DependencyProperty(name,propertyType,ownerType,defaultValue);

    globalIndex++;

    dp.Index=globalIndex;

      RegisterdDps.Add(dp.HashCode,dp);

    Return dp;

}

}

 

 

Internal struct EffectiveValueEntry

{

       Internal int PropertyIndex{get;set;}

       Internal object Value{get;set;}

}

Public class DependencyObject

{

Private List<EffectiveValueEntry> effectiveValues=new List<EffectiveValueEntry>();

     Public static readonly DependencyProperty NameProperty=DependencyProperty.Register(“name”,typeof(string),typeof(DependencyObject),string.empty);

 

     Public object GetValue(DependencyProperty dp)

     {

          EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);

          If(effectiveValue.PropertyIndex!=0)

          {

                Return effectiveValue.Value;

}

Else

{

          Return DependencyProperty.RegistedDps[dp.HashCode].Value;

}

}

Public object SetValue(DependencyProperty dp,object value)

{

EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);

          If(effectiveValue.PropertyIndex!=0)

          {

                effectiveValue.Value=value;

}

      Else

      {

EffectiveValueEntry effectiveValue=new EffectiveValueEntry(){PropertyIndex=dp.Index; Value=value;}

}

      }

 

Public string Name

{

       get{return GetValue(NameProperty).ToString()}

      set{SetValue(NameProperty,value);}

}

}

Problem: Derived class can override field in parent class

Improved

Public class PropertyMetaData

{

         Public Type Type{get;set;};

         Public object Value{get;set;}

         Public PropertyMetaData(object defaultValue)

         {

                   This.Value=defaultValue;

}

}

 

Public class DependencyProperty

{

     Internal static Dictionary<object, DependencyProperty> RegisteredDps=new Dictionary<object,DependencyProperty>();

   Internal string Name;

     Internal int Index;

   Internal object Value;

     Internal object HashCode;

   Private static int globalIndex=0;

     Private List<PropertyMetaData> metaDataMap=new List<PropertyMetaData>();

Private PropertyMetaData defaultMetaData;

  Private DependencyProperty(string name,Type propertyType, Type ownerType, object defaultValue)

     {

          This.Name=name;

          This.Value=defaultValue;

          This.HashCode=name.GetHashCode^ownerType.GetHashCode;

          PropertyMetaData metadata=new PropertyMetaData(defaultValue){Type=ownerType};

          metaDataMap.Add(metaData);

          defaultMetaData=metadata;

}

Public static DependencyProperty Register(string name,Type propertyType, Type ownerType,object defaultValue)

{

      DependencyProperty dp=new DependencyProperty(name,propertyType,ownerType,defaultValue);

    globalIndex++;

    dp.Index=globalIndex;

      RegisterdDps.Add(dp.HashCode,dp);

    Return dp;

}

 

Public void OverrideMetaData(Type forType,PropertyMetaData metaData)

{

      metadata.Type=forType;

      metaDataMap.Add(metaData);

}

 

Public PropertyMetaData GetMetaData(Type type)

{

      PropertyMetaData metadata=metaDataMap.FirstOrDefault((i)=>type.isSubClassOf(i.Type));

      If(metadata==null)

           Return defaultMetaData;

      Else

           Return metadata;

}

}

 

 

Public class DependencyObject

{

Private List<EffectiveValueEntry> effectiveValues=new List<EffectiveValueEntry>();

     Public static readonly DependencyProperty NameProperty=DependencyProperty.Register(“name”,typeof(string),typeof(DependencyObject),string.empty);

 

     Public object GetValue(DependencyProperty dp)

     {

          EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);

          If(effectiveValue.PropertyIndex!=0)

          {

                Return effectiveValue.Value;

}

Else

{

          Return DependencyProperty.RegistedDps[dp.HashCode].GetMetaData(this.getType()).Value;

}

}

Public object SetValue(DependencyProperty dp,object value)

{

EffectiveValueEntry effectiveValue=effectiveValues.FirstOrDefault((i)=>i.PropertyIndex=dp.Index);

          If(effectiveValue.PropertyIndex!=0)

          {

                effectiveValue.Value=value;

}

      Else

      {

EffectiveValueEntry effectiveValue=new EffectiveValueEntry(){PropertyIndex=dp.Index; Value=value;}

}

      }

 

Public string Name

{

       get{return GetValue(NameProperty).ToString()}

      set{SetValue(NameProperty,value);}

}

}

Then we can define a new DependencyObject instance

Public class SubDenpendencyObject:DependencyObject

{

         Static SubDependencyObject()

         {

                   NameProperty.OverrideMetaData(typeof(SubDependencyProperty),new PropertyMetaData(“SubName”));

}

}

http://www.cnblogs.com/Zhouyongh/archive/2009/09/10/1564099.html

posted on 2014-02-25 11:34  carolinehan  阅读(845)  评论(0编辑  收藏  举报