我有一个使用 Show.Dialog() 显示的对话框,并且在附加到视图的 Loaded 事件的方法中具有这些步骤:
- Show.Busy()
- 可能长时间运行的 Web 请求(我在这里有一个自定义的异步 IResult)
- 如果通过 Show.MessageBox() 出错则弹出
- Show.NotBusy()
我发现如果您在第 2 步关闭我的视图需要一段时间,然后重新打开,则不会显示新视图上第 1 步的忙碌指示符。
所以一开始,我以为是我的错,如果视图被关闭,我就放了一个简单的机制来取消第 4 步。但没有运气...
从它的样子来看,第 1 步中的 Show.Busy() 正在尝试与已经关闭的视图进行交互。这是 Caliburn 中的错误吗?
我的 ViewModel 是一个单例,所以这也可能归因于我认为的问题。对于测试,我切换到 IsBusy 布尔属性,问题就消失了。然而,在我的整个应用程序中,这将是一个很大的改变。
对任何解决方法的想法?或者其中一个 Caliburn 人可以在这里帮助我吗?我正在使用最新版本的完整版 Caliburn。
更新:
我尝试了 Marco 的解决方法,导入 IBusyService 并在我的 ViewModel 中执行此操作:
public override void TryClose(bool? dialogResult)
{
_busyService.MarkAsNotBusy(this);
base.TryClose(dialogResult);
}
但这似乎没有帮助。如果我做一个简单的复制会有帮助吗?
更新#2:
我继续进行了复制,因为很多时候会发现问题。
原来,这与我必须直接调用 IWindowManager 有关。我的应用程序部分是带有插件架构的 WinForms,我们使用了几个基于 Caliburn 的插件。
以下是导致问题的代码示例:
if (_child.IsActive)
{
_child.BringToFront();
}
else
{
_manager.ShowWindow(_child);
}
这是在 WinForms NotifyIcon MenuItem 的单击事件处理程序中。
_child 是一个 Screen,BringToFront() 调用底层 View 的 Activate 方法(当然是通过服务)。_manager 是 IWindowManager。
如果您直接运行 Caliburn,则 Show.Dialog() 不会导致问题。
关于解决方法的任何想法?我不确定这是否是 Caliburn 问题,但可能只是由直接使用 IWindowManager 引起的。