引言
ViewModel访问View的场景非常常见,比如打开关闭窗口,访问剪切板等等,想操作前端View的一些功能和属性必须要View的引用。这里介绍一种非常高效的方式与View进行交互。当然有很多方式,比如回调函数、CommunityToolkit.MVVM的Messenger等
1、Interaction
相当于统一格式了,支持任意消息类型订阅处理。包含入参和返回值
public class Interaction<TIn, TOut> { private Func<TIn, Task<Tout>>? _handler; public void RegisterHandler(Func<TIn, Task<TOut>> handler) { ArgumentNullException.ThrowIfNulL(handler); handler = handler; } public async Task<Tout> Handle(TIn input) { if(handler =null) throw new InvalidoperationException("No handler registered."); return await _handler(input); } } public readonly struct Unit { public static readonly Unit Default = default; public override int GetHashCode() => 0; public override bool Equals(object? obj) => obj is Unit; }1.1、VM中使用
这样再在ViewModel中声明一个实例使用:
public Interaction<Unit,string> RequestMessageInteraction{get;} = new(); [RelayCommand] private async Task UseInteraction() { IsBusy = true; Message = await RequestMessageInteraction.Handle(Unit.Default); IsBusy = false; }1.2、View中订阅
public MainWindow() { InitializeComponent(); var viewModel = new MainViewModel(); this.DataContext = viewModel; viewModel.RequestMessageInteraction.RegisterHandler(async _ => { await Task.Delay(2000); return "Hello from MainWindow with Interaction!"; }); }一般通过依赖注入进行VM的实例设置,这里简单实例化了一个MainViewModel。