WPF进行数据绑定时,不同类型的数据是不能直接绑定的,需要将数据类型进行转换,数据转换包括单值转换和多值转换。
转换器的创建非常简单,只需要新建一个类,以IValueConverter(单值转换)或IMultiValueConverter(多值转换)为基类即可。如:
public class MyConver : IValueConverter //单值转换
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return DependencyProperty.UnsetValue;
string str = (string)value;
return "(" + str.Split(',').Length + ")";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class MyMultiConver : IMultiValueConverter //多值转换
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length < 3)
return null;
int a = ((string)values[0]).Split(',').Length;
int b = ((string)values[1]).Split(',').Length;
int c = ((string)values[2]).Split(',').Length;
if (!(a == b && a == c))
{
return new SolidColorBrush(Colors.Red);
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class MyErrorConver : IValueConverter //单值转换
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
Array.ConvertAll(((string)value).Split(','), s => double.Parse(s));
}
catch
{
return new SolidColorBrush(Colors.Red);
}
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
以上代码中,MyConver类是将字符串转换成以逗号分隔之后的长度;MyMultiConver类是分别将三个字符串各取以逗号分隔之后的长度,并判断是否相等,如果不等则返回红色;MyErrorConver类是将字符串以逗号分隔并转换成数字,如果转换错误则返回红色。
转换器创建好之后,接下来就要使用转换器了。在xaml代码中:
<Window.Resources>
<local:MyConver x:Key="cvtLength"/>
<local:MyMultiConver x:Key="cvtColor"/>
<local:MyErrorConver x:Key="cvtErrorColor"/>
<Style x:Key="txtStyle" TargetType="TextBox">
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="5,0,0,0"/>
<Setter Property="InputMethod.IsInputMethodEnabled" Value="False"/>
</Style>
<Style x:Key="gStyle" TargetType="Grid">
<Setter Property="Margin" Value="5"/>
</Style>
<Style x:Key="lblStyle" TargetType="Label">
<Setter Property="Margin" Value="-15,0,0,0"/>
<Setter Property="Grid.Column" Value="1"/>
<Setter Property="Foreground">
<Setter.Value>
<MultiBinding Converter="{StaticResource cvtColor}">
<Binding ElementName="txtRadii" Path="Text"/>
<Binding ElementName="txtEnergy" Path="Text"/>
<Binding ElementName="txtHeight" Path="Text"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
引用Window.Resources,定义所有转换器。
<StackPanel Margin="0,5,0,0">
<Grid Style="{StaticResource gStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="每圈半径" Foreground="{Binding ElementName=txtRadii,Path=Text,Converter={StaticResource cvtErrorColor}}"/>
<Label Style="{StaticResource lblStyle}" Content="{Binding ElementName=txtRadii,Path=Text,Converter={StaticResource cvtLength}}"/>
<TextBox Name="txtRadii" Grid.Column="2" Text="0,10" Style="{StaticResource txtStyle}" PreviewMouseDoubleClick="txtRadii_PreviewMouseDoubleClick"/>
</Grid>
<Grid Style="{StaticResource gStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="每圈能量" Foreground="{Binding ElementName=txtEnergy,Path=Text,Converter={StaticResource cvtErrorColor}}"/>
<Label Style="{StaticResource lblStyle}" Content="{Binding ElementName=txtEnergy,Path=Text,Converter={StaticResource cvtLength}}"/>
<TextBox Name="txtEnergy" Grid.Column="2" Text="1,1" Style="{StaticResource txtStyle}" MouseDoubleClick="txtRadii_PreviewMouseDoubleClick"/>
</Grid>
<Grid Style="{StaticResource gStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="每圈高度" Foreground="{Binding ElementName=txtHeight,Path=Text,Converter={StaticResource cvtErrorColor}}"/>
<Label Style="{StaticResource lblStyle}" Content="{Binding ElementName=txtHeight,Path=Text,Converter={StaticResource cvtLength}}"/>
<TextBox Name="txtHeight" Grid.Column="2" Text="0.02,0.01" Style="{StaticResource txtStyle}" MouseDoubleClick="txtRadii_PreviewMouseDoubleClick"/>
</Grid>
<Button Name="btnStart" Content="开始生成" Width="100" Height="40" Click="BtnStart_Click"/>
</StackPanel>