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;
    }
}
相关推荐
程序员泠零澪回家种桔子12 分钟前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
源代码•宸1 小时前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
晚霞的不甘2 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
喵叔哟2 小时前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
Charlie_lll3 小时前
力扣解题-移动零
后端·算法·leetcode
打工的小王3 小时前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
80530单词突击赢5 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
爬山算法5 小时前
Hibernate(87)如何在安全测试中使用Hibernate?
java·后端·hibernate
WeiXiao_Hyy5 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
苏渡苇6 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式