Caliburn.Micro TryClose 每 window 关闭一次
Caliburn.Micro TryClose closes every window
我有以下场景:
- 有一个登录屏幕
- 登录成功后,应关闭登录界面并重新启动一个新界面
我在 Bootstrapper 中使用了这段代码:
public class AppBootstrapper : BootstrapperBase
{
public AppBootstrapper()
{
Initialize();
}
private IWindowManager windowManager = new WindowManager();
private MainViewModel mainViewModel = new MainViewModel();
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
Init(new LoginViewModel());
}
public void Init(object viewModel)
{
windowManager.ShowWindow(viewModel);
}
public void Init2()
{
windowManager.ShowWindow(mainViewModel);
}
}
这是我的 App.xaml.cs:
public partial class App : Application
{
public static AppBootstrapper Bootstrapper;
protected override void OnStartup(StartupEventArgs e)
{
Bootstrapper = new AppBootstrapper();
base.OnStartup(e);
}
}
这是登录视图模型中的方法:
public class LoginViewModel: Screen
{
public void DoLogin()
{
if (LoginSuccessful)
{
App.Bootstrapper.Init2();
TryClose();
}
}
}
当使用 TryClose
时,第二个 window 也关闭并且我的应用程序退出。
为什么会这样?我该如何预防?
检查了你的代码。此时我所看到的是 TryClose 导致异常
Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.
似乎 Caliburn 甚至 System.Windows.Navigation 不知何故在幕后转到了另一个线程(我看到 [ MainViewModel 的构造函数中的 =20=]ManagedThreadId 不同于 ManagedThreadId,其中 Init2 是称为)。
如果您将代码更改为这个代码,那么一切都会按预期执行(这不是很完美的解决方案,只是表明它可能在某些条件下工作)
App.Bootstrapper.Init2();
Task.Factory.StartNew(() => { TryClose(); });
我认为在尝试显示另一个时关闭最后一个可用 window 不是一个好习惯。只需使用一些 shell (如果您不想一开始就看到它,甚至可以隐藏它)。如果您要使用 Conductor 继承,请将所有对 WindowManager or/and ActivateItem 的调用移到那里.所以你永远不会遇到这种情况,因为你至少有一部分应用程序在后台运行,它只会在你需要时终止,而不是意外终止。
我有以下场景:
- 有一个登录屏幕
- 登录成功后,应关闭登录界面并重新启动一个新界面
我在 Bootstrapper 中使用了这段代码:
public class AppBootstrapper : BootstrapperBase
{
public AppBootstrapper()
{
Initialize();
}
private IWindowManager windowManager = new WindowManager();
private MainViewModel mainViewModel = new MainViewModel();
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
Init(new LoginViewModel());
}
public void Init(object viewModel)
{
windowManager.ShowWindow(viewModel);
}
public void Init2()
{
windowManager.ShowWindow(mainViewModel);
}
}
这是我的 App.xaml.cs:
public partial class App : Application
{
public static AppBootstrapper Bootstrapper;
protected override void OnStartup(StartupEventArgs e)
{
Bootstrapper = new AppBootstrapper();
base.OnStartup(e);
}
}
这是登录视图模型中的方法:
public class LoginViewModel: Screen
{
public void DoLogin()
{
if (LoginSuccessful)
{
App.Bootstrapper.Init2();
TryClose();
}
}
}
当使用 TryClose
时,第二个 window 也关闭并且我的应用程序退出。
为什么会这样?我该如何预防?
检查了你的代码。此时我所看到的是 TryClose 导致异常
Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.
似乎 Caliburn 甚至 System.Windows.Navigation 不知何故在幕后转到了另一个线程(我看到 [ MainViewModel 的构造函数中的 =20=]ManagedThreadId 不同于 ManagedThreadId,其中 Init2 是称为)。
如果您将代码更改为这个代码,那么一切都会按预期执行(这不是很完美的解决方案,只是表明它可能在某些条件下工作)
App.Bootstrapper.Init2();
Task.Factory.StartNew(() => { TryClose(); });
我认为在尝试显示另一个时关闭最后一个可用 window 不是一个好习惯。只需使用一些 shell (如果您不想一开始就看到它,甚至可以隐藏它)。如果您要使用 Conductor 继承,请将所有对 WindowManager or/and ActivateItem 的调用移到那里.所以你永远不会遇到这种情况,因为你至少有一部分应用程序在后台运行,它只会在你需要时终止,而不是意外终止。