在 WPF(Windows Presentation Foundation)中,Converter(转换器) 是实现 数据绑定(Data Binding) 时对源数据和目标 UI 元素之间进行值转换的关键机制。它通过实现 IValueConverter(单向/双向)或 IMultiValueConverter(多绑定)接口,让你可以灵活控制数据如何显示或如何从用户输入反向更新。


一、为什么需要 Converter?

WPF 数据绑定要求源属性和目标属性类型兼容。但现实中经常遇到:

  • 布尔值 → 控件可见性(trueVisiblefalseCollapsed
  • 数字 → 颜色(如:0~100 分数 → 红/黄/绿)
  • 枚举值 → 图标或文本
  • 空字符串 → 占位符文本

这时就需要 Converter 来“翻译”数据。


二、核心接口

1. IValueConverter(最常用)

public interface IValueConverter
{
object Convert(object value, Type targetType, object parameter, CultureInfo culture);
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
  • Convert:从 数据源 → UI(例如:ViewModel 的 bool IsOnline → UI 的 Visibility
  • ConvertBack:从 UI → 数据源(例如:用户输入的文本 → ViewModel 的 DateTime

⚠️ 如果只用于显示(OneWay 绑定),可只实现 ConvertConvertBack 抛出 NotImplementedException


2. IMultiValueConverter

用于 MultiBinding,将多个输入值合并为一个输出值。

public interface IMultiValueConverter
{
object Convert(object[] values, Type targetType, object parameter, CultureInfo culture);
object[,] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture);
}

三、实战示例

✅ 示例 1:布尔值 → 可见性(BooleanToVisibilityConverter)

WPF 内置了这个转换器,但我们可以自己实现一个更灵活的版本:

// BooleanToVisibilityConverter.cs
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool boolValue)
{
// 支持取反:当 Parameter="invert" 时,true→Collapsed
bool invert = parameter?.ToString()?.ToLower() == "invert";
bool result = invert ? !boolValue : boolValue;
return result ? Visibility.Visible : Visibility.Collapsed;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Visibility visibility)
{
bool invert = parameter?.ToString()?.ToLower() == "invert";
bool isVisible = visibility == Visibility.Visible;
return invert ? !isVisible : isVisible;
}
return false;
}
}
在 XAML 中使用:
<Window x:Class="MyApp.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:MyApp.Converters">
<Window.Resources>
  <local:BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
<StackPanel>
  <TextBlock Text="在线状态:" />
    <TextBlock Text="✅ 在线"
    Visibility="{Binding IsOnline, Converter={StaticResource BoolToVis}}"/>
    <TextBlock Text="❌ 离线"
    Visibility="{Binding IsOnline, Converter={StaticResource BoolToVis}, ConverterParameter=invert}"/>
</StackPanel>
</Window>

✅ 示例 2:数值 → 颜色(分数评级)

public class ScoreToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double score)
{
if (score >= 90) return Brushes.Green;
if (score >= 60) return Brushes.Orange;
return Brushes.Red;
}
return Brushes.Gray;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException(); // 只用于显示
}
}

XAML 使用:

<Window.Resources>
  <local:ScoreToColorConverter x:Key="ScoreToColor"/>
</Window.Resources>
  <TextBlock Text="{Binding StudentScore}"
  Foreground="{Binding StudentScore, Converter={StaticResource ScoreToColor}}"/>

✅ 示例 3:空值/空字符串 → 占位符文本

public class NullToPlaceholderConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string input = value as string;
string placeholder = parameter as string ?? "(未填写)";
return string.IsNullOrWhiteSpace(input) ? placeholder : input;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string input = value as string;
return string.IsNullOrWhiteSpace(input) ? null : input;
}
}

XAML:

<TextBlock Text="{Binding UserName, Converter={StaticResource NullToPlaceholder}, ConverterParameter='请输入姓名'}"/>

✅ 示例 4:多值转换(IMultiValueConverter)—— 拼接姓名

public class FullNameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
string firstName = values[0] as string ?? "";
string lastName = values[1] as string ?? "";
return $"{firstName} {lastName}".Trim();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
string fullName = value as string;
var parts = fullName?.Split(' ', 2) ?? new string[2];
return new object[] { parts.FirstOrDefault(), parts.Skip(1).FirstOrDefault() };
}
}

XAML:

<Window.Resources>
  <local:FullNameConverter x:Key="FullNameConv"/>
</Window.Resources>
<TextBlock>
  <TextBlock.Text>
      <MultiBinding Converter="{StaticResource FullNameConv}">
      <Binding Path="FirstName"/>
      <Binding Path="LastName"/>
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

四、最佳实践

建议说明
Converter 设为静态资源避免重复创建实例,提升性能
支持 ConverterParameter增强复用性(如是否取反、格式字符串等)
处理 null 和类型不匹配防止运行时异常
文化信息(CultureInfo)处理本地化(如日期、货币格式)
避免复杂逻辑Converter 应轻量,复杂逻辑放 ViewModel

五、WPF 内置常用 Converter

WPF 自带一些转换器,位于 System.Windows.Controls 或通过资源引用:

  • BooleanToVisibilityConverter(需手动添加到资源)
  • ObjectDataProvider(间接实现转换)
  • 但大多数场景仍需自定义。

注意:BooleanToVisibilityConverter 虽然存在,但不会自动生效,必须在资源中声明:

<Window.Resources>
  <BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>

✅ 总结

功能实现方式
单值转换IValueConverter + {Binding Converter=...}
多值转换IMultiValueConverter + <MultiBinding>
参数传递ConverterParameter
双向绑定同时实现 ConvertConvertBack

Converter 是 WPF 数据绑定体系中实现“表现与逻辑分离”的重要桥梁,合理使用能让 UI 更灵活、代码更清晰。