WPF入门(2)——依赖属性

今天我们说说依赖属性

什么是依赖属性?

当然,学术定义依旧Please Baidu:https://baike.baidu.com/item/%E4%BE%9D%E8%B5%96%E5%B1%9E%E6%80%A7/637278?fr=aladdin

那么,请问你看明白了吗?明白了就请出门左转吧,同时本人也是很佩服的,本人也是经人点拨后才了解依赖属性到底是个什么东西,他真实的定义就是:

依赖属性——一个反抗旧思想旧家庭的新时代抗争青年(说白了就是个愤青)

先讲一个故事:

贾少爷,姓贾名五代,出身贵族家庭,其父贾老爷,姓贾名四代,著名商旅,其祖父贾爷爷,姓贾名三代,文人墨客,其高祖贾高祖,姓贾名二代,官宦重臣,其先祖贾剑客,姓贾名一代,侠士风流,家中历代均有家产流传给后世。流传图谱如下:

贾一代:隐士剑谱

贾二代:丞相司印

贾三代:风雅画卷

贾四代:金银重鼎

以上四件神器流传至今,均传给了贾五代

结果贾五代是个家族异类,专心研究佛法,手里最看重的宝贝是:念珠木鱼。

这就尴尬了,作为贾少爷,只想研究佛法,那四件价值连城的宝贝根本瞧不上(给我呀……),一心想要和家庭抗争,只想拿着念珠木鱼烧香拜佛,所以这事该怎么办?

好的故事到此结束。

其实这就是依赖属性,每个父类都有其自有属性,当一个子类多级继承其父类时,那么它必然继承了其父类的所有可以继承的成员,所以就会造成最后的一个叶子子类臃肿不堪,本来不想要的属性也因为继承链而被传递给子类。上面的故事用代码解释就是这样的。

    public class JiaYidai
    {
        public string YinShiJianPu { get; set; }
    }

    public class JiaErdai:JiaYidai
    {
        public string ChengXiangSiYin { get; set; }
    }

    public class JiaSandai : JiaErdai 
    {
        public string FengYaHuaJuan { get; set; }
    }

    public class JiaSidai : JiaSandai 
    {
        public string JinYinZhongDing { get; set; }
    }

    public class JiaWudai : JiaSidai 
    {
        public string NianZhuMuYu { get; set; }
    }

那么当我们在调用JiaWudai时肯定会出现之前的父类的属性,如图:

 

 那么那些不相干的属性就会同步继承而来,所以依赖属性就是为了解决这个问题而产生的。

我们来看如何来解决这个问题,既然贾五代不想继承其它的属性,那么我们就将其父类的宝贝都做成依赖属性,看看会怎么样。

首先我们先建立一个依赖属性对象:

public class DependencyProperty
    {
        /// <summary>
        /// 属性名
        /// </summary>
        internal string Name;
        /// <summary>
        /// 属性值
        /// </summary>
        internal object Value;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"></param>
        /// <param name="propertyName"></param>
        /// <param name="ownerType"></param>
        /// <param name="defaultValue"></param>
        private DependencyProperty(string name, Type propertyName, Type ownerType, object defaultValue)
        {
            this.Name = name;
            this.Value = defaultValue;
        }
        /// <summary>
        /// 创建属性的方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="propertyName"></param>
        /// <param name="ownerType"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static DependencyProperty CreateInstance(string name, Type propertyName, Type ownerType, object defaultValue)
        {
            DependencyProperty dp = new DependencyProperty(name, propertyName, ownerType, defaultValue);
            return dp;
        }
    }

之后我们再建立贾五代的四个父级类,代码如下

public class JiaYidai
    {
        public static readonly DependencyProperty InstantYidai = DependencyProperty.CreateInstance("YinShiJianPu", typeof(string), typeof(JiaYidai), "隐士剑谱");
        public object GetValueYidai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueYidai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string YinShiJianPu
        {
            get
            {
                return GetValueYidai(InstantYidai).ToString();
            }
            set
            {
                SetValueYidai(InstantYidai, value);
            }
        }
    }

    public class JiaErdai : JiaYidai
    {

        public static readonly DependencyProperty InstantErdai = DependencyProperty.CreateInstance("ChengXiangSiYin", typeof(string), typeof(JiaYidai), "丞相司印");
        public object GetValueErdai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueErdai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string ChengXiangSiYin
        {
            get
            {
                return GetValueErdai(InstantErdai).ToString();
            }
            set
            {
                SetValueErdai(InstantErdai, value);
            }
        }
    }

    public class JiaSandai : JiaErdai
    {
        public static readonly DependencyProperty InstantSandai = DependencyProperty.CreateInstance("FengYaHuaJuan", typeof(string), typeof(JiaYidai), "风雅画卷");
        public object GetValueSandai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueSandai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string FengYaHuaJuan
        {
            get
            {
                return GetValueSandai(InstantSandai).ToString();
            }
            set
            {
                SetValueSandai(InstantSandai, value);
            }
        }
    }

    public class JiaSidai : JiaSandai
    {
        public static readonly DependencyProperty InstantSidai = DependencyProperty.CreateInstance("JinYinZhongDing", typeof(string), typeof(JiaYidai), "金银重鼎");
        public object GetValueSidai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueSidai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string JinYinZhongDing
        {
            get
            {
                return GetValueErdai(InstantErdai).ToString();
            }
            set
            {
                SetValueErdai(InstantErdai, value);
            }
        }
    }

然后我们再次调用

 

 咦,为什么没有变化呢?查看源代码就会发现我们为了调用的方便,我们在依赖属性的SetValue和GetValue方法后封装了一个public的同名属性,这个属性是可以继承的,所以贾五代依旧可以看到并使用这些属性。可以通过删除父级类中的属性进行测试,在从不再详述。当然如果真的希望各个属性间不发生任何属性继承,可以取消所有继承,让各级父类分别继承这五个依赖属性,就可以实现类构成的精简

那么这个依赖属性有什么用?让我们看另外一个例子,代码如下:

public class JiaYidai
    {
        private static DependencyProperty Instant = DependencyProperty.CreateInstance("YinShiJianPu", typeof(string), typeof(JiaYidai), "隐士剑谱");
        public object GetValueYidai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueYidai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string YinShiJianPu
        {
            get
            {
                return GetValueYidai(Instant).ToString();
            }
            set
            {
                SetValueYidai(Instant, value);
            }
        }
    }

    public class JiaErdai : JiaYidai
    {

        private static DependencyProperty Instant = DependencyProperty.CreateInstance("ChengXiangSiYin", typeof(string), typeof(JiaYidai), "丞相司印");
        public object GetValueErdai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueErdai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string ChengXiangSiYin
        {
            get
            {
                return GetValueErdai(Instant).ToString();
            }
            set
            {
                SetValueErdai(Instant, value);
            }
        }
    }

    public class JiaSandai : JiaErdai
    {
        private static DependencyProperty Instant = DependencyProperty.CreateInstance("FengYaHuaJuan", typeof(string), typeof(JiaYidai), "风雅画卷");
        public object GetValueSandai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueSandai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string FengYaHuaJuan
        {
            get
            {
                return GetValueSandai(Instant).ToString();
            }
            set
            {
                SetValueSandai(Instant, value);
            }
        }
    }

    public class JiaSidai : JiaSandai
    {
        private static DependencyProperty Instant = DependencyProperty.CreateInstance("JinYinZhongDing", typeof(string), typeof(JiaYidai), "金银重鼎");
        public object GetValueSidai(DependencyProperty dp)
        {
            return dp.Value;
        }
        public void SetValueSidai(DependencyProperty dp, string value)
        {
            dp.Value = value;
        }
        public string JinYinZhongDing
        {
            get
            {
                return GetValueErdai(Instant).ToString();
            }
            set
            {
                SetValueErdai(Instant, value);
            }
        }
    }

    public class JiaWudai : JiaSidai
    {
        public string NianZhuMuYu { get; set; }
    }

再运行如图所示代码:

 

 看结果:

 

咦,本来改的是子类,怎么把父类给改了?没错这就是依赖属性的好处,一处修改,大家都知道了,想想也知道,假如贾五代这天闲来无事,打开了风雅画卷,突然无聊,拿起笔来在画卷上写了个hello world,然后把画卷收回去了,他的祖父贾三代再拿出来打开的时候hello world会没了么?写上了不擦肯定不会消失的,这就是依赖属性的好处。

所以如果依赖属性和使用了依赖属性的对象再继承一个接口INotifyPropertyChanged的话,好像……诞生了一个新的世界,这个世界让我们下回分解……

 

 

posted @ 2019-11-28 13:10  若雪白衣  阅读(239)  评论(0编辑  收藏  举报