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哦

可以使用WPF的动画和线程来实现这个功能。以下是一个简单的实现方法: 1. 在启动窗口,添加一个动画控件,比如一个旋转的圆圈。 2. 启动一个线程,在后台检测连接是否成功。 3. 当连接成功时,关闭启动窗口,打开应用程序主窗口。 以下是一个示例代码: XAML代码: ```xml <Window x:Class="StartupWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:YourNamespace" Title="StartupWindow" Height="300" Width="300"> <Grid> <Canvas> <Ellipse Width="50" Height="50" Fill="Blue"> <Ellipse.RenderTransform> <RotateTransform Angle="0" CenterX="25" CenterY="25"/> </Ellipse.RenderTransform> <Ellipse.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(Ellipse.RenderTransform).(RotateTransform.Angle)" From="0" To="360" Duration="0:0:1" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Ellipse.Triggers> </Ellipse> </Canvas> </Grid> </Window> ``` C# 代码: ```csharp public partial class StartupWindow : Window { public StartupWindow() { InitializeComponent(); // 启动后台线程 Thread thread = new Thread(new ThreadStart(CheckConnection)); thread.Start(); } private void CheckConnection() { // 检测连接是否成功 bool isConnected = YourNamespace.CheckConnection(); // 如果连接成功,关闭启动窗口,打开主窗口 if (isConnected) { Dispatcher.Invoke(() => { MainWindow mainWindow = new MainWindow(); mainWindow.Show(); Close(); }); } } } ``` 在上面的代码,我们使用了Canvas和Ellipse来创建一个圆圈动画。我们使用了一个后台线程来检测连接是否成功,如果连接成功,我们使用Dispatcher.Invoke方法在主线程关闭启动窗口,打开主窗口。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值