IActivatableViewModel在视图之前被激活,因此在VM激活中引发UnhandledInteraction



我有一个ViewModel,它对独立于View和ViewModel的队列中的每个项目使用一个Interaction。处理在this.WhenActivated块中开始,并且它依赖于Interaction。在IViewFor<MyViewModel>.WhenActivated中设置了Interation的处理程序。

由于激活的顺序,会抛出UnhandledInteractionException

using System;
using System.Reactive;
using System.Reactive.Disposables;
using System.Windows;
using ReactiveUI;
namespace RxActivationRepro
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, IViewFor<MainViewModel>
{
public MainWindow()
{
ViewModel = new MainViewModel();
InitializeComponent();
this.WhenActivated(d =>
{
ViewModel.Interaction.RegisterHandler(ctx =>
{
MessageBox.Show("Interaction!");
ctx.SetOutput(Unit.Default);
});
});
}
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (MainViewModel)value;
}
public MainViewModel? ViewModel { get; set; }
}
public class MainViewModel : ReactiveObject, IActivatableViewModel
{
public MainViewModel()
{
this.WhenActivated( d =>
{
Interaction.Handle(Unit.Default)
.Subscribe(_ => { MessageBox.Show("Nope!"); }, ex => { MessageBox.Show(ex.Message); })
.DisposeWith(d);
});
}
public ViewModelActivator Activator { get; } = new();
public Interaction<Unit, Unit> Interaction { get; } = new();
}
}

我希望下面的代码能正常工作,但事实并非如此。我解决了从虚拟机中删除接口以禁用视图激活虚拟机的问题,并手动处理激活,没什么大不了的。

但是有没有办法改变激活顺序或推迟VM的激活?还是我处理这件事错了?

在RxUI 7.4.0中找到(不要问:p(,但在17.17+dotnet 6中也有同样的行为,所以我猜这是故意的。

更多上下文:

我试图实现Rider中的一个功能,即当您打开已经有一个实例的新解决方案时,会出现一个对话框,询问是打开新实例,还是替换当前实例的内容。我将让它为每个新文件打开一个特殊的编辑窗口,因此Interaction将编辑窗口与监视请求队列的ViewModel解耦。如果您在登录前打开新文件进行编辑,激活前队列中的项目可能会发生。我也不想垃圾邮件窗口,所以我想等待Interaction.Handle调用,一次只编辑一个项目。

好吧,感谢SO社区,尤其是作为我的黄色橡皮鸭的网站:(

namespace RxActivationRepro
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, IViewFor<MainViewModel>
{
public MainWindow()
{
ViewModel = new MainViewModel();
InitializeComponent();
this.WhenActivated(d =>
{
ViewModel.Interaction.RegisterHandler(ctx =>
{
MessageBox.Show("Interaction!");
ctx.SetOutput(Unit.Default);
});

ViewModel.InteractUntilDisposed().Subscribe().DisposeWith(d);
});
}
object? IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (MainViewModel)value;
}
public MainViewModel? ViewModel { get; set; }
}
public class MainViewModel : ReactiveObject
{
public IObservable<Unit> InteractUntilDisposed()
{
return Observable.StartAsync(async ct =>
{
while (!ct.IsCancellationRequested)
{
await Interaction.Handle(Unit.Default);
await Task.Delay(5000);
}
});
}
public Interaction<Unit, Unit> Interaction { get; } = new();
}
}

最新更新