显示一个子VM,然后显示另一个,在第一个被关闭后

本文关键字:显示 第一个 另一个 然后 一个 VM | 更新日期: 2023-09-27 18:04:35

我有一个父导体。我想在里面显示第一个视图模型。然后在第一个视图关闭后(即完成一些操作),我想显示一个不同的视图模型。

我用的是Caliburn.Micro。贡献,其中传导结果导体中显示子VM。它有一个很酷的扩展方法AfterClosingDo,它在子进程停用并关闭后运行一个协程。

然而,当我使用AfterClosingDo运行另一个传导结果时,基本上会发生这种情况:

  • 第一个子虚拟机已关闭
  • 去激活事件发生,关闭操作后运行传导结果
  • 在关闭后,我在父导体中使用传导结果打开第二个子VM
  • 第二个子VM被正确激活
  • 然而,
  • 第一个子VM的去激活仍然没有完成,并且null项在导体
  • 中被设置为活动。

第一个VM基本显示加载操作的进度,第二个VM显示实际数据。加载完成后,我想在父Conductor中显示数据(当然,使用第二个VM)。

所以,我的问题:在Caliburn.Micro中是否有一种干净的方法来做到这一点,最好是不重写导体,屏幕等的默认行为。

我正在考虑使用EventAggregator,虽然我不确定,如果它是最好的解决方案。

显示一个子VM,然后显示另一个,在第一个被关闭后

我有一个非常类似的问题,我有一个导体打开一个子VM,然后一个确认框会弹出说"你想要关闭",并为原始项目CanClose方法触发了一个回调,该方法具有与您描述的相同的效果。

弹出式虚拟机将关闭,但在关闭时它将触发一个回调,该回调应该关闭第一个虚拟机。

我的指挥最后重新激活了原来的VM,这很烦人。事件发生的顺序为:

  • 打开VM 1
  • 尝试关闭虚拟机1
  • 关闭保护方法被触发
  • 在关闭vm1时弹出vm2(使用相同的导体)
  • VM 2上的确认按钮被点击
  • 确认按钮触发关闭回调并关闭VM1
  • VM2关闭
  • 导体记得vm1在vm2之前是活动的,所以在vm1关闭后重新打开它

最后,我只是实现了一个接口,在关闭后触发。

关闭后有工作要做的子项目实现接口(IAfterClose)

然后我为导体上的DeactivateItem提供了一个覆盖:

    public override void DeactivateItem(IScreen item, bool close)
    {
        var afterClose = item as IAfterClose;
        base.DeactivateItem(item, close);
        if (afterClose != null && close)
            afterClose.AfterClose();
    }

这确保回调不会过早触发。我不确定这是否对你有好处(因为我没有使用过contrib库),但它可能会给你一些想法。

唯一的缺点是我必须对DefaultCloseStrategy进行修复,因为当回调将触发时,它会在那里抛出空引用异常。我所应用的修复似乎没有造成不良影响,但我还没有真正研究为什么抛出null ref异常。

我找不到任何其他方法来做到这一点,因为最后一个触发的事件似乎是停用事件,它们仍然太早。