[WPF]WPF中如何实现数据与表示分离。(二) —— Binding(下)
2006-01-20 09:32 Colin Han 阅读(4650) 评论(8) 编辑 收藏 举报“我怎么知道什么时候数据改变?”
“我可能必须利用反射去访问数据,而反射的性能会很低。”
“{Binding Path=Red}是什么东西?”
好在这一切都只是我的一个想象,微软已经为我们提供了解决方案。这里就要引入WPF中的DependencyProperty的概念了。
在我刚刚开始接触到WPF的DependencyProperty的时候,仅仅觉得是一个很巧妙的实现,随着学习WPF的深入,也来越觉得DependencyProperty其实是WPF的核心技术点之一。
DependencyProperty和DependencyObject配合,提供了WPF中基本的数据存储、访问和通知的机制。也正是因为这两个东西的存在,使得XAML,Binding,Animation都成为可能。
让我们来看一下重新实现后的数据层。

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

在行12-35,我们注册了4个DependencyProperty:RedProperty, GreenProperty, BlueProperty 和 BackgroundProperty。我们也不再使用成员字段去保存这些属性的具体值。而是直接使用DependencyObject上的GetValue和SetValue方法设置和读取值。
当Red, Green, Blue属性发生变化的时候,我们来同步Background属性(注1)。同时,DependencyObject也会使用特定的方式向关联的对象(例如:Binding)发出通知。
Ok,通知的问题解决了。我们开发人员以后不再需要去制定或维护这套数据层和表示层通讯的策略。然后,我们就需要解决第二个问题:使用反射获得对象的属性的性能问题。
从前面的Code中,也许细心的你已经发现,我们不再需要使用反射去获得对象的某个属性了。因为DependencyObject已经提供了GetValue和SetValue方法。数据绑定管理者(暂且先这样叫吧)可以通过这两个方法容易的获得或设置任何一个属性的值(注2)。而且,前面的属性注册的机制,也让微软有一个机会来优化内部的数据存储,提高性能(注3)。剩下的性能问题可能就出在了Boxing和UnBoxing上了,毕竟很多属性都是值类型的。但是,以目前的结构,微软在JIT上对这一部分进行一些专门的优化也并非不可能。个人猜想,具体情况如何,留待各位去研究了。
啊哈,剩下最后一个问题了。{Binding Path=Red}是什么?微软的官方称呼为:MarkupExtension。或者可以翻译为标记扩展。我写过一篇Blog简单的说了如何自定义一个MarkupExtension,虽然当时我没有调通,但是我认为已经概括性的告诉了你,MarkupExtension是如何工作的。
上面的这条语句也就是说,Slider的Value属性的值是由Binding这个MarkupExtension对象提供(ProvideValue)的。
Ok,Clear。但是,这样就够了吗?所有的问题都解决了吗?这样的设计已经是最好的了吗?
“不!”(也许各位的客户也经常这样向你喊。)
“Brush是个什么东西?我的数据模块只关心Color,不关心Brush!”
“Background的更新逻辑太土了。”(就象很多你们碰到的用户一样,用户有时候就希望能有一个非常漂亮的界面。)
没问题,我将在后面的文章中讨论如何改进这些问题,让我们的数据模块和表示层尽量的分离。
最后,附上本节的源代码:ColorPicker2.rar
注意:本文相关的例子都在WinFX 12月CTP下测试通过,因为目前环境限制,没能再今年1月CTP下进行测试,请见谅。
注1:其实,这一部分,微软已经为我们提供了更巧妙的途径,留待下一节来讲解吧。
注2:其实,不光数据绑定,XAML其实也是使用这两个方法来访问对象的属性的
注3:反编译代码后,证实了我的这个设想,微软为DependencyProperty实现了一套高效的Hash值算法来优化存储。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix