WPF学习笔记一 依赖属性及其数据绑定
本文想通过由浅入深的讲解让读者比较深的理解依赖属性. 首先,我们回顾一下依赖属性的发展历史.
最初,人们提出面向对象编程时,并没有属性这个说法,当时叫做成员变量.一个对象由成员变量和成员函数组成,如下:
Public int Index;//成员变量
Public void Fun(){} //成员函数
}
后来,提出了对成员变量的改进,增加了get/set 方法,成员变量自然也叫属性了。.net采用了这种方法:
Public Class A{Private int index;//属性Public int Index{Set{index = Value;}Get{return index ;}}Public void Fun(){} //方法
}
到了WPF, 终于变成依赖属性(WPF大部分属性都是依赖属性)。我们先看一个依赖属性的实现,再理解。
public partial class MyButton : Button {public static DependencyProperty PressedImageProperty;//依赖属性public string PressedImage {get { return (string)GetValue(PressedImageProperty); }set { SetValue(PressedImageProperty, value); }}static MyButton() {PressedImageProperty = DependencyProperty.Register("PressedImage", typeof(string), typeof(MyButton),new FrameworkPropertyMetadata(""));}public MyButton () {InitializeComponent();}
上面实现了一个PressedImage的依赖属性。和.net属性比较有几点区别:
1。依赖属性的实体是静态的,类型为DependencyProperty。
如上例中的属性PressedImage,如果在.net中会这样定义它的实体
public string pressedImage;
依赖属性却是这样:
public static DependencyProperty PressedImageProperty;
2。多了一个Register。
3. 它的Get/Set方法借助DependencyObject的GetValue/SetValue来实现.
但凭这些区别是没法理解依赖属性,因为你不知道DependencyProperty,DependencyObject怎么实现的.这里我只能说一下依赖属性一个特点:
在面向对象编程时,一个对象有自己的各种属性,我们以往创建一个对象时,它的属性值就保存在对象本身.但依赖属性却不是把属性值保存在对象本身,而是保存在一张公共的依赖属性表里,它包含所有对象的依赖属性.因此,当我们要知道一个对象的某个属性时,WPF不是从该对象直接取出,而是从那张公共的依赖属性表里取出.
呵呵,大概你明白了为什么依赖属性会变得复杂起来.实际上,功能也强大得多.
下面就来讨论自定义依赖属性和它的数据绑定.
通过例子说明。对上文MyButton进行修进,实现以下功能:当MyButton被按下时显示图片"c:\images\ButtonPressed.png",否则显示图片"c:\images\ButtonNormal.png". xaml代码
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="imgNormal"
Source="c:\images\ButtonNormal.png" Visibility="Visible"/>
<Image x:Name="imgPressed"
Source="c:\images\ButtonPressed.png" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="imgNormal" Property="Visibility" Value="Hidden"/>
<Setter TargetName="imgPressed" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
cs文件代码:
public partial class MyButton : Button {public MyButton () {InitializeComponent();}
上面的代码看不懂也没关系,并没有用到依赖属性。 但同时,这个MyButton并没有使用价值,因为他的图片是固定的。我们希望MyButton的图片可以由用户来设定。在上面的xaml文件中,只需改变Image的Source属性。WPF的方法就是数据绑定,也就是把Image的Source属性绑定到一个变量,修改一下xaml:
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="imgNormal" Source="{Binding Path=NormalImage}" Visibility="Visible"/>
<Image x:Name="imgPressed" Source="{Binding Path=PressedImage}" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="imgNormal" Property="Visibility" Value="Hidden"/>
<Setter TargetName="imgPressed" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
imgNormal的图片路径绑定变量NormalImage, imgPressed的图片路径绑定到PressedImage,再在MyButton类中增加2个属性NormalImage,PressedImage
public partial class MyButton : Button {public string NormalImage;
public string NormalImage;
public MyButton () {InitializeComponent();}
在使用MyButton时用以下语句访问:
搞定!!怎么?编译通不过?因为NormalImage和PressedImage不是依赖属性,所以编译无法通过。 那就继续改吧,把NormalImage和PressedImage改成依赖属性。
MyButton.cs的最后代码如下:
public partial class MyButton : Button {public static DependencyProperty NormalImageProperty;public static DependencyProperty PressedImageProperty;public string NormalImage {get { return (string)GetValue(NormalImageProperty); }set { SetValue(NormalImageProperty, value); }}public string PressedImage {get { return (string)GetValue(PressedImageProperty); }set { SetValue(PressedImageProperty, value); }}static MyButton () {NormalImageProperty = DependencyProperty.Register("NormalImage", typeof(string), typeof(MyButton ),new FrameworkPropertyMetadata(""));PressedImageProperty = DependencyProperty.Register("PressedImage", typeof(string), typeof(MyButton ),new FrameworkPropertyMetadata(""));}public MyButton () {InitializeComponent();}
为什么xaml不支持普通属性?
回顾一下WPF的基本理念:真正做到了分离界面设计人员与开发人员的工作。也就是说,xaml文件呈现的是用户界面,从xaml到用户界面的转化不是由编译器直接编译成用户界面的运行代码(这样和原来的WIN FORM又没有区别了),而是由WPF本身类库来来完成的,打个比方,XAML有如下代码:
<Button Background="White"></Button>
其中的“White”是如何与C#中的System.Windows.Media.Brushes.White等价的呢?。原来WPF提供了Brush数据类型的转换器。
对于简单属性(如int类型的), WPF要解释它并不难,如果是自定义类型的呢,WPF要解释它也不难,比如要求开发人员在使用自定义类型的属性时,同时提供该自定义类型的转换器。因此,个人认为,xaml不支持普通属性的原因就是WPF的设计者认为没有必要。
转载于:https://www.cnblogs.com/zhongxg/archive/2011/05/25/2056530.html
WPF学习笔记一 依赖属性及其数据绑定相关推荐
- WPF学习笔记(数据绑定篇3)
接上回的<WPF学习笔记(数据绑定篇2)>,继续 BindValidation 此示例演示了: 如何使用错误模板: 使用样式显示错误信息: 如何在校验发生异常时执行回调: 首先,你可以看见 ...
- SpringMVC:学习笔记(11)——依赖注入与@Autowired
SpringMVC:学习笔记(11)--依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...
- WPF xaml中列表依赖属性的定义
原文:WPF xaml中列表依赖属性的定义 列表内容属性 如上图,是一个列表标题排序控件,我们需要定义一个标题列表,从而让调用方可以自由的设置标题信息. 在自定义控件时,会遇到列表依赖属性,那么该如何 ...
- WPF学习笔记(7):DataGrid中数字自定义格式显示
WPF学习笔记(7):DataGrid中数字自定义格式显示 原文:WPF学习笔记(7):DataGrid中数字自定义格式显示 DataGrid中数据显示如下图,数据格式比较杂乱.希望达到以下要求:(1 ...
- MongoDB学习笔记~对集合属性的操作
$unset清除元素 请注意在单个数组元素上使用$unset的结果可能与你设想的不一样.其结果只是将元素的值设置为null,而非删除整个元素.要想彻底删除某个数组元素,可以用$pull 和$pop操作 ...
- WPF学习之深入浅出话属性
通过前面的学习,我们已经知道Data Binding是WPF"数据驱动UI"理念的基础.上一章我们将主要的精力放在了Binding的数据源这一端,研究了Binding的Source ...
- WPF 学习笔记 路由事件
1. 可传递的消息: WPF的UI是由布局组建和控件构成的树形结构,当这棵树上的某个节点激发出某个事件时,程序员可以选择以传统的直接事件模式让响应者来响应之,也可以让这个事件在UI组件树沿着一定的方向 ...
- [Aaronyang] 写给自己的WPF4.5 笔记[2依赖属性]
人生的意义不在于拿一手好牌,而在于打好一手坏牌 --Aaronyang的博客(www.ayjs.net)-www.8mi.me =============时隔两年后再看WPF========== 因为 ...
- 深入浅出WPF学习笔记之Binding
深入浅出WPF之Binding Binding Binding基础 Binding模型 把控件作为Binding源与Binding标记扩展 Binding的(Path)路径 Binding支持多级路径 ...
最新文章
- 【光纤通信】关于RFA(喇曼光纤放大器)
- 201771010111李瑞红《面向对象的程序设计》第八周实验总结
- 爱奇艺大数据分析平台的演进之路
- JSP自定义标签开发入门
- 网线直连Window和Ubuntu
- Halcon —— 边缘检测算子详解
- Whats the difference between git reset --mixed, --soft, and --hard?
- Cognos11中通过URL访问report的设置
- iOS Runtime运行机制详解
- 虚拟机利用Host-only实现在不插网线的情况下,虚拟机与主机实现双向通信,实现ssh连接以及samba服务实现共享...
- iOS不再美好 安卓收入逼近千万
- web工程was部署
- 【搬运】不思议的小故事,其实舰娘们也是有灵性的
- win10主机ping不通win10虚拟机
- 你为什么成为一名程序员?
- Docker一探究竟
- C++实现改变网速*SpeedDuplex和网速监控
- HarmonyOS APP开发入门3——组件(二 Text组件)
- 《Photoshop修饰与合成专业技法》—第1章伪造的抠像:第一部分
- attention机制、self-attention、channel attention、spatial attention、multi-head attention、transformer