之前我们所学的属性是这样设计的 [csharp] private Uri url; public Uri Url { get { return url; } set { url = value; } } [/csharp] 由于WPF中的依赖属性非常强大,所以它的属性应该这样设计 [csharp] public static readonly DependencyProperty url = DependencyProperty.Register("Imageurl", typeof(Uri), typeof(Pic), new PropertyMetadata(string.Empty)); public Uri Imageurl { get { return (Uri)GetValue(url); } set { SetValue(url, value); } } [/csharp] 除了写法复杂点,它的优势在哪里呢?首先,PropertyMetadata方法给属性了一个初值(当然在传统的属性设计中也很容易实现), 我们先看它的构造函数 [csharp] <pre>public PropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);</pre> [/csharp] 第一个给属性的默认值,第二个是一个回调函数,当属性的值改变时,就会调用这里面的函数,第三个还是一个回调函数,这个函数主要用来强制一个值,比如该属性的值必须在0-100之间,那么当给该属性赋值1000时,需要做相应的处理,就在这里。
Register还有一个参数ValidateValueCallback,它也是一个回调函数, 是该属性的“大门”,用来指示该属性是否有效, 返回值为bool类型,如果它设置为无效, 那么值改变,强制值的那些回调函数都不会执行。 总的来说,比传统的方法更强大,属性一旦定义好,就能够保证数据的正确。 下面来个完整的例子 [csharp] class Program { static void Main(string[] args) { SimpleDpClass sim = new SimpleDpClass(); sim.SimpleDP = 8; } } public class SimpleDpClass : DependencyObject { public static readonly DependencyProperty SimpleDpProperty = DependencyProperty.Register("SimpleDP", typeof(double), typeof(SimpleDpClass), new FrameworkPropertyMetadata((double)0.0, FrameworkPropertyMetadataOptions.None, new PropertyChangedCallback(OnValueChange), new CoerceValueCallback(CoerceValue)), new ValidateValueCallback(IsValidValue)); public double SimpleDP { get{return (double)GetValue(SimpleDpProperty);} set{SetValue(SimpleDpProperty,value);} } private static void OnValueChange(DependencyObject obj,DependencyPropertyChangedEventArgs e) { Console.WriteLine("当值改变时,需要做一些操作,就在这里{0}",e.NewValue); } private static object CoerceValue(DependencyObject obj,object value) { double myvalue=0; if ((double)value > 5) { myvalue = 10; } Console.WriteLine("对值进行限定,强制值: {0}", myvalue); return myvalue; } private static bool IsValidValue(object value) { Console.WriteLine("验证值是否通过,返回bool值,如果返回True表示严重通过,否则会以异常的形式暴露: {0}", value); return true; } } [/csharp] 接下来了解下监听属性 在这里,继承自DependencyObject的所有对象的属性都能够监听,有2种方法