WPF/Silverlight ->DependencyProperty

之前我们所学的属性是这样设计的 [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种方法
  1. 继承自你要监听属性的类,重写元数据,比如我想监听TextBox的Background属性,那么[csharp] <pre>public class MyTextBox : TextBox { public MyTextBox():base() { } static MyTextBox() { BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(bkCallback))); } private static void bkCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { MessageBox.Show("改变了颜色"); } }</pre> [/csharp] 这样就监听了背景颜色
  2. 用于某一个控件[csharp] <pre>public MainWindow() { InitializeComponent(); DependencyPropertyDescriptor des = DependencyPropertyDescriptor.FromProperty(Button.BackgroundProperty, typeof(Button)); des.AddValueChanged(mybutton, new EventHandler(buttonbkchange)); } private void buttonbkchange(object sender, EventArgs e) { MessageBox.Show("Button BackgroundChange"); }</pre> [/csharp]
  3. 完整的例子[csharp] <pre>public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DependencyPropertyDescriptor des = DependencyPropertyDescriptor.FromProperty(Button.BackgroundProperty, typeof(Button)); des.AddValueChanged(mybutton, new EventHandler(buttonbkchange)); } private void buttonbkchange(object sender, EventArgs e) { MessageBox.Show("Button BackgroundChange"); } private void Button_Click(object sender, RoutedEventArgs e) { mybutton.Background = Brushes.Blue; myTextBox.Background = Brushes.Green; } } public class MyTextBox : TextBox { public MyTextBox():base() { } static MyTextBox() { BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(bkCallback))); } private static void bkCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { MessageBox.Show("改变了颜色"); } }</pre> [/csharp] 有关WPF属性的基本介绍就到这里,有更加详细的资料在这儿http://www.cnblogs.com/KnightsWarrior/archive/2010/08/27/1809739.html
posted @ 2012-08-15 11:39  UncleNull  阅读(408)  评论(0编辑  收藏  举报