WPF Converter转换器

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


📌 一、为什么需要 Converter?

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

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

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


🧱 二、核心接口

1. IValueConverter(最常用)

csharp 复制代码
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,将多个输入值合并为一个输出值。

csharp 复制代码
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 内置了这个转换器,但我们可以自己实现一个更灵活的版本:

csharp 复制代码
// 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 中使用:
xml 复制代码
<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:数值 → 颜色(分数评级)

csharp 复制代码
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 使用:

xml 复制代码
<Window.Resources>
    <local:ScoreToColorConverter x:Key="ScoreToColor"/>
</Window.Resources>

<TextBlock Text="{Binding StudentScore}"
           Foreground="{Binding StudentScore, Converter={StaticResource ScoreToColor}}"/>

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

csharp 复制代码
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:

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

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

csharp 复制代码
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:

xml 复制代码
<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 虽然存在,但不会自动生效,必须在资源中声明:

xml 复制代码
<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>

✅ 总结

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

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

相关推荐
zzyzxb19 小时前
WPF中Adorner和Style异同
wpf
棉晗榜21 小时前
WPF锚点页面,点击跳转到指定区域
wpf
zzyzxb21 小时前
Style/Setter、Template 属性、ControlTemplate 三者的关系
wpf
要记得喝水21 小时前
某公司WPF面试题(含答案和解析)--2
wpf
zzyzxb1 天前
WPF中Template、Style、Adorner异同
wpf
小股虫1 天前
数据一致性保障:从理论深度到架构实践的十年沉淀
架构·wpf
廋到被风吹走1 天前
【Spring】PlatformTransactionManager详解
java·spring·wpf
源之缘-OFD先行者1 天前
全栈开发实战:WPF+FFmpeg+GIS,打造工业级雷达探测终端
ffmpeg·wpf
Poetinthedusk2 天前
WPF动画制作分享
wpf·动画
张人玉2 天前
WPF HTTPS 通信示例使用说明
数据库·网络协议·http·c#·wpf