什么是值转换器
在WPF(Windows Presentation Foundation)中,值转换器(Value Converter)是一种机制,允许你在绑定时转换绑定源和绑定目标之间的值。值转换器实现了 IValueConverter
接口,该接口包含两个方法:Convert
和 ConvertBack
。这两个方法分别用于在绑定源到目标时进行值转换,以及在目标到源时进行值转换。
使用值转换器的Demo
首先创建一个绑定数据源类:
using System; using System.ComponentModel; namespace BindConversion { public class MyData : INotifyPropertyChanged { private DateTime _thedate; public MyData() { _thedate = DateTime.Now; } public DateTime TheDate { get { return _thedate; } set { _thedate = value; OnPropertyChanged("TheDate"); } } // Declare event public event PropertyChangedEventHandler PropertyChanged; // OnPropertyChanged method to update property value in binding private void OnPropertyChanged(string info) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info)); } } }
有一个类型为DateTime
的属性TheDate
,该类实现了INotifyPropertyChanged
接口。
再创建一个转换器类:
using System; using System.Globalization; using System.Windows.Data; using System.Windows.Media; namespace BindConversion { public class MyConverter : IValueConverter { public object Convert(object o, Type type, object parameter, CultureInfo culture) { var date = (DateTime) o; switch (type.Name) { case "String": return date.ToString("F", culture); case "Brush": return Brushes.Red; default: return o; } } public object ConvertBack(object o, Type type, object parameter, CultureInfo culture) => null; } }
该类实现了IValueConverter
接口。
IValueConverter介绍
如果要将值转换器与绑定相关联,请创建实现 接口的 IValueConverter 类, Convert 然后实现 和 ConvertBack 方法。 转换器可以将数据从一种类型更改为另一种类型,根据文化信息转换数据,或修改演示文稿的其他方面。
值转换器具有区域性感知能力。 Convert和 ConvertBack 方法都有一个culture
参数,用于指示区域性信息。 如果区域性信息与转换无关,则可以在自定义转换器中忽略该参数。
该接口有两个方法Convert
与ConvertBack
。
public object Convert (object value, Type targetType, object parameter, System.Globalization.CultureInfo culture);
中各参数的含义如下所示:
参数 | 类型 | 含义 |
value | object | 绑定源生成的值。 |
targetType | Type | 绑定目标属性的类型。 |
parameter | object | 要使用的转换器参数。 |
culture | CultureInfo | 要用在转换器中的区域性。 |
再看一下MainWindow.xaml:
<Window x:Class="BindConversion.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BindConversion" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <StackPanel Width="300" Height="300" Name="Page1"> <StackPanel.Resources> <local:MyData x:Key="MyDataSource"/> <local:MyConverter x:Key="MyConverterReference"/> <Style TargetType="TextBlock"> <Setter Property="FontSize" Value="15"/> <Setter Property="Margin" Value="3"/> </Style> </StackPanel.Resources> <StackPanel.DataContext> <Binding Source="{StaticResource MyDataSource}"/> </StackPanel.DataContext> <TextBlock Text="Unconverted data:"/> <TextBlock Text="{Binding Path=TheDate}"/> <TextBlock Text="Converted data:"/> <TextBlock Name="myconvertedtext" Foreground="{Binding Path=TheDate, Converter={StaticResource MyConverterReference}}"> <TextBlock.Text> <Binding Path="TheDate" Converter="{StaticResource MyConverterReference}"/> </TextBlock.Text> </TextBlock> </StackPanel> </Window>
首先定义了资源:
<StackPanel.Resources> <local:MyData x:Key="MyDataSource"/> <local:MyConverter x:Key="MyConverterReference"/> <Style TargetType="TextBlock"> <Setter Property="FontSize" Value="15"/> <Setter Property="Margin" Value="3"/> </Style> </StackPanel.Resources>
一个名为MyDataSource
类型为MyData
的资源与一个名为MyConverterReference
类型为MyConverter
的资源。
我们发现有三处地方用到了Binding
:
<Binding Source="{StaticResource MyDataSource}"/>
这种形式我们已经见过了。
<TextBlock Name="myconvertedtext" Foreground="{Binding Path=TheDate, Converter={StaticResource MyConverterReference}}">
<Binding Path="TheDate" Converter="{StaticResource MyConverterReference}"/>
注意,这两处Binding
中都出现了Converter
。
Converter介绍
通过实现 IValueConverter 接口并实现 Convert 方法创建转换器。 该方法应返回一个对象,该对象的类型与绑定所面向的依赖属性的类型相同,或者至少返回一个可隐式强制转换或转换为目标类型的类型。
再结合这段代码:
public object Convert(object o, Type type, object parameter, CultureInfo culture) { var date = (DateTime) o; switch (type.Name) { case "String": return date.ToString("F", culture); case "Brush": return Brushes.Red; default: return o; } }
根据目标类型的不同,进行不同的转换。
TextBlock.Foreground
的类型为Brush
就返回Brushes.Red
。
TextBlock.Text
的类型为String
就返回date.ToString("F", culture)
。
结果如下图所示:
Demo代码来源
[WPF-Samples/Data Binding/BindConversion at main · microsoft/WPF-Samples (github.com)](https://github.com/microsoft/WPF-Samples/tree/main/Data Binding/BindConversion)