【WPF】Binding和MultiBinding数据绑定:Converter的使用(IValueConverter/IMultiValueConverter)
Binding和MultiBinding中存在一个Converter属性,可以用来对绑定的数据进行一些处理后,转换成页面需要的数据。
Converter属性在MultiBinding中使用更加常见,将多个属性值转成UI需要的单个值。
Binding Converter
举例
下面举例同一显示效果的两种写法,来展示Converter的用法
存在需求
下拉框需要满足editType!="不可修改"&&valueType==“Option”
条件才能可见,否则都是不可见状态。
常规写法
使用两组MultiDataTrigger来实现
xaml部分
<ComboBox ItemsSource="{Binding valueOptions}"
SelectedItem="{Binding selectedOptionItem}">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding valueType}"
Value="Option"/>
<Condition Binding="{Binding editType}"
Value="任意修改"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding valueType}"
Value="Option"/>
<Condition Binding="{Binding editType}"
Value="停机修改"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Visibility" Value="Visible"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding fullDetail}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
cs部分
public string editType{get;set;}
public string valueType{get;set;}
Converter写法
cs部分新增bool类型
public string editType{get;set;}
public string valueType{get;set;}
public bool IsCheckBoxVisibility
{
get {
return valueType == ValueTypeEnum.Option && editType != "不可修改";
}
}
IValueConverter接口的Visibility实现
public class VisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool isVisible && isVisible)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
xaml中使用VisibilityConverter
<UserControl.Resources>
<local:VisibilityConverter x:Key="VisibilityConverter"/>
</UserControl.Resources>
<ComboBox ItemsSource="{Binding valueOptions}"
SelectedItem="{Binding selectedOptionItem}"
Visibility="{Binding IsCheckBoxVisibility,Converter={StaticResource VisibilityConverter}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding fullDetail}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
更多Converter
根据举例可以简单理解Converter的应用场景和优势,同时VisibilityConverter是可以复用的,当同一工程中出现类似的情况,可以复用此Converter。
接下来补充一些常见的Converter
BytesToStringConverter
字节数组转字符串Converter,当我们获取的数据是一串字节数组时,需要将字节数组变成字符串显示要页面上。
<TextBox Text="{Binding Content,Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource BytesToStringConverter}}" />
public byte[] Content{get;set;}
public class BytesToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is byte[])) { return null; }
byte[] bytes = value as byte[];
string str = System.Text.Encoding.Default.GetString(bytes);
return str.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is string)) { return null; }
byte[] bytes = System.Text.Encoding.Default.GetBytes(value as string);
return bytes;
}
}
自适应宽度转换器WidthConverter
需要某控件的宽度根据另一控件的宽度变化,如Button宽度是其外面Border宽度的1/3
<Border Name="border" Margin="50" BorderBrush="Black" BorderThickness="2">
<Button Content="宽是边框的1/3 长=宽"
Width="{Binding ElementName=border, Path=ActualWidth,
Converter={StaticResource widthconverter}}"
Height="{Binding RelativeSource={RelativeSource Mode=Self},
Path=Width}"></Button>
</Border>
public class WidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// 返回宽度的 1/3
return (double)value / 3;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
MultiBinding Converter
多重绑定(Multibinding)允许开发者将一个属性绑定到多个源属性。这种绑定通常与转换器(Converter)一起使用,转换器负责将多个源属性的值合并为目标属性可以接受的单个值。
Converter
简单例子
拼接字符串
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
public class NameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return $"{values[0]} {values[1]}";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
var fullName = ((string)value).Split(' ');
return new object[] { fullName[0], fullName[1] };
}
}
应用
表格中存在一个单元格的背景颜色需要根据值的情况来设置,首先表格每行中存在设定值、当前值和出厂值, 存在修改类型,存在更新状态。
要求设定值所在单元格的背景颜色根据如下情况进行变化。
1、设定值和当前值不同:#FFE4E1;
2、设定值和出厂值不同:#EFE4B0;
3、修改类型为不可修改:#B0B0B0;
4、更新状态为更新失败:#FEC8F1;
<TextBlock.Background>
<MultiBinding Converter="{StaticResource SetValueBackgroundConverter}">
<Binding Path="setValue" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="curValue" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="defaultValue" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="editType" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="updateStatus" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</TextBlock.Background>
public class SetValueBackgroundConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
object setValue = values[0];
object curValue = values[1];
object defaultValue = values[2];
string editType = values[3].ToString();
string updateStatus = values[4].ToString();
if (editType == "不可修改") return new SolidColorBrush((Color)ColorConverter.ConvertFromString("#B0B0B0"));
if (updateStatus == "更新失败") return new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FEC8F1"));
if (setValue.ToString() != "--" && setValue.ToString() != curValue.ToString()) return new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFE4E1"));
if (setValue.ToString() != "--" && setValue.ToString() != defaultValue.ToString()) return new SolidColorBrush((Color)ColorConverter.ConvertFromString("#EFE4B0"));
return Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}