记录一次WPF登录跳转的报错

我在WPF程序登录窗体到主窗体跳转遇到问题,我没有写任何关闭,但是程序直接退出了,代码如下

  private IUnityContainer Container { get; }
  public Bootstrapper()
  {
      Container = ConfigureService();         
  }
  private IUnityContainer ConfigureService()
  {
      var container=new UnityContainer();
      xxxxx其他注册
      return container;
  }
 public void Run()
 {
     Application app = new Application();
     app.Resources.MergedDictionaries.Add(DefaultResource);
     var loginWindow = Container.Resolve<LoginWindow>();
     var viewModel = Container.Resolve<LoginWindowViewModel>();
     loginWindow.DataContext = viewModel;
     var result = loginWindow.ShowDialog();
     if (result == false)
     {
         Application.Current.Shutdown();

     }
     else
     {
         var mainWindow = Container.Resolve<MainWindow>();
         var mainViewModel = Container.Resolve<MainWindowViewModel>();
         mainWindow.DataContext = mainViewModel;
         mainWindow.Show();
         var s = app.Run(mainWindow);
     }

登录按钮传递了DialogResult过去,没有其他多余代码

 private void ExecuteLogin(Window win)
 {
     win.DialogResult = true;
 }

我将容器换成ServiceCollection,结果发现一样,程序直接退出,并且IServiceProvider 在解析的时候还会出现null,因为ServiceCollection和IUnityContainer不一样,IUnityContainer解析和注册是同一个接口,内部应该会自己实例化,使用IServiceProvider的时候,必须ServiceCollection注册一波,
言归正传。
当我替换

 var loginWindow = Container.Resolve<LoginWindow>();

 var loginWindow = new LoginWindow();

程序好了?并且底下

  var mainWindow = new MainWindow();
  var mainWindow = Container.Resolve<MainWindow>();

不管写哪一种程序都是好的,只有上面需要实例化,我将 var loginWindow = Container.Resolve();和 var loginWindow = new LoginWindow();同时保留在代码中,发现程序也是好的,反正就是需要实例化一个LoginWindow
,但是还是会出现一个问题主窗体程序关闭的时候VS2022还在运行,我只好写了

  public partial class MainWindow : Window
  {
      public MainWindow()
      {
          InitializeComponent();
      }

      protected override void OnClosed(EventArgs e)
      {
          Application.Current.Shutdown();
          base.OnClosed(e);
      }
  }

这两个问题我都解决了,但是只知道是容器生命周期和管理的问题,具体哪里不清楚,有知道的可以留言,一起探讨一下
这里的关键点是理解 ShowDialog 方法的工作方式:

ShowDialog 会阻塞当前线程,直到对话框窗口关闭。
当对话框关闭,ShowDialog 返回一个 bool? 值,表示用户是以确认 (true) 还是取消 (false) 方式关闭了对话框。
一旦 ShowDialog 返回,对话框窗口实际上已经关闭,因此不会在屏幕上显示。
因此,loginWindow 的生命周期在用户关闭对话框时结束
关于 ShowDialog 返回值的一些细节:

如果用户关闭对话框(例如,点击了“确定”或“取消”按钮),ShowDialog 将返回一个 bool? 类型的值,该值是 true 或 false,取决于对话框的 DialogResult 属性。
如果 ShowDialog 返回 true,这通常表示用户以一种确认的方式关闭了对话框(例如,点击了“确定”按钮)。
如果 ShowDialog 返回 false,这通常表示用户以一种取消的方式关闭了对话框(例如,点击了“取消”按钮或关闭图标)。
一旦 ShowDialog 有返回值,无论它是 true 还是 false,对话框都会关闭。
ShowDialog的改动导致窗体关闭,由于窗体的生命周期交给容器了,窗体的关闭不影响程序的继续进行,所以VS2022还在运行,
按理来说正确写法

// 通过依赖注入容器解析LoginWindow和其视图模型
var login = Container.Resolve<LoginWindow>();
var loginViewModel = Container.Resolve<LoginWindowViewModel>();
login.DataContext = loginViewModel;

var loginResult = login.ShowDialog();
if (loginResult.HasValue && loginResult.Value)
{
    // 登录成功后的操作
    var mainWindow = Container.Resolve<MainWindow>();
    var mainViewModel = Container.Resolve<MainWindowViewModel>();
    mainWindow.DataContext = mainViewModel;
    
    // 设置MainWindow并显示
    Application.Current.MainWindow = mainWindow;
    mainWindow.Show();
    
    // 启动应用程序的消息循环
    Application.Current.Run();
}
else
{
    Application.Current.Shutdown();
}

5.26下午,今天我有想了一下

我删除了第一句Application app = new Application();和最后一句 app.Run(mainWindow);,主窗体出现了不到一秒就关闭了程序

本文作者:孤沉

本文链接:https://www.cnblogs.com/guchen33/p/18206906

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   孤沉  阅读(25)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开