依赖属性之“风云再起”五
十二. 其他协助类测试代码
1: using System;
2: using System.Windows;
3: using NUnit.Framework;
4:
5: namespace TDDDependencyTest.System.Windows
6: {
7: [TestFixture]
8: public class DependencyObjectTypeTest
9: {
10:
11: [Test]
12: public void Accessors()
13: {
14: DependencyObjectType t = DependencyObjectType.FromSystemType(typeof(TestDepObj));
15: Assert.AreEqual("TestDepObj", t.Name);
16: Assert.AreEqual(typeof(TestDepObj), t.SystemType);
17: Assert.AreEqual(typeof(DependencyObject), t.BaseType.SystemType);
18: }
19:
20: [Test]
21: public void IsInstanceOfType()
22: {
23: DependencyObjectType t = DependencyObjectType.FromSystemType(typeof(TestDepObj));
24: DependencyObjectType t2 = DependencyObjectType.FromSystemType(typeof(TestSubclass));
25: Assert.IsTrue(t.IsInstanceOfType(new TestSubclass()));
26: Assert.IsTrue(t2.IsSubclassOf(t));
27: Assert.IsFalse(t.IsSubclassOf(t2));
28: }
29:
30: [Test]
31: public void TestCache()
32: {
33: DependencyObjectType t = DependencyObjectType.FromSystemType(typeof(TestDepObj));
34: DependencyObjectType t2 = DependencyObjectType.FromSystemType(typeof(TestDepObj));
35: Assert.AreSame(t, t2);
36: }
37: }
38: }
十三. 其他协助类的实现代码
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Collections;
6:
7: namespace System.Windows
8: {
9: //手动实现一个IEnumerator来方便访问LocalValue
10: public struct LocalValueEnumerator : IEnumerator
11: {
12: private IDictionaryEnumerator propertyEnumerator;
13: private Dictionary<DependencyProperty, object> properties;
14:
15: private int count;
16:
17: internal LocalValueEnumerator(Dictionary<DependencyProperty, object> properties)
18: {
19: this.count = properties.Count;
20: this.properties = properties;
21: this.propertyEnumerator = properties.GetEnumerator();
22: }
23:
24: public int Count
25: {
26: get { return count; }
27: }
28:
29: //获取当前LocalValue
30: public LocalValueEntry Current
31: {
32: get
33: {
34: return new LocalValueEntry((DependencyProperty)propertyEnumerator.Key,
35: propertyEnumerator.Value);
36: }
37: }
38:
39: object IEnumerator.Current
40: {
41: get { return this.Current; }
42: }
43:
44:
45: public bool MoveNext()
46: {
47: return propertyEnumerator.MoveNext();
48: }
49:
50: //重置propertyEnumerator
51: public void Reset()
52: {
53: propertyEnumerator.Reset();
54: }
55:
56: public static bool operator !=(LocalValueEnumerator obj1, LocalValueEnumerator obj2)
57: {
58: throw new NotImplementedException();
59: }
60:
61: public static bool operator ==(LocalValueEnumerator obj1, LocalValueEnumerator obj2)
62: {
63: throw new NotImplementedException();
64: }
65:
66: public override bool Equals(object obj)
67: {
68: throw new NotImplementedException();
69: }
70:
71: public override int GetHashCode()
72: {
73: throw new NotImplementedException();
74: }
75: }
76:
77: //LocalValue实体类
78: public struct LocalValueEntry
79: {
80: private DependencyProperty property;
81: private object value;
82:
83: internal LocalValueEntry(DependencyProperty property, object value)
84: {
85: this.property = property;
86: this.value = value;
87: }
88:
89: public DependencyProperty Property
90: {
91: get { return property; }
92: }
93:
94: public object Value
95: {
96: get { return value; }
97: }
98:
99: public static bool operator !=(LocalValueEntry obj1, LocalValueEntry obj2)
100: {
101: throw new NotImplementedException();
102: }
103:
104: public static bool operator ==(LocalValueEntry obj1, LocalValueEntry obj2)
105: {
106: throw new NotImplementedException();
107: }
108:
109: public override bool Equals(object obj)
110: {
111: throw new NotImplementedException();
112: }
113:
114: public override int GetHashCode()
115: {
116: throw new NotImplementedException();
117: }
118: }
119: }
120:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: namespace System.Windows
7: {
8: public class DependencyPropertyChangedEventArgs
9: {
10: //第一个参数为该DependencyProperty、第二个参数为原来的值、第三个参数为新值
11: public DependencyPropertyChangedEventArgs(DependencyProperty property, object oldValue, object newValue)
12: {
13: this.Property = property;
14: this.OldValue = oldValue;
15: this.NewValue = newValue;
16: }
17:
18: //注意所有的属性只对外界开放只读操作
19: public object NewValue
20: {
21: get;
22: private set;
23: }
24:
25: public object OldValue
26: {
27: get;
28: private set;
29: }
30:
31: public DependencyProperty Property
32: {
33: get;
34: private set;
35: }
36:
37: public override bool Equals(object obj)
38: {
39: if (!(obj is DependencyPropertyChangedEventArgs))
40: return false;
41:
42: return Equals((DependencyPropertyChangedEventArgs)obj);
43: }
44:
45: public bool Equals(DependencyPropertyChangedEventArgs args)
46: {
47: return (Property == args.Property &&
48: NewValue == args.NewValue &&
49: OldValue == args.OldValue);
50: }
51:
52: public static bool operator !=(DependencyPropertyChangedEventArgs left, DependencyPropertyChangedEventArgs right)
53: {
54: throw new NotImplementedException();
55: }
56:
57: public static bool operator ==(DependencyPropertyChangedEventArgs left, DependencyPropertyChangedEventArgs right)
58: {
59: throw new NotImplementedException();
60: }
61:
62: public override int GetHashCode()
63: {
64: throw new NotImplementedException();
65: }
66:
67: }
68: }
1:
2: namespace System.Windows
3: {
4: //构造函数传入该DependencyProperty,然后通过Type来OverrideMetadata
5: public sealed class DependencyPropertyKey
6: {
7: internal DependencyPropertyKey (DependencyProperty dependencyProperty)
8: {
9: this.dependencyProperty = dependencyProperty;
10: }
11:
12: private DependencyProperty dependencyProperty;
13: public DependencyProperty DependencyProperty {
14: get { return dependencyProperty; }
15: }
16:
17: public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata)
18: {
19: dependencyProperty.OverrideMetadata (forType, typeMetadata, this);
20: }
21: }
22: }
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: namespace System.Windows
7: {
8: public class DependencyObjectType
9: {
10: //键为Type(即OwnerType),值为DependencyObjectType(即ID和systemType)的键值对
11: private static Dictionary<Type, DependencyObjectType> typeMap = new Dictionary<Type, DependencyObjectType>();
12: private static int current_id;
13:
14: private int id;
15: private Type systemType;
16:
17: //构造函数私有,在FromSystemType里进行构造,初始化id和systemType
18: private DependencyObjectType(int id, Type systemType)
19: {
20: this.id = id;
21: this.systemType = systemType;
22: }
23:
24: //基类型的DependencyObjectType
25: public DependencyObjectType BaseType
26: {
27: get { return DependencyObjectType.FromSystemType(systemType.BaseType); }
28: }
29:
30: public int Id
31: {
32: get { return id; }
33: }
34:
35: public string Name
36: {
37: get { return systemType.Name; }
38: }
39:
40: public Type SystemType
41: {
42: get { return systemType; }
43: }
44:
45: //用静态Dictionary<Type, DependencyObjectType>来存储DependencyObjectType
46: public static DependencyObjectType FromSystemType(Type systemType)
47: {
48: if (typeMap.ContainsKey(systemType))
49: return typeMap[systemType];
50:
51: DependencyObjectType dot;
52:
53: typeMap[systemType] = dot = new DependencyObjectType(current_id++, systemType);
54:
55: return dot;
56: }
57:
58: //是否是该DependencyObject的子类实例
59: public bool IsInstanceOfType(DependencyObject d)
60: {
61: return systemType.IsInstanceOfType(d);
62: }
63:
64: //该DependencyObjectType是否是传入DependencyObjectType的子实例
65: public bool IsSubclassOf(DependencyObjectType dependencyObjectType)
66: {
67: return systemType.IsSubclassOf(dependencyObjectType.SystemType);
68: }
69:
70: public override int GetHashCode()
71: {
72: throw new NotImplementedException();
73: }
74: }
75: }
76:
十四. 回归并统计覆盖率
![](/assets/blank.gif)
![](/assets/blank.gif)
十五. 简单验证依赖属性系统
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: SimpleDPClass sDPClass = new SimpleDPClass();
6: sDPClass.SimpleDP = 8;
7: Console.ReadLine();
8: }
9: }
10:
11: public class SimpleDPClass : DependencyObject
12: {
13: public static readonly DependencyProperty SimpleDPProperty =
14: DependencyProperty.Register("SimpleDP", typeof(double), typeof(SimpleDPClass),
15: new PropertyMetadata((double)0.0,
16:
17: new PropertyChangedCallback(OnValueChanged),
18: new CoerceValueCallback(CoerceValue)),
19: new ValidateValueCallback(IsValidValue));
20:
21: public double SimpleDP
22: {
23: get { return (double)GetValue(SimpleDPProperty); }
24: set { SetValue(SimpleDPProperty, value); }
25: }
26:
27: private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
28: {
29: Console.WriteLine("当值改变时,我们可以做的一些操作,具体可以在这里定义: {0}", e.NewValue);
30: }
31:
32: private static object CoerceValue(DependencyObject d, object value)
33: {
34: Console.WriteLine("对值进行限定,强制值: {0}", value);
35: return value;
36: }
37:
38: private static bool IsValidValue(object value)
39: {
40: Console.WriteLine("验证值是否通过,如果返回True表示验证通过,否则会以异常的形式暴露: {0}", value);
41: return true;
42: }
43:
44: }
![](/assets/blank.gif)
十六. 本文总结
十七. 相关代码下载
![](/assets/blank.gif)
上图就是整个代码包的结构图,下载链接: DependencySystem.rar
十八.系列进度
前篇· 1. WPF 基础到企业应用系列1——开篇有益· 2. WPF 基础到企业应用系列2——WPF前世今生· 3. WPF 基础到企业应用系列3——WPF开发漫谈· 4. WPF 基础到企业应用系列4——WPF千年轮回· 5. WPF 基础到企业应用系列5——WPF千年轮回 续前缘· 6. WPF 基础到企业应用系列6——WPF布局全接触· 7. WPF 基础到企业应用系列7——深入剖析依赖属性(核心篇)· 8. WPF 基础到企业应用系列8——依赖属性之“风云再起”· 9. WPF 基础到企业应用系列9——深入剖析WPF事件机制 (核心篇)·10. WPF 基础到企业应用系列10——WPF事件机制之“刨根问底”·11. WPF 基础到企业应用系列11——深入剖析WPF命令机制 (核心篇)·12. WPF 基础到企业应用系列12——WPF命令之“庖丁解牛”·13. WPF 基础到企业应用系列13——WPF Binding全接触 (核心篇)·14. WPF 基础到企业应用系列14——WPF Binding之“面面俱到”中篇· 1. 资源、样式、模板· 2. 尺寸缩放、定位与变换元素· 3. WPF控件分类介绍与使用技巧· 4. 用户控件和自定义控件开发· 5. 多语言、皮肤和主题· 6. 2D图形· 7. 3D图形· 8. 动画(几种动画的应用)· 9. 音频、视频、语音· 10. 文档、打印、报表后篇· 1. Win32、Windows Form以及ActiveX之间的互用性· 2. 构建并部署应用程序(ClickOnce部署、微软setup /InstallShield+自动更新组件)· 3. MVC、MVP、MVVM全解析· 4. WPF的模式讲解及实例(MVC Demo)· 5. WPF的模式讲解及实例(MVP Demo)· 6. WPF的模式讲解及实例(MVVM Demo)· 7. 性能优化(WPF项目的瓶颈)· 8.一个完整WPF项目(普通架构版)· 9. 一个完整WPF项目(MVVM架构版)· 10. WPF 4.0新功能
依赖属性之“风云再起”五相关推荐
- WPF基础到企业应用系列8——依赖属性之“风云再起”
一. 摘要 首先圣殿骑士很高兴"WPF 基础到企业应用系列" 能得到大家的关注.支持和认可.看到很多朋友留言希望加快速度的问题,我会尽力的,对你们的热情关注也表示由衷的感谢.这段时 ...
- 依赖属性之“风云再起”二
五. 引入测试驱动开发 1,引入概念 由于本篇的依赖属性体系是基于测试驱动开发完成的,所以我们就先来看一下什么叫测试驱动开发:测试驱动开发的基本思想就是在开发功能代码之前, 先编写测试代码.也就是说在 ...
- 依赖属性之“风云再起”四
十. PropertyMetadata测试代码 前面我们看到一个依赖属性的注册最全的形式是下面这样子的: public static DependencyProperty Register(strin ...
- 依赖属性之“风云再起”三
八. DependencyObject测试代码 在写DependencyObject测试代码之前,我们先看一下它到底有哪些成员和方法,如下图: 通过上面的这幅图,我们知道它的主要功能包括:各种依赖属性 ...
- WPF入门教程(七)---依赖属性(3)(转)
WPF入门教程(七)---依赖属性(3) 2018年08月24日 08:33:43 weixin_38029882 阅读数:50 四. 只读依赖属性 在以前在对于非WPF的功能来说,对于类的属性的封装 ...
- WPF入门教程系列十三——依赖属性(三)
四. 只读依赖属性 在以前在对于非WPF的功能来说,对于类的属性的封装中,经常会对那些希望暴露给外界只读操作的字段封装成只读属性,同样在WPF中也提供了只读属性的概念,如一些 WPF控件的依赖属性是只 ...
- WPF入门教程系列十四——依赖属性(四)
六.依赖属性回调.验证及强制值 我们通过下面的这幅图,简单介绍一下WPF属性系统对依赖属性操作的基本步骤: 借用一个常见的图例,介绍一下WPF属性系统对依赖属性操作的基本步骤: 第一步,确定Base ...
- 3-maven学习-学习创建maven的依赖属性
一.什么是依赖属性 在por.xml配置中会添加所需要引入的jar包,前面已经知道,jar包有三要素:必须写 groupId:公司或组织的id artifactId:一个项目或者是项目中的一个模块的i ...
- SilverlightWPF依赖属性DependencyProperty讲解
作者:周永恒 出处:http://www.cnblogs.com/Zhouyongh 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
最新文章
- php7.0 连接ftp,PHPstorm连接ftp
- [UVa10296]Jogging Trails
- 编程题: 将一个矩阵(二维数组)顺时针旋转90度
- 用户暴增下的收入降低,AWS面临尴尬
- cocos2d-android-1 使用方法
- ApacheCN 学习资源汇总 2018.11
- C++指针探讨 (二) 函数指针
- 苹果系统和安卓系统的区别_Android和iPhone的区别?还不如说安卓系统和IOS系统的差别...
- Cadence用于版图设计时芯片logo的制作
- LabVIEW编程LabVIEW开发高级数据采集技术 操作数字IO 例程与相关资料
- 苹果笔记本电脑亮度无法调节_macbook怎么调节屏幕亮度|苹果笔记本调显示器亮度方法...
- 【转】Mac 下钥匙串不能授权访问怎么解决--不错
- 浏览器默认主页被360篡改解决办法
- 武汉坚守第六十三天——七九已满疫未退,印度大法上棍棒
- 实战新浪微博、腾讯微博的分享功能(转)
- 如何修改Hosts文件(Windows、Linux)
- Consolas和微软雅黑混合字体
- c语言程序设计教程王曙燕,C语言程序设计
- 用好这两个小工具,制作乐谱更高效!
- 【iOS-知乎日报第二周总结】