1. 前文
在普遍的也业务系统中, 数据要驱动到操作的用户界面, 它实际储存的方式和表达方式会多种多样, 数据库存储的数字 0或1, 在界面用户看到显示只是 成功或失败, 或者存储的字符、或更多的格式,
但是最终到界面上, 一般是需要一个转换, 至于这个转换是在数据库中, 还是业务代码中, 都是一个必不可少的操作。
2. WPF转换器 ( IValueConverter )
WPF中, 提供一种数据转换的接口、那就是在 System.Windows.Data 命名空间下的, IValueConverter 接口, 改接口的Convert方法可以任意的数据转换操作。
namespace System.Windows.Data { // // 摘要: // 提供将自定义逻辑应用于绑定的方法。 public interface IValueConverter { // // 摘要: // 转换值。 // // 参数: // value: // 绑定源生成的值。 // // targetType: // 绑定目标属性的类型。 // // parameter: // 要使用的转换器参数。 // // culture: // 要用在转换器中的区域性。 // // 返回结果: // 转换后的值。 如果该方法返回 null,则使用有效的 null 值。 object Convert(object value, Type targetType, object parameter, CultureInfo culture); // // 摘要: // 转换值。 // // 参数: // value: // 绑定目标生成的值。 // // targetType: // 要转换为的类型。 // // parameter: // 要使用的转换器参数。 // // culture: // 要用在转换器中的区域性。 // // 返回结果: // 转换后的值。 如果该方法返回 null,则使用有效的 null 值。 object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture); } }
3.如何使用转换器
为了更够简单的描述其作用, 在后台声明一个int类型为 Status的变量, 然后通过绑定的形式关联的界面层。( 如下创建MainViewModel层,主要用于关联DataContext )
public class MainViewModel : ViewModelBase { /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel() { } private int status; /// <summary> /// 状态 0 / 1 /// </summary> public int Status { get { return status; } set { status = value; RaisePropertyChanged(); } } }
用户界面绑定的Status字段, 为了能够看到实际效果, 用了相同的字段绑定两个进行比较, 如下
<UniformGrid Rows="2" Columns="2" > <TextBlock Text="没有使用转换器的效果:" Style="{DynamicResource TextBlockStyle}" /> <TextBlock Text="{Binding Status}" Style="{DynamicResource TextBlockStyle}"/> <TextBlock Text="使用转换器的效果:" Style="{DynamicResource TextBlockStyle}"/> <TextBlock Text="{Binding Status,Converter={StaticResource StatusConverter}}" Style="{DynamicResource TextBlockStyle}"/> </UniformGrid>
声明一个 StatusConverter 转换器 , 改转换器实现了,将数据 0 设置为未完成, 为1 则设置为完成。
public class StatusConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value != null && int.TryParse(value.ToString(), out int result)) { if (result == 1) { return "完成"; } } return "未完成"; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
界面层引用改转换器, 完整代码, 红色加粗部分为引用声明的转换器。
<Window x:Class="WpfApp4.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:WpfApp4" xmlns:converter="clr-namespace:WpfApp4.Converter" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <converter:StatusConverter x:Key="StatusConverter"/> <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}"> <Setter Property="TextWrapping" Value="NoWrap"/> <Setter Property="TextTrimming" Value="None"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="FontSize" Value="25"/> </Style> </Window.Resources> <Grid> <UniformGrid Rows="2" Columns="2" > <TextBlock Text="没有使用转换器的效果:" Style="{DynamicResource TextBlockStyle}" /> <TextBlock Text="{Binding Status}" Style="{DynamicResource TextBlockStyle}"/> <TextBlock Text="使用转换器的效果:" Style="{DynamicResource TextBlockStyle}"/> <TextBlock Text="{Binding Status,Converter={StaticResource StatusConverter}}" Style="{DynamicResource TextBlockStyle}"/> </UniformGrid> </Grid> </Window>
测试效果 :
结尾:
WPF中, 还有一种转换器, 同样是位于 System.Windows.Data命名空间的 IMultiValueConverter 接口, 通过ILSpy可以查看到,如下所示:
IMultiValueConverter 的作用则可能进行多个数据源绑定, 这种骚操作称之为, 多路绑定, 根据多个数据库来决定最后显示的内容。
后面会单独一篇文章介绍IMultiValue的使用场景和使用方法。