(一)首先我们来看看普通的属性和依赖属性的定义方式:
【普遍属性】
{
private double _fontSize = 12;
public double FontSize { get { return _fontSize; } set{ _fontSize = value; } }
}
【依赖属性】
{
public static readonly DependencyProperty FontSizeProperty =
DependencyProperty.Register("FontSize", typeof(double), typeof(MyTextBlock), 12.0/*缺省值*/);
public double FontSize
{
get { return (double)base.GetValue(FontSizeProperty); }
set { base.SetValue(FontSizeProperty, value); }
}
}
第一点:要定义一个static readonly的类型为DependencyProperty的FontSizeProperty字段;
再有,依赖属性可以应用动画,双向绑定,Style,还可以从可视化树的祖先中继承值,等等很多好处。
我们来模拟一下这两个类的实现。
1. 先从简单的来:DependencyProperty类,代码很简单,如下:
{
private Type _propertyType;
private Type _ownerType;
private string _name;
private object _defaultValue;
public object DefaultValue { get { return _defaultValue; } }
public string Name { get { return _name; } }
private DependencyProperty(string name, Type propertyType, Type ownerType, object defaultValue)
{
_propertyType = _propertyType;
_ownerType = ownerType;
_name = name;
_defaultValue = defaultValue;
}
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, object defaultValue)
{
if (defaultValue.GetType() != propertyType)
{
throw new Exception(string.Format("the type of defaultValue is not {0}", propertyType.Name));
}
DependencyProperty dp = new DependencyProperty(name, propertyType, ownerType, defaultValue);
//再做一些其它的事情,好让dp能获得一些WPF的功能
//可能会用到 ownerType
return dp;
}
}
2. 接下来,模拟一下DependencyObject类的实现,代码不难,如下:
{
private IDictionary<DependencyProperty, object> _dict = new Dictionary<DependencyProperty, object>();
public void SetValue(DependencyProperty p, object val)
{
if (_dict.ContainsKey(p))
{
_dict[p] = val;
}
else
{
_dict.Add(p, val);
}
}
public object GetValue(DependencyProperty p)
{
//如果被动画控制,返回动画计算值。(可能会用到p.Name)
//如果有本地值,返回本地值
if(_dict.ContainsKey(p))
{
return _dict[p];
}
//如果有Style,则返回Style的值
//返回从可视化树中继承的值
//最后, 返回依赖属性的DefaultValue
return p.DefaultValue;
}
}
说明
3. 可以写一小段代码验证一下:如果没设置FontSize,则FontSize返回缺省值,代码很难,如下:
{
static void Main(string[] args)
{
//不设置txt的FontSize属性
MyTextBlock txt = new MyTextBlock();
Console.WriteLine(txt.FontSize);
//设置FontSize属性
txt.FontSize = 18;
Console.WriteLine(txt.FontSize);
}
}
最后,上面只是对DependencyProperty和DependencyObject的猜测。
如果你觉得讲得还是罗嗦,那就也写一篇吧。