书名:WPF专业编程指南
作者:李应保
出版社:电子工业出版社
出版时间:2010-01
ISBN:9787121100116
数据绑定
一、开发自己的IValueConverter
- 与控件模板需要转换数据类型一样,在进行数据绑定时,有时候目标对象和源对象间的数据类型是不同的,需要对数据类型进行转化。
WPF提供了一些默认的转换,例如,颜色值和画刷间的转换。
但任何系统都没法包括现实中所有的类型转换,解决方法是让程序员根据需要提供自己的类型转换。
二、两件事
- 程序员为Binding类提供类型转换时需要做两件事:
一是开发一个支持IValueConverter接口的类;
二是把这个类的实例赋给Binding类中的Converter。
WPF在传递数据时自动调用IValueConverter的Convert和ConvertBack方法:
public class MyConverter: IValueConverter
{
public object Convert( object value, Type typeTarget,
object param, CultureInfo culture)
{
…
}
public object ConvertBack( object value Type typeTarget,
object param, CultureInfo culture)
{
…
}
}
- 其中,参数value是要转换的值,typeTarget是要转换后的值的类型。
如果无法转换该Value的值,则Convert和ConvertBack应返回null。
参数param是为Binding类中的ConvertParameter准备的,CultureInfo是某些情况下,转换可能要涉及语言环境,比如说100.35,在德语和法语里应为“100,35”。
三、C#里使用
- 在C#里使用自定义Converter类,只要把自定义的Convert值连接到Bingding类中的Convert属性即可:
Binding myBinding = new Binding();
myBinding. Convert = new MyConverter();
四、XAML中使用
- 在XAML中使用自定义类型转换,你需要:
- 在Resources中加入自定义Converter类:
<srcLMyConverter x: key="conv" />
- 在Binding中,加上Converter属性:
<…. "{Binding.Converter= {StaticResource conv}…}"
五、例子
- 现在,让我们来看一个完整使用自定义类型转化的例子。
AmountMoneyConvert类移植了IValueConverter接口,把用户输入的数字转换成两位小数的字符串,这个数字的物理意义是用户在银行户头上的存款余额,对于普通储户来说,存款余额只需要精确到两位小数(即几分钱“)。
在AmountMoneyConvert类前面加上了ValueConversion属性,ValueConversion属性的作用是告诉WPF AmountMoneyConvert类可以转换的源数据和目标数据的类型。
在Convert方法中,首先把value转换成字符串,若该字符串为空,则返回0.0。这是为了支持TextBox中的值为空Null的情形。
namespace Yingbao.Chapter11.BindingWithConverter
{
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
[ValueConversion(typeof(string), typeof(string))]
public class AmountMoneyConvert : IValueConverter
{
public object Convert(object value, Type typeTarget,
object param, CultureInfo culture)
{
string inputValue = value.ToString();
if (inputValue.Length == 0) return 0.00;
Decimal num = System.Convert.ToDecimal(value);
if (param != null)
{
num = Decimal.Round(num,
Int32.Parse(param as string));
}
return num;
}
public object ConvertBack(object value,
Type typeTarget, object param, CultureInfo culture)
{
return value; // we don't need to do anything
}
}
}
- 这里用param来表示在进行字符串转换时所要保留的小数位数,下面这段XAML程序使用了AmountMoneyConvert类:
<Window x:Class="Yingbao.Chapter11.BindingWithConverter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src=
"clr-namespace:Yingbao.Chapter11.BindingWithConverter"
Title="自定义转换的数据绑定" Height="150" Width="300">
<Window.Resources>
<src:AmountMoneyConvert x:Key="amtConv"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width ="120"/>
<ColumnDefinition Width ="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height ="25" />
<RowDefinition Height ="25" />
</Grid.RowDefinitions>
<Label Content ="输入存款:" FontSize ="14" Grid.Row="0"
Grid.Column ="0"/>
<TextBox Name="InputAmt" HorizontalAlignment ="Center"
FontSize ="10" Width ="130"
Height ="18" Grid.Row ="0" Grid.Column ="1"/>
<Label Content ="转换后的存款:" FontSize ="14" Grid.Row="1"
Grid.Column ="0"/>
<TextBox HorizontalAlignment ="Center" FontSize ="10"
Width ="130" Height ="18" Grid.Row ="1" Grid.Column ="1"
Text ="{Binding ElementName=InputAmt, Path=Text,
Mode=OneWay, Converter={StaticResource
amtConv },ConverterParameter=2}" />
</Grid>
</Window>
-
程序使用了两个字符输入框TextBox,第一个字符输入框是源对象,第二个字符输入框被绑定到第一个字符输入框上,绑定模式为OneWay,即第一个TextBox输入的值InputAmt会影响第二个TextBox。
若第一个TextBox中输入的值为多个小数点的小数,则第二个TextBox中只显示带有两位小数点的小数值。其结果如图11-4所示:
图11-4 使用自定义转换
