zoukankan      html  css  js  c++  java
  • WPF中实现先登录后启动主程序的方法

     我觉得先登录后启动应用主程序是一个很经典的问题,基本上如果要写一个应用程序都会用到这个的小环节。我在这个问题上挣扎了大半天才找到解决方案,我的实现方法我觉得有点不正宗,如果有哪位高手知道更好的方法欢迎留言指导!!

      首先来说一下传统C#在WinForm中的实现方法,基本上是在Main函数中根据第一个启动窗口的DialogResult来判断是否实例第二个窗口,DialogResult是在第一个窗口中根据登录情况来设置的。代码如下

    主函数代码:

    static class Program

    {

        [STAThread]

        static void Main()

        {

            try

            {

                Application.EnableVisualStyles();

                Application.SetCompatibleTextRenderingDefault(false);

                frmLogin frm = new frmLogin(); //登录

                if (frm.ShowDialog() == DialogResult.OK)

                {

                    Application.Run(new frmMain()); //主窗体

                }

                else

                {

                    Application.Exit();

                }

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message, "系统登陆", MessageBoxButtons.OK, MessageBoxIcon.Stop);

                Application.Exit();

            }

        }

    }

      第一个登录窗口中设置DialogResult的代码:

      this.DialogResult = DialogResult.OK;

      this.Close();

      From: http://www.itc8.cn/a/bianchengleyuan/2011/0126/216.html

      参考WinFrom中的这个基本想法,在WPF中实现。我重写了OnStartup函数:

    protected override void OnStartup(StartupEventArgs e)

            {

                base.OnStartup(e);

     

                Login loginWindow = new Login();

                loginWindow.ShowDialog();

                result = loginWindow.DialogResult;

                username = loginWindow.UserName;

                if (true == result)

                {

                    MainWindow main = new MainWindow(username);

                    main.ShowDialog();

                }   

            } //这里需要注意的一点就是上面要用ShowDialog(),而不能直接调用Show(),Show()是不会返回任何结果的,只有用ShowDialog()才能渠道DialogResult

      死活都是只能启动第一个窗口登录,然后第二个窗口无法呈现出来。调试后发现main窗口已经实例化了但是ShowDialog()貌似完全不起作用。纠结了。。

      这个问题的可能原因有:

      1. MainWindow也就是我要创建的第二个主窗口没有实例化成功;

      2. DialogResult错误导致没有进入MainWindow的实例和显示过程;

      3. 第一个窗口在作祟。

      经过调试排除第一、二中可能,那么肯定就是第一个窗口设置不对或者哪里出问题了。Google了一下别人WPF的方法,发现有一篇文章中提到了需要将WPF的ShutDownMode设置为OnExplicitShutdown才行,试了一下,果然生效了!只需要很简单的在Main主函数修改Application的ShutdownMode,修改代码如下

    public static void Main()

            {

                PFM.GUI.App.App app = new PFM.GUI.App.App();

                app.ShutdownMode = ShutdownMode.OnExplicitShutdown;

                app.Run();

            }

      让我们来看看这个ShutdownMode是何方神圣。ShutdownMode可以设置为一个ShutdownMode 枚举值,包括三种:OnLastWindowClose、OnMainWindowClose、OnExplicitShutdown,默认值是OnLastWindowClose。如果将 ShutdownMode 设置为 OnLastWindowClose,则 Windows Presentation Foundation (WPF) 会在应用程序中的最后一个窗口关闭时隐式调用 Shutdown,即使任何当前已经实例化的窗口被设置为主窗口也是如此(MSDN: http://goo.gl/fAyrD )。最后一句是关键:即使任何当前已经实例化的窗口被设置为主窗口也是如此。因为WPF中默认将在Application中实例化的第一个 Window 对象的引用自动设置为MainWindow。

      也就是说当我们实例化第一个窗口的时候,它被认为是一个MainWindow,所以当它被关闭的时侯WPF就已经隐式调用了ShutDown所以之后我们在怎么实例化窗口都是徒劳。这就是为什么把ShutdownMode设为显示关闭这样就可以避免上面的问题了。需要注意的是在OnStartUp中记得调用App.Shutdown()来关闭Application哦

  • 相关阅读:
    代码质量检查那点事
    DataTable中如何去除重复的项【转】
    TAG的用法和用途[转]
    Sqlite: unable to open database file
    [转]DataGridView绑定泛型List的种种
    SQLite清空表并将自增列归零[转]
    .NET特性-Attribute
    基于边信道的硬件攻击小综述
    国内下载vscode速度慢解决
    centos与内核版本对应关系
  • 原文地址:https://www.cnblogs.com/swarb/p/9924277.html
Copyright © 2011-2022 走看看