zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    n-1位数
    关于VC预定义常量_WIN32,WIN32,_WIN64
    python中的闭包
    TCP粘包, UDP丢包, nagle算法
    C++中 explicit的用法
    为什么mysql索引要使用B+树,而不是B树,红黑树
    屏障和屏障属性
    带有超时的读写锁
    pthread_mutex_timedlock
    段错误以及调试方式
  • 原文地址:https://www.cnblogs.com/HelloMyWorld/p/2657889.html
Copyright © 2011-2022 走看看