Caliburn.Micro TryClose关闭每个窗口

时间:2015-04-17 09:05:36

标签: c# wpf caliburn.micro

我有以下情况:

  • 有一个登录屏幕
  • 登录成功后,应关闭登录屏幕并开始新屏幕

我在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);
        }
    }

这是来自Login viewmodel的方法:

public class LoginViewModel: Screen
{
     public void DoLogin()
        {   

          if (LoginSuccessful)
          {       
            App.Bootstrapper.Init2();
            TryClose();
          }
       }
}

使用TryClose时,第二个窗口也会关闭,我的应用程序退出。

为什么会这样?我应该如何预防?

1 个答案:

答案 0 :(得分:2)

检查了您的代码。此时我所看到的是TryClose导致异常

Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed.

似乎 Caliburn 甚至 System.Windows.Navigation 以某种方式进入另一个线程(我看到 ManagedThreadId at at MainViewModel 的构造函数与 ManagedThreadId 的区别不同,其中 Init2 被调用。

如果您将代码更改为此代码,那么所有代码​​都按预期执行(这不是一个非常完美的解决方案,只是表明它可能在某些条件下工作

App.Bootstrapper.Init2();
Task.Factory.StartNew(() => { TryClose(); });

我不认为在尝试展示另一个窗口时关闭最后一个可用窗口是一个好习惯。只需使用一些 shell (如果你不想在第一时间看到它,甚至隐藏它)。如果要使用 Conductor 继承,请将所有调用移至 WindowManager 或/和 ActivateItem 。所以你永远不会处于这样的境地,因为你在背景上至少有一部分应用程序,只有当你需要它而不是偶然时才会终止。

相关问题