最近又要找工作,很多东西要复习。打算写下面试时的复习的东西做成一个系列,先从WPF开始
DependencyProperty
- 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
l The 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);
【前言】
Blend自诞生那一天起就伴随这开发者如此的评价:
有VS还用Blend干啥,直接码代码就好了。
Blend会生成一堆垃圾无用代码,很不爽。
对于这类我只会在心里评价,当你并不真正了解一样事物的情况下,就给这个东西扣帽子,实在很不公平。
作为程序员首先要明白时间的宝贵和效率的重要性,更应了解各种效能工具,Blend便是其中一个,如果你仍然觉得学怎么用Blend纯粹是浪费时间,
那么恭喜你,后面的文章可以忽略了:-)
【本文讲述的内容】
使用blend为程序添加设计时的数据。
【本文适用的场景】
很多应用由于本身的性质决定了,其数据来源是远端网络,因此调整UI时非常不方便,多数情况调UI的过程是:
1、调整UI布局
2、运行程序
3、等待数据加载
4、数据加载完毕后看是否还有UI问题,如果有则goto 1
如此效率非常的低,本文介绍的方法可以将流程调整为:
1、添加设计时数据源
2、调整UI布局
3、调整UI布局
4、调整UI布局
省去联机调试,提高效率。
【正文】
一、实现思路
Blend本身提供了SampleData功能,此功能可以根据Model的定义自动生成一个SampleData文件,又提供了d:DataContext 和d:DesignData来指定设计时的DataContext。二者结合便可以实现前面说到的效果。
二、具体步骤
1、我们首先创建程序的Model和主页面的MainpageViewModel
Model:
ViewModel:
接下来打开blend找到Data选项卡,点击右方第一个按钮
这里看到三个选项,我们选择第三个,根据类来创建Sample Data:
接下来选择MainpageViewModel:
之后我们观察工程目录,会看到如下新添加的信息:多出了一个Xaml文件。
打开看一看,可以看到自动生成了如下数据,包括VM中定义的Title以及ModelList列表,并且自动为列表加入了随机的数据
看到这里可能读者会有一个疑问,SampleData会不会增大程序的包呢?
如果存在这个疑问说明你是个细心的读者,考虑很周全,那么我们看下这个SampleData文件的属性:
可以清楚的看到Build Action是DesignData Do not copy。也就是锁这个文件不会被打包的程序的安装包中。
最后一步:
在page中指定DataContext按下面的格式写:
在页面内容中加个简单的列表,定义简单的模版:
最后我们Build一下。再看VS的编辑器里面Sample数据就显示出来了
【更多功能】
我们甚至可以在Blend的Data选项卡下,每个属性最右面的按钮中选择数据的格式,如下图:
SampleData文件中的数据便会根据选择的格式重新生成对应的数据了。:-)
【总结】
以上办法非常简单,并且十分遍历,极大的提高了开发效率,因此推荐给大家,如有任何疑问欢迎加入
WP交流群:182659848
本文链接:http://www.cnblogs.com/tianhonghui/p/3566274.html,转载请注明。
没有评论:
发表评论