WPF中的IValueConverter接口(值转换器)

1.IValueConverter 是什么?解决什么问题?

1.1 定义

IValueConverter是WPF中用于数据绑定时进行值转换的接口。

C# 复制代码
namespace System.Windows.Data
{
    public interface IValueConverter{
        object Convert(object value, Type targetType, object parameter, CultureInfo culture);
        object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
    }
}

当需要调用时,实现该接口并重写Convert和ConvertBack,以下分别叙述这两个方法的用途

1.2 核心作用

当ViewModle中的数据类型,不能直接用View展示,即ViewModel与View对应的数据类型不一致时,需要使用该接口进行数据类型转换,IValueConverter起到了"翻译官"的角色。

2.为什么要使用值转换器?

在 MVVM 模式中:

  • ViewModel 只暴露 业务含义的数据
  • View 需要 UI 能理解的类型

典型示例:

ViewModel数据 View
bool Visibility
enum Style
DataTime string

为了解决这样的类型不匹配,需要使用值转换器

3.IValueConverter 的生命周期与执行时机

3.1 执行时机

IValueConverter的实现类对象会在以下情况被调用

  • 绑定源属性首次赋值
  • 绑定源属性发生变化(INotifyPropertyChanged)
  • 绑定目标需要重新计算显示值

3.2 执行方向

ViewModel -> View 调用Convert方法

View -> ViewModel 调用ConvertBack方法

4.Convert 与 ConvertBack 的职责划分

4.1 Convert

C# 复制代码
object Convert(object value, Type targetType,object parameter, CultureInfo culture);
参数 含义
value 当前传递的值,在Concert中来自ViewModel
targetType 目标属性类型
parameter XAML传入的附加参数
culture 区域信息

4.2CovertBack

C# 复制代码
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
参数 含义
value 当前传递的值,来自View
targetType 目标属性类型
parameter XAML传入的附加参数
culture 区域信息

一般不具体实现

C# 复制代码
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){
    Binding.DoNothing;
}

在以下两种情况需要具体实现

  • Mode=TwoWay
XAML 复制代码
{Binding Path=... Mode=TwoWay}
  • View需要回写到ViewModel中

5.具体实例

需要实现导航栏按钮被按下后,样式改变以提醒用户界面切换,为了完成该需求,可以在ViewModel中维护一个枚举属性来记录当前的访问界面

C# 复制代码
//枚举
```
public enum MainWindowMenuItem
{
    Menu1,
    Menu2,
    Menu3,
    Menu4,
    Menu5,
    Menu6,
    Menu7,
    Menu8,
    Menu9
}
```

public partial class MainWindowViewModel : ObservableObject
{
    ...Other...
    [ObservableProperty] private MainWindowMenuItem _selectedMenuItem = MainWindowMenuItem.Menu1;
    ...Other...
}
XAML 复制代码
<Button
    Style="{Binding SelectedMenuItem,Converter={StaticResource MenuConverter},ConverterParameter={x:Static local:MainWindowMenuItem.Menu1}}"
    Command="{Binding SelectMenuCommand}"
    CommandParameter="{x:Static local:MainWindowMenuItem.Menu1}">
    <Button.Content>
        ...
    </Button.Content>
</Button>

可以看到这个按钮绑定了一个传入枚举的命令,当点击它的时候,他会修改ViewModel中的SelectedMenuItem属性,当该属性被修改时,会把对应的枚举值交给值转换器,然后对比按钮上的parameter,将被点击的按钮的样式修改为SelectedButtonStyle。

C# 复制代码
public class MenuConverter:IValueConverter
{
    public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        var normal = (Style)Application.Current.Resources["NormalButtonStyle"];
        var selected = (Style)Application.Current.Resources["SelectedButtonStyle"];

        if (value == null || parameter == null)
            return normal;

        return value.Equals(parameter) ? selected : normal;
    }

    public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
相关推荐
波波00715 小时前
ASP.NET MVC 中的返回类型全集详解
后端·asp.net·mvc
糟糕好吃21 小时前
我让 AI 操作网页之后,开始不想点按钮了
前端·javascript·后端
leonkay21 小时前
Golang语言闭包完全指南
开发语言·数据结构·后端·算法·架构·golang
颜酱1 天前
BFS 与并查集实战总结:从基础框架到刷题落地
javascript·后端·算法
无限大61 天前
数字生存02:如何在信息爆炸的时代保持清醒,不被算法控制
后端
无限大61 天前
AI实战02:一个万能提示词模板,搞定90%的文案/设计/分析需求
前端·后端
青柠代码录1 天前
【Linux】脚本:console.log 日志定期备份清理
后端
陈随易1 天前
站在普通开发者的角度,我觉得 RollCode 更像是“把 H5 交付这件事重新捋顺了”
前端·后端·程序员
陈随易1 天前
RollCode:不只是在做页面,而是在缩短“从需求到上线”的整条链路
前端·后端
y = xⁿ1 天前
【LeetCodehot100】二叉树大合集 T94:二叉树的中序遍历 T104:二叉树的最大深度 T226:翻转二叉树 T101:对称二叉树
后端·算法·深度优先