《深入浅出WPF》学习笔记二数据绑定(Binding)、依赖属性和附加属性
第六章 深入浅出话Binding
1、绑定的源可以是任意对象,并通过属性公开自己的数据;
绑定的目标必须是依赖对象的依赖属性。
2、INotifyPropertyChanged接口,当对象实现了这个接口的时候,当数据源改变的时候可以通知UI同时实现改变,
实现原理:当为Binding设置了数据源后,Binding会自动侦听来自这个接口的事件。
public event PropertyChangedEventHandler PropertyChanged;
protected void FirePropertyChanged(string propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
然后在属性的Set访问器重使用
set
{
if (_age != value)
{
_age = value;
FirePropertyChanged("Age");
}
}
3、依赖属性:这类属性的值可以通过Binding依赖在其他对象的属性值上,被其他对象的属性值所驱动。
4、绑定路径(Path):需要绑定的值 (PropertyPath类型)
bind.Path = new PropertyPath("Name");//设定数据绑定的路径
还支持多级路径:Text={Binding Path=Text.Length,ElementName=textBox1,Mode=OneWay}
5、绑定模式:OneTime(初始化时的绑定,后面不会再改变)、OneWay(数据源改变UI改变,默认)TwoWay(双向绑定)
6、数据源(Source)的来源
a、普通CLR类型的单个对象:自定义的类或者.NET自带的类型;
b、集合类型:数组、List<T>、ObservableCollection<T>等
c、ADO.NET数据对象:DataTable和DataView等(Win8和WP都不支持)
d、使用XmlDataProvider把XML作为数据的来源(貌似win8不支持)
e、依赖对象(既可以作为源有可以作为绑定目标)
f、 把容器的DataContext指定为源:我们明知道从哪个属性获取数据,但是不知道具体把哪个对象作为Binding源。
g、ElementName作为数据源:元素之间的绑定
h、使用Binding类的RelativeSource属性:控件内部绑定(支持本身但是不支持层级相对绑定)
i、ObjectDataProvider对象指定为Source:当数据源的数据不是通过属性而是通过方法暴露给外界的时候。(貌似Win8不支持)
k、把使用LINQ检索得到的数据对象作为源。
7、转换器IValueConverter
Converter:从源到目标的转换
ConverterBack:从目标到源的转换
8、数据校验ValidationgRule 貌似win8和wp不支持,(如果有谁研究过,望回复一起研究下)
第七章 深入浅出话属性
1、静态字段在内存中只有一个拷贝,非静态字段则是每一个实例拥有一个拷贝,但无论方法是静态还是非静态,在内存中只会有一份拷贝,区别只是你只能
通过类名或者实例名来访问存放指令的内存
2、依赖属性:一种可以自己没有值,可以通过Binding从数据源获取得到值,拥有依赖属性的对象称为依赖对象,
节省实例对内存的开销
属性值通过Binding依赖在其他对象身上,既可以作为数据源有可以作为数据绑定目标
3、依赖属性对内存的使用方式:对象在创建的时候并不包含用于存储数据的空间(即字段所占用的空间)、只保留在需要用到数据的时候能够获得默认值、借用
其他对象数据或实时分配空间的能力。
a、依赖属性(DependencyProperty)必须以DependencyObject为宿主,通过它的SetValue和GetValue设置和获取值,
b、声明必须以 public static readonly开头
c、属性成员变量的名字后面要加上Property,以表明他是一个依赖属性
d、使用DependencyProperty.Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata)创建而不是new,
第一个参数用来指明用哪个CLR属性来作为这个依赖属性的包装器(包装器以实例属性暴露依赖属性)。
第二个参数用来指明依赖属性存储什么类型的值
第三个参数用来指明依赖属性的宿主是什么类型
//第一步:继承DependencyObject
class StudentDependency:DependencyObject
{
//第三步:使用CLR属性作为依赖属性的包装器
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
//第二步:注册依赖属性
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Name", typeof(string), typeof(StudentDependency), new PropertyMetadata(null));
}
4、附加属性:一个属性本来不属于某个对象,但是由于某种需求而被后来附加上,即把对象放入一个特定的环境后才具有的属性。
作用就是将属性与数据类型(宿主)解耦,让数据类型设计更加灵活
本质还是依赖属性,二者仅在包装器和注册上有点区别
//使用的是两个方法对属性进行赋值
public static int GetGrade(DependencyObject obj)
{
return (int)obj.GetValue(GradeProperty);
}
public static void SetGrade(DependencyObject obj, int value)
{
obj.SetValue(GradeProperty, value);
}
//使用的时RegisterAttached方法注册
public static readonly DependencyProperty GradeProperty =
DependencyProperty.RegisterAttached("Grade", typeof(int), typeof(SchoolAttachedProperty), new PropertyMetadata(0));