wpf学习有感(二)
1.xaml
xaml就是由xml派生而来的,就像网页后台,花花绿绿的。由一堆标签组成
而写在里面的一对对标签全部都是一个个对象。
Attribute和Property的区别
两者皆可翻译为属性,但注意的是,这两个不是一种东西。
对于Property而言,其针对的是对象,而对于Attribute,其针对的是标签,其也可以译为特征。
简单来说,后台代码中对象的属性可以称为Property,而xaml中标签中的属性可以称为Attribute。
注意,一个标签具有的Attribute多于它所代表的对象的Property。
2.依赖项属性(dependency property)
依赖项属性与普通属性使用方法一样,但其背后的代码编写方式是不一样的,其目的是为了解决普通属性因为继承带来的对象膨胀的问题
定义
定义表示属性的对象。
public static readonly DependencyProperty MyPropertyProperty;
注册
MyPropertyProperty = DependencyProperty.Register(“MyProperty”, typeof(int), typeof(类名), new PropertyMetadata(0));
可以看到Register方法有三个重载,前三个参数
- String:表示所要对其进行封装的属性的名称;
- 第一个Type:表示该属性所属类型;
- 第二个Type:表示该属性所有者的类型,也就是在哪个类里面定义的这个依赖属性;
- PropertyMetadata对象:这个对象里面包含有依赖属性的元数据相关的信息,元数据也就是一些用来描述类型的信息,这里包含例如属性默认值,通知回调和验证回调的引用,还有一些框架性特征(布局、数据绑定等)
Object:表示要对该属性指定的默认值,例如string类型可以指定default(string);
PropertyChangedCallback:从名字就可以看出,这是一个在属性值被更改时所调用的回调函数,常用于绑定数据变更时处理;
CoerceValueCallback:Coerce意思是胁迫、强制,也就是这个方法用于在对属性值进行改变的时候,对赋值进行检查,强制对值进行赋值,返回值为Object类型,这个才是要赋给属性的值; - Register方法的最后一个参数是ValidateValueCallback,这个方法同样是对值的检查。
传入的参数value为Object类型,也就是要进行检查的属性值,这里会不会有疑问,既然已经有了CoerceValueCallback方法可以对值进行检查之后强制改变要进行的赋值,为什么还要有这个合法值得检查?因为CoerceValueCallback方法无论如何检查,返回值为Object,都会给属性值进行一个赋值,然后会调用PropertyChangedCallback方法,但是在进行CoerceValueCallback方法的调用之前,就会调用ValidateValueCallback方法对值进行检查,可以看到该方法的返回值为一个bool类型,当值满足条件时返回true,这时就会去调用CoerceValueCallback对值进行进一步的处理,如果不满足条件的话返回false,则本次赋值失败告终,根本就没有后续CoerceValueCallback什么事,也就是ValidateValueCallback方法是值更新前检查方法 ,对值进行的最初的拦截检查。
3.附加属性
附加属性就是依赖属性
除了注册方法是RegisterAttached之外还有另外独立出来的静态方法SetValue和GetValue,在这里RegisterAttached和Register方法并没有什么不同,都是往全局字典中添加属性;
区别:
依赖属性是给自己用的,附加属性是给别人用的,这句话是没错的,在使用附加属性的时候回将使用者的信息作为参数传入进来,所以会有一些布局控件例如Grid,Canvas等有附加属性,Grid.SetRow和Canvas.SetLeft都是直接调用了静态的方法,通过传入的参数来告知属性所有者是谁用了我的属性,把它设为了什么值,这样在布局的时候我就知道要把谁往哪里放,这也是依赖属性和附加属性的一个区别。而且像这样单独将两个方法暴露出来也是为了方便他人使用。
附加属性就是自己没有这个属性,在某些上下文中需要就被附加上去。比如TextBox的Grid.Row属性,如果我们定义TextBox类时定义一个Row属性是没有意义的,因为我们并不知道一定会放在Grid里,这样就造成了浪费。
附加属性是依赖属性的一种特殊形式,它可以让用户在一个元素中设置其他元素的属性。一般来说,附加属性是用于一个父元素定位其他元素布局的。就像Grid和DockPanel元素就包含附加属性。Grid使用附加属性来指定包含子元素的特定行和列,而DockPanel使用附加属性是来指定子元素应该停靠在面板中的何处位置。