调用ActivateItem函数时CaliburnMicro StackOverflowException

时间:2013-06-08 11:54:49

标签: caliburn.micro

我有两个VM - View(继承自Screen)和Edit(继承自Screen)。视图用于显示带有数据的网格和编辑 - 将新项目添加/编辑到网格中。

在我的ShellViewModel中,我有以下代码来激活View。

    public void WorkstationView()
    {
        this.ActivateItem(ServiceLocator.Current.GetInstance<WorkstationViewModel>());
    }

在WorkstationViewModel中,当用户单击“创建”按钮时,将调用以下代码

    public void CreateAction()
    {
        EditableObject = new WorkstationDto();
        TryClose(true);
    }

还有一个Deactivated事件属性的监听器,请参阅下面的代码(在ShellViewModel构造函数中调用InitViewModels)。

    private void InitViewModels()
    {
        #region Init

        WorkstationViewModel = ServiceLocator.Current.GetInstance<WorkstationViewModel>();
        WorkstationEditViewModel = ServiceLocator.Current.GetInstance<WorkstationEditViewModel>();

        #endregion

        #region Logic

        WorkstationViewModel.Deactivated += (o, args) => 
        {
            if (WorkstationViewModel.EditableObject == null)
            {
                return;
            }
            WorkstationEditViewModel.EditableObject = WorkstationViewModel.EditableObject;
            ActivateItem(WorkstationEditViewModel);
        };

        #endregion
    }

当我关闭编辑视图时,这里的问题是StackOverflow异常(请参阅创建操作)。

1 个答案:

答案 0 :(得分:0)

“由于指挥不维持”屏幕收集“,每个新项目的激活都会导致停用和关闭之前活动的项目。”Caliburn.Micro documentation

如果您使用的是Conductor<T>,那么ActivateItem(WorkstationEditViewModel);处理程序内部的Deactivated会隐式重新触发上一个视图模型的停用 - 为您提供无限循环。尝试将您的指挥更改为继承Conductor<IScreen>.Collection.OneActive。但是,您仍将有两个停用:来自原始TryClose操作的一个,以及激活新屏幕时的第二个。覆盖DetermineNextItemToActivate可以帮助您避免这种情况。