依赖项属性

依赖项属性在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值