書名:WPF專業(yè)編程指南
作者:李應(yīng)保
出版社:電子工業(yè)出版社
出版時(shí)間:2010-01
ISBN:9787121100116
數(shù)據(jù)綁定
一、開發(fā)自己的IValueConverter
- 與控件模板需要轉(zhuǎn)換數(shù)據(jù)類型一樣,在進(jìn)行數(shù)據(jù)綁定時(shí),有時(shí)候目標(biāo)對(duì)象和源對(duì)象間的數(shù)據(jù)類型是不同的,需要對(duì)數(shù)據(jù)類型進(jìn)行轉(zhuǎn)化。
WPF提供了一些默認(rèn)的轉(zhuǎn)換,例如,顏色值和畫刷間的轉(zhuǎn)換。
但任何系統(tǒng)都沒法包括現(xiàn)實(shí)中所有的類型轉(zhuǎn)換,解決方法是讓程序員根據(jù)需要提供自己的類型轉(zhuǎn)換。
二、兩件事
- 程序員為Binding類提供類型轉(zhuǎn)換時(shí)需要做兩件事:
一是開發(fā)一個(gè)支持IValueConverter接口的類;
二是把這個(gè)類的實(shí)例賦給Binding類中的Converter。
WPF在傳遞數(shù)據(jù)時(shí)自動(dòng)調(diào)用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)
{
…
}
}
- 其中,參數(shù)value是要轉(zhuǎn)換的值,typeTarget是要轉(zhuǎn)換后的值的類型。
如果無法轉(zhuǎn)換該Value的值,則Convert和ConvertBack應(yīng)返回null。
參數(shù)param是為Binding類中的ConvertParameter準(zhǔn)備的,CultureInfo是某些情況下,轉(zhuǎn)換可能要涉及語言環(huán)境,比如說100.35,在德語和法語里應(yīng)為“100,35”。
三、C#里使用
- 在C#里使用自定義Converter類,只要把自定義的Convert值連接到Bingding類中的Convert屬性即可:
Binding myBinding = new Binding();
myBinding. Convert = new MyConverter();
四、XAML中使用
- 在XAML中使用自定義類型轉(zhuǎn)換,你需要:
- 在Resources中加入自定義Converter類:
<srcLMyConverter x: key="conv" />
- 在Binding中,加上Converter屬性:
<…. "{Binding.Converter= {StaticResource conv}…}"
五、例子
- 現(xiàn)在,讓我們來看一個(gè)完整使用自定義類型轉(zhuǎn)化的例子。
AmountMoneyConvert類移植了IValueConverter接口,把用戶輸入的數(shù)字轉(zhuǎn)換成兩位小數(shù)的字符串,這個(gè)數(shù)字的物理意義是用戶在銀行戶頭上的存款余額,對(duì)于普通儲(chǔ)戶來說,存款余額只需要精確到兩位小數(shù)(即幾分錢“)。
在AmountMoneyConvert類前面加上了ValueConversion屬性,ValueConversion屬性的作用是告訴WPF AmountMoneyConvert類可以轉(zhuǎn)換的源數(shù)據(jù)和目標(biāo)數(shù)據(jù)的類型。
在Convert方法中,首先把value轉(zhuǎn)換成字符串,若該字符串為空,則返回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來表示在進(jìn)行字符串轉(zhuǎn)換時(shí)所要保留的小數(shù)位數(shù),下面這段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="自定義轉(zhuǎn)換的數(shù)據(jù)綁定" 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 ="轉(zhuǎn)換后的存款:" 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>
-
程序使用了兩個(gè)字符輸入框TextBox,第一個(gè)字符輸入框是源對(duì)象,第二個(gè)字符輸入框被綁定到第一個(gè)字符輸入框上,綁定模式為OneWay,即第一個(gè)TextBox輸入的值InputAmt會(huì)影響第二個(gè)TextBox。
若第一個(gè)TextBox中輸入的值為多個(gè)小數(shù)點(diǎn)的小數(shù),則第二個(gè)TextBox中只顯示帶有兩位小數(shù)點(diǎn)的小數(shù)值。其結(jié)果如圖11-4所示:
圖11-4 使用自定義轉(zhuǎn)換
