依赖项属性

来源:互联网 发布:视频播放加速软件 编辑:程序博客网 时间:2024/06/03 16:52

依赖项属性在WPF界面中扮演着核心角色,是WPF很多重要功能的基础,从原理上讲,它劫持了windows窗口的消息循环,使得窗口能实时应对属性变化进行重绘,并且从一个属性影响到其他属性
一。注册依赖项
1.定义依赖项属性
(所有的依赖项都应设定成static readonly并在静态构造函数中赋值)

        public static readonly DependencyProperty RedColorProperty;

2.属性包装器

        public int RedColor        {            set { SetValue(RedColorProperty, value); }            get { return (int)GetValue(RedColorProperty); }        }

3.静态构造函数中设定FrameworkPropertyMetadata

            FrameworkPropertyMetadata meta0 =                 new FrameworkPropertyMetadata(                0/*默认值*/,                FrameworkPropertyMetadataOptions.AffectsRender/*参数flg*/,                RGBColorPropertyChanged, //changed回调                RGBColorCoerce);//修正回调

4.赋值注册依赖项

            RedColorProperty=DependencyProperty.Register(                "RedColor"/*属性名*/,                typeof(int)/*属性类型*/,                typeof(MyButton)/*父类型*/,                meta0/*PropertyMetadata*/,                 IsColorValid/*验证回调*/);

5.回调函数

        //属性变化时回调        private static void RGBColorPropertyChanged(            DependencyObject d,DependencyPropertyChangedEventArgs e)        {            MyButton bt = d as MyButton;            if(bt!=null)            {                bt.Foreground = new SolidColorBrush(Color.FromRgb((byte)bt.RedColor, (byte)bt.GreenColor, (byte)bt.BlueColor));            }        }        //属性变化前验证前回调以修正属性值        private static object RGBColorCoerce(            DependencyObject d, object value)        {            int colorvalue = (int)value;            if (colorvalue > 255) return 255;            else if (colorvalue < 0) return 0;            else return colorvalue;        }        //属性变化前验证,判断是否合法,合法返回true        private static bool IsColorValid(object value)        {            int colorvalue = (int)value;            if (colorvalue > 255 || colorvalue < 0) return false;            return true;        }

完整示例

        <local:MyButton Grid.Row="0" FontSize="72"  RedColor="210" GreenColor="10" BlueColor="10">            <sys:DateTime>3/4/2016 3:02 PM</sys:DateTime>        </local:MyButton>
using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using System.Windows;//DependencyProperty定义必要namespace San13DramaEditor{    public class MyButton : Button    {        protected override void OnClick()        {            /*写入的代码*/            base.OnClick();        }        //定义依赖项属性        public static readonly DependencyProperty RedColorProperty;        public static readonly DependencyProperty GreenColorProperty;        public static readonly DependencyProperty BlueColorProperty;        //属性包装器        public int RedColor        {            set { SetValue(RedColorProperty, value); }            get { return (int)GetValue(RedColorProperty); }        }        public int GreenColor        {            set { SetValue(GreenColorProperty, value); }            get { return (int)GetValue(GreenColorProperty); }        }        public int BlueColor        {            set { SetValue(BlueColorProperty, value); }            get { return (int)GetValue(BlueColorProperty); }        }        //静态构造函数中注册依赖项属性        static MyButton()        {            FrameworkPropertyMetadata meta0 =                 new FrameworkPropertyMetadata(                0/*默认值*/,                FrameworkPropertyMetadataOptions.AffectsRender/*参数flg*/,                RGBColorPropertyChanged, //changed回调                RGBColorCoerce);//修正回调            FrameworkPropertyMetadata meta1 =                new FrameworkPropertyMetadata(                0/*默认值*/,                FrameworkPropertyMetadataOptions.AffectsRender/*参数flg*/,                RGBColorPropertyChanged, //changed回调                RGBColorCoerce);//修正回调            FrameworkPropertyMetadata meta2 =                new FrameworkPropertyMetadata(                0/*默认值*/,                FrameworkPropertyMetadataOptions.AffectsRender/*参数flg*/,                RGBColorPropertyChanged, //changed回调                RGBColorCoerce);//修正回调            RedColorProperty=DependencyProperty.Register(                "RedColor"/*属性名*/,                typeof(int)/*属性类型*/,                typeof(MyButton)/*父类型*/,                meta0/*PropertyMetadata*/,                 IsColorValid/*验证回调*/);            GreenColorProperty=DependencyProperty.Register(                "GreenColor"/*属性名*/,                 typeof(int)/*属性类型*/,                typeof(MyButton)/*父类型*/,                 meta1/*PropertyMetadata*/,                 IsColorValid/*验证回调*/);            BlueColorProperty=DependencyProperty.Register(                "BlueColor"/*属性名*/,                 typeof(int)/*属性类型*/,                typeof(MyButton)/*父类型*/,                meta2/*PropertyMetadata*/,                 IsColorValid/*验证回调*/);        }        //静态构造函数中引用的回调方法        //属性变化时回调        private static void RGBColorPropertyChanged(            DependencyObject d,DependencyPropertyChangedEventArgs e)        {            MyButton bt = d as MyButton;            if(bt!=null)            {                bt.Foreground = new SolidColorBrush(Color.FromRgb((byte)bt.RedColor, (byte)bt.GreenColor, (byte)bt.BlueColor));            }        }        //属性变化前验证前回调以修正属性值        private static object RGBColorCoerce(            DependencyObject d, object value)        {            int colorvalue = (int)value;            if (colorvalue > 255) return 255;            else if (colorvalue < 0) return 0;            else return colorvalue;        }        //属性变化前验证,判断是否合法,合法返回true        private static bool IsColorValid(object value)        {            int colorvalue = (int)value;            if (colorvalue > 255 || colorvalue < 0) return false;            return true;        }    }}

二。共享依赖项
静态构造函数中调用共享依赖项属性的AddOwner()方法

        public class MyButton2 : Button        {            //定义依赖项属性            public static readonly DependencyProperty RedColorProperty;            //属性包装器            public int RedColor            {                set { SetValue(RedColorProperty, value); }                get { return (int)GetValue(RedColorProperty); }            }            //共享依赖项属性            static MyButton2()            {                RedColorProperty = MyButton.RedColorProperty.AddOwner(typeof(MyButton2));            }        }

三。附加依赖项

           //定义依赖项属性            public static readonly DependencyProperty RedColorProperty;            //附加依赖项属性            static MyButton2()            {                FrameworkPropertyMetadata meta0 =                    new FrameworkPropertyMetadata(                    0/*默认值*/,                    FrameworkPropertyMetadataOptions.AffectsRender/*参数flg*/,                    RGBColorPropertyChanged, //changed回调                    RGBColorCoerce);//修正回调                RedColorProperty = DependencyProperty.RegisterAttached(                    "RedColor"/*属性名*/,                    typeof(int)/*属性类型*/,                    typeof(MyButton)/*父类型*/,                    meta0/*PropertyMetadata*/,                    IsColorValid/*验证回调*/);            }
            MyButton mb = new MyButton();            mb.SetValue(MyButton2.RedColorProperty, 20);

四。总结:
1)注册依赖项时,
1.定义public static readonly DependencyProperty类型
2.定义一个属性,通过DependencyObject中的静态方法SetValue和GetValue包装依赖项
3.静态构造函数中用FrameworkPropertyMetadataOptions和可选的两个回调函数实例化FrameworkPropertyMetadata
4.静态构造函数中用FrameworkPropertyMetadata和可选的验证回调通过DependencyProperty.Register静态方法注册依赖项并赋值
5.完成三个可选的回调函数

2)共享依赖项时,定义依赖项和属性包装器后,在使用类的静态构造函数中调用共享类的依赖项属性的AddOwner()方法。也可以重新提供验证回调和metadata对象

3)附加依赖项时,定义依赖项后不定义属性包装器,在静态构造函数中使用DependencyProperty.RegisterAttached替代DependencyProperty.Register,在之后的使用中直接调用SetValue和GetValue方法绕过属性包装器。

0 0
原创粉丝点击