引言
ViewModel访问View的场景非常常见,比如打开关闭窗口,访问剪切板等等,想操作前端View的一些功能和属性必须要View的引用。这里介绍一种非常高效的方式与View进行交互。当然有很多方式,比如回调函数、CommunityToolkit.MVVM的Messenger等
1、Interaction
相当于统一格式了,支持任意消息类型订阅处理。包含入参和返回值
cs
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中声明一个实例使用:
cs
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中订阅
cs
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。