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

C# 在第一个VM关闭后,显示一个子VM,然后显示另一个子VM,c#,mvvm,viewmodel,caliburn.micro,C#,Mvvm,Viewmodel,Caliburn.micro,我有一个家长。我想展示它里面的第一视图模型。然后,在第一个视图关闭后(即完成一些操作),我想显示一个不同的视图模型 我使用的是,ConductResult在导体中显示子VM。在closingdo之后,它有一个很酷的扩展方法,该方法在该子项被停用并关闭后运行一个协同程序 但是,当我使用AfterClosingDo运行另一个ConductResult时,基本上会发生以下情况: 第一个子虚拟机 关门了 发生停用事件,ConductResult在关闭操作后运行 在结束后,我在父导体中使用Conduct

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

我使用的是,ConductResult在导体中显示子VM。在closingdo之后,它有一个很酷的扩展方法,该方法在该子项被停用并关闭后运行一个协同程序

但是,当我使用
AfterClosingDo
运行另一个ConductResult时,基本上会发生以下情况:

  • 第一个子虚拟机 关门了
  • 发生停用事件,ConductResult在关闭操作后运行
  • 在结束后,我在父导体中使用ConductResult打开第二个子VM
  • 第二个子VM已正确激活
  • 但是,第一个子VM的停用仍然没有完成,并且null项在导体中设置为活动
第一个VM基本上显示加载操作的进度,第二个VM显示实际数据。加载完成后,我想在父导体中显示数据(当然,使用第二个VM)

所以,我的问题是:
Caliburn.Micro
中是否有一种干净的方法来实现这一点,最好不要覆盖导体、屏幕等的默认行为


我正在考虑使用事件聚合器,但我不确定它是否是最佳解决方案。

我遇到了一个非常类似的问题,我让一个售票员打开一个儿童虚拟机,然后会弹出一个确认框,说“您想关闭吗?”并为原始项启动了回调
CanClose
方法,其效果与您描述的相同

弹出的VM将关闭,但在关闭时,它将触发一个回调,该回调本应关闭第一个VM

我的指挥最后重新激活了原来的虚拟机,这很烦人。事件的顺序是:

  • 打开虚拟机1
  • 尝试关闭VM 1
  • CanClose-guard方法已启动
  • 在VM 1的CanClose中弹出VM 2(使用相同的导体)
  • 单击VM 2上的确认按钮
  • 确认按钮触发CanClose回调并关闭VM1
  • VM2关闭
  • 导体记得VM 1在VM 2之前是活动的,所以在关闭VM 1后重新打开它
最后,我实现了一个在关闭后启动的接口

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

然后,我在导体上为
停用Item
提供了一个覆盖:

    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异常的原因


我找不到任何其他方法来执行此操作,因为触发的最后一个事件似乎是停用事件,它们仍然很早。

如果您感兴趣,我可能知道,为什么在DefaultCloseStrategy.Execute()中引发空引用异常。我不确定这是一个bug还是框架的某种误用,但我提出了一个问题:太棒了,我仔细研究了一下,看到了null ref被抛出的地方,但没有走得更远,因为当时没有CM源代码/PDB——希望CM团队能够修复它。谢谢你的信息!