Binding类,主要是用于数据绑定,它包含了一系列可用的属性、方法,已经使用过的总结如下:
1、Source:数据来源对象,可以是自定义的类或者是控件
2、ElementName:数据来源控件名称
3、Path:数据绑定路径,用于数据绑定的属性需要是依赖属性,或者完成自动更新机制的属性【通过实现INotifyPropertyChanged】
其实对于这个类还有别的属性和方法,总结如下:
第一部分、转换器【实现接口:IValueConverter】
转换器实际上就是对于绑定的属性的值进行转换,它可以用在这样的场景:
数据库对于性别存储的是一个1、0值,所以绑定到相关的控件时候要根据性别显示不同的文字“男”、“女”,所以要做一个转换,可以这样做:
A、在sql语句中完成
B、使用诸如:sex == 1 ?“男”:“女”这样的表达式
C、使用数据绑定转换器
1、要使用转换器的话,需要自定义一个继承并实现了IValueConverter的类,其具体代码如下:
2、XAML代码如下:
3、结果如下:
从流程上看,转换器是在数据绑定之后进行的,可以看到在自定义的转换类CustomizeConverter的函数Convert中有几行被注释的代码,如果在这个例子中那这几行代码放开的话,代码中定义的异常会被抛出,这是因为:
A、Label首先绑定属性Sex
B、将Label将属性Content作为函数Convert的第一个参数value传入方法,同时这个属性的类型将作为参数targetType传入
C、由于Label将属性Content得属性是Object,所以不管绑定的数据是什么,这个异常throw new Exception("输入的数据类型必须是Int32类型的数据");将一定抛出
另外,自定义的转换类CustomizeConverter的函数Convert中还包含了parameter参数,其类型是Object,这个参数所对应的是Binding类的ConverterParameter属性。
所以当我们在Label的绑定中修改成如下代码的时候,增加了【ConverterParameter=1】:
其他代码不变,结果会改变成如下:
之所以会这样,是因为在定义转换类CustomizeConverter的时候,首先判断了参数parameter,当parameter不为空的时候就根据这个参数的值作出相应的转换。
第二部分、数据绑定模式
之前的数据绑定,都是从数据源 -> 目标对象的绑定,也就是更新了数据源的相关属性,目标对象也会发生相应的改变。
但是实际上,对于Binding类而言,绑定的模式有4种,可以使用Mode属性进行设置:
A、OneWay : 当数据源改变时,目标对象会被更新。
B、TwoWay : 顾名思义,就是数据源和目标对象任意一方改变时,另一方就会改变。
C、OneWayToSource : 和A相反,当目标对象改变的时候,数据源将会改变。
D、OneTime : 只在数据源初始化的时候,绑定一次到目标对象上,之后两者没有关系。
因为存在了双向的绑定,所以对于何时触发类似于目标对象改变的时候通知数据源的方式,Binding也给出了三种方式,可以使用UpdateSourceTrigger属性进行设置:
A、PropertyChanged : 只要值被改变,立即触发。
B、LostFocus : 当包含值的对象失去焦点【一般是控件】的时候,立即触发。
C、Explicit: 调用BindingExpression.UpdateSource方法,来触发更新。
所以,根据以上内容,可以将第一部分代码更新成
1、XAML的部分:
这一次在Grid中增加了两行,同时将第二列第一行的Label控件更改成TextBox控件,然后在TextBox控件上指明Mode以及UpdateSourceTrigger属性的值,最后还添加了一个按钮,以及为按钮添加单击事件。
2、单击事件的代码:
3、运行结果:
A、Onload之后的结果
可以看到,TextBox和Label中的值都是空的,这是因为TextBox的绑定模式是OneWayToSource,而初始化的时候控件的Text属性是空的,所以,导致数据眼为空。
B、当在文本框中输入文本的结果
这个结果显示了,当文本框的文本属性被更新后,数据源也会被更新,而Label的文本来源和文本框使用的是同一个,所以这个时候Label的文本也会被改变。
C、当点击按钮后的结果
可以看出,TextBox的文本没有改变,正是由于其绑定模式决定的,而Label的文本改变了,因为它使用的是默认的绑定模式。
第三部分、验证器【ValidationRule】
转换器更多充当一个适配器的角色,而验证器就是在数据绑定之后,转换之前对数据进行验证。
1、可以自定义一个实现ValidationRule的验证器类,代码如下:
ValidationRule是一个抽象类,只需要实现一个方法即可使用,返回的是一个ValidationResult对象,包含了验证的所有信息。
2、XAML的代码如下:
这一次修改的仍然是绑定Name属性的TextBox控件,和之前不一样的是,这一次将把Binding作为一个节点使用,而不是一个属性。
主要修改了几个部分:
A、为Binding指明了NotifyOnValidationError属性,这样当出现验证不通过的信息的时候将会触发相关事件。
B、为TextBox指明了Validation.Error事件,这个事件主要用于处理验证失败时的信息。
C、将自定义的CustomizeValidationRule绑定到Binding的ValidationRules节点中。
3、Validation.Error事件的代码如下:
只是简单的显示验证错误信息,该信息是自定义类中的"名称当中不可包含数字"的信息。
4、运行结果
A、当输入一个数字的时候:
但是这里会有一个问题,就是在错误信息“1”的基础上在输入一个“1”的时候,消息对话框将弹出两次,这是因为处理验证异常的方法
TextBox_Error的参数e.Error.ErrorContent在处理完一次之后仍会包含这个信息,所以无论后面输入的信息是否合法,第一次非法的信息都将会存在,所以要对这个对象进行Null的处理,代码如下:
下一节将总结Binding的其他属性的用途