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 更灵活、代码更清晰。

相关推荐
她说彩礼65万1 小时前
C# Thread和Task的区别
wpf
张人玉4 小时前
C#编写西门子S7PLC通信的相关知识点
microsoft·c#·wpf·plc·西门子s7通信
乐科6 小时前
WPF定时器
stm32·单片机·wpf
wuty0071 天前
WPF 调用 Win32的SetWindowDisplayAffinity 函数 实现捕获屏幕时,过滤指定的窗口
wpf·setwindowdisplayaffinity·过滤窗口·wgc·截屏过滤窗口
TracyCoder1231 天前
RocketMQ技术原理简单解析:从架构到核心流程
架构·wpf·rocketmq
烽火聊员1 天前
SSLSocket 服务器端WPF C#测试代码
开发语言·c#·wpf·ssl
暮雪倾风1 天前
【WPF开发】加载solidworks的3D模型
wpf
Macbethad1 天前
高性能 CANopen 主站程序技术方案 (基于 WPF)
网络协议·wpf·信息与通信
Macbethad2 天前
使用WPF编写一个工控软件设置界面
wpf