WPF 繫結中Converter的應用
阿新 • • 發佈:2019-01-26
在WPF 經常用到繫結,如果繫結的源資料和目標屬性是同類型的則不需要轉換。比如
<TextBox x:Name="txt1" Background="Blue" Text="測試"/>
<TextBox Background="{Binding ElementName=txt1,Path=Background}" Grid.Column="1"/>
如果是不同型別的資料我們要怎麼做呢?比如有一個文字框,一個按鈕,我一個文字框裡輸入一個的數字用來代表顏色,1表示“紅色”,2 表示“綠色”,3表示“藍色”。我輸入對應的數字,按鈕的文字顯示對應顏色。
顯然這個不是同類型的資料:文字框的資料是String型別,而按鈕的文字顏色是Brush型別,這個時候我們就需要用到轉換器(converter)來告訴我們的banding怎麼轉換我們的資料。首先定義一個轉換器(類),命名為Number2Color,要想實現轉換的功能,必須實現IValueConverter介面中的Convert和ConvertBack兩個函式。Convert函式是把我們的資料來源轉換為目標資料的方法,這裡就是把文字框裡的string型別轉換為Brush型別。我們這樣實現Convert函式,(引數value就是資料來源的值,這裡就是文字框中的資料,返回值就是Brush)
ConvertBak函式我們暫時先這樣實現public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { int colorValue = System.Convert.ToInt32(value); switch (colorValue) { case 1: //紅色 return new SolidColorBrush(Colors.Red); case 2: //綠色 return new SolidColorBrush(Colors.Green); case 3: //藍色 return new SolidColorBrush(Colors.Blue); } return new SolidColorBrush(Colors.LawnGreen); }
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return new NotImplementedException();
}
現在來到xaml程式碼,顯示一個文字框和一個按鈕,並把按鈕的前景色繫結到文字框的文字屬性上,使用自定義的Number2Color轉換器,執行程式 你修改文字框中的值,會看到按鈕顏色發生變化。
現在我們想實現如果按鈕的文字顏色發生改變,文字框中的文字也對應改變。新增3個按鈕,點選按鈕的時候改變“測試”按鈕的文字顏色。<Window x:Class="Converter.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cvt="clr-namespace:Converter" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <cvt:Number2Color x:Key="N2C"/> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="30"/> <RowDefinition Height="50"/> <RowDefinition/> </Grid.RowDefinitions> <TextBox x:Name="colorText" Text="1" BorderBrush="Gray" BorderThickness="2" Width="200" Grid.Row="1"/> <Button x:Name="testBtn" Content="測試" Width="100" Grid.Row="3" FontSize="25" Foreground="{Binding Path=Text,ElementName=colorText, Converter={StaticResource N2C}}"/> </Grid> </Window>
<StackPanel Orientation="Horizontal">
<Button Content="Red" Width="100" Foreground="Red" Click="btnClick"/>
<Button Content="Green" Width="100" Foreground="Green" Click="btnClick"/>
<Button Content="Blue" Width="100" Foreground="Blue" Click="btnClick"/>
</StackPanel>
private void btnClick(object sender, RoutedEventArgs e)
{
testBtn.Foreground = ((Button)sender).Foreground;
}
執行程式,點選按鈕,發現“測試”按鈕文字顏色是改變了,但是文字框中的文字沒有發生改變。這個和我們的繫結模式有關係,預設是單向繫結,我們應設定為雙向繫結,我們為繫結增加屬性:Mode=TwoWay
<Button x:Name="testBtn" Content="測試" Width="100" Grid.Row="3" FontSize="25" Foreground="{Binding Path=Text,ElementName=colorText, Converter={StaticResource N2C}, Mode=TwoWay}"/>
此時執行程式,點選按鈕發現,文字能變色,文字框內數字依然沒有改變,而且按鈕出現紅色邊框,提示錯誤。因為我們沒有告訴程式怎麼將Brush資料轉換為文字資料,這正是ConvertBack要做的事情。我們之前在實現這個函式的時候是丟擲一個異常,所有按鈕會出現紅色邊框,表示不允許逆向轉換。現在就讓我們告訴程式怎麼轉換資料
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush sb = (SolidColorBrush)value;
Color c = sb.Color;
if (c==Colors.Red)
{
return 1;
}
else if (c == Colors.Green)
{
return 2;
}
else if (c==Colors.Blue)
{
return 3;
}
return 0;
}
}
這樣就能實現雙向綁定了。
轉換器程式碼
namespace Converter
{
public class Number2Color:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int colorValue = System.Convert.ToInt32(value);
switch (colorValue)
{
case 1: //紅色
return new SolidColorBrush(Colors.Red);
case 2: //綠色
return new SolidColorBrush(Colors.Green);
case 3: //藍色
return new SolidColorBrush(Colors.Blue);
}
return new SolidColorBrush(Colors.LawnGreen);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush sb = (SolidColorBrush)value;
Color c = sb.Color;
if (c==Colors.Red)
{
return 1;
}
else if (c == Colors.Green)
{
return 2;
}
else if (c==Colors.Blue)
{
return 3;
}
return 0;
}
}
}
前臺程式碼
<Window x:Class="Converter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cvt="clr-namespace:Converter"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<cvt:Number2Color x:Key="N2C"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="30"/>
<RowDefinition Height="50"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox x:Name="colorText" Text="1" BorderBrush="Gray" BorderThickness="2" Width="200" Grid.Row="1"/>
<Button x:Name="testBtn" Content="測試" Width="100" Grid.Row="3" FontSize="25" Foreground="{Binding Path=Text,ElementName=colorText, Converter={StaticResource N2C}, Mode=TwoWay}"/>
<StackPanel Orientation="Horizontal">
<Button Content="Red" Width="100" Foreground="Red" Click="btnClick"/>
<Button Content="Green" Width="100" Foreground="Green" Click="btnClick"/>
<Button Content="Blue" Width="100" Foreground="Blue" Click="btnClick"/>
</StackPanel>
</Grid>
</Window>
按鈕點選程式碼
private void btnClick(object sender, RoutedEventArgs e)
{
testBtn.Foreground = ((Button)sender).Foreground;
}