做登录系统界面用到的,想在登录后显示新的窗体,并且关闭登录窗体。(登录窗体为主窗体)不想使用hide方法,要确实把登录窗体销毁,但不影响整个应用程序的子窗体。别人说,主窗体销毁后,应用程序就结束了,但可以用静态变量实现。不知道是怎么一回事。或者谁有更好的方法吗?

解决方案 »

  1.   

    给你例子:    static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //Application.Run(new FrmMain());
                FrmLogon frmLogon = new FrmLogon();//登录窗体
                frmLogon.ShowDialog();
               
                if (frmLogon.DialogResult== DialogResult.OK)
                {
                    frmLogon.Close();
                    Application.Run(new FrmMain(frmLogon.txtName.Text));
                }
            }
        }
    在登录窗体那边,如果登录成功就设置登录窗体的DialogResult=DialogResult.OK。
      

  2.   

    看看这个
    http://www.cnblogs.com/LeoWong/archive/2009/11/13/1602204.html
      

  3.   


    参考15-16楼的回复:
    http://topic.csdn.net/u/20090730/17/86fcd2f7-40de-49ed-be09-4217f6b2f14a.html
      

  4.   

    如果程序在装载时需要进行较长时间的处理,最好使用启动画面,一方面美化程序,一方面可以不使用户面对着一片空白的程序界面。 
    我手头上一个小项目主界面启动时需要检查用户文件及运行环境是否有效,需要一段时间处理,因此想到要添加一个启动画面,在网上搜了一阵,发现下面两个方案: 1、用C#给程序加启动画面并只允许一个应用程序实例运行 
    http://www.zahui.com/html/14/36790.htm 
    2、HOW TO:溅射屏幕(Splash Screen),也叫程序启动画面的制作(.NET2003) 
    http://lzmtw.cnblogs.com/archive/2005/10/31/265782.html 第一个方案在实现与界面分离上做得不够好,启动界面(一个窗体)依赖于特定窗体,主窗体还必须添加一个PreLoad方法完成装载任务,只能在代码级重用。而且那个只允许一个实例的写法也太.... 第二个方案框架很好,但细微处理可能存在一点问题,需要判断主窗体的WindowState,整个代码也较复杂。 我改动了一下,基本结构仿照第二个方案。 功能:为程序添加启动界面,显示启动界面的同时加载主窗体,主窗体加载完毕后关闭启动界面,显示主窗体。启动画面停留的时间是设定的时间和主窗体装载所需时间两个的最大值。启动画面在另一个线程上运行。 
    plus:我的水平还很差,见笑。 程序代码如下: //启动窗体虚基类,继承自ApplicationContext 
    using System.Windows.Forms; 
    using System.Threading; 
    using System; //启动画面虚基类,启动画面会停留一段时间,该时间是设定的时间和主窗体构造所需时间两个的最大值 
    public abstract class SplashScreenApplicationContext : ApplicationContext 

        private Form _SplashScreenForm;//启动窗体 
        private Form _PrimaryForm;//主窗体 
        private System.Timers.Timer _SplashScreenTimer; 
        private int _SplashScreenTimerInterVal = 5000;//默认是启动窗体显示5秒 
        private bool _bSplashScreenClosed = false; 
        private delegate void DisposeDelegate();//关闭委托,下面需要使用控件的Invoke方法,该方法需要这个委托     public SplashScreenApplicationContext() 
        { 
            this.ShowSplashScreen();//这里创建和显示启动窗体 
            this.MainFormLoad();//这里创建和显示启动主窗体 
        }     protected abstract void OnCreateSplashScreenForm();     protected abstract void OnCreateMainForm();     protected abstract void SetSeconds();     protected Form SplashScreenForm 
        { 
            set 
            { 
                this._SplashScreenForm = value; 
            } 
        }     protected Form PrimaryForm 
        {//在派生类中重写OnCreateMainForm方法,在MainFormLoad方法中调用OnCreateMainForm方法 
            //  ,在这里才会真正调用Form1(主窗体)的构造函数,即在启动窗体显示后再调用主窗体的构造函数 
            //  ,以避免这种情况:主窗体构造所需时间较长,在屏幕上许久没有响应,看不到启动窗体       
            set 
            { 
                this._PrimaryForm = value; 
            } 
        }     protected int SecondsShow 
        {//未设置启动画面停留时间时,使用默认时间 
            set 
            { 
                if (value != 0) 
                { 
                    this._SplashScreenTimerInterVal = 1000 * value; 
                } 
            } 
        }     private void ShowSplashScreen() 
        { 
            this.SetSeconds(); 
            this.OnCreateSplashScreenForm(); 
            this._SplashScreenTimer = new System.Timers.Timer(((double)(this._SplashScreenTimerInterVal))); 
            _SplashScreenTimer.Elapsed += new System.Timers.ElapsedEventHandler(new System.Timers.ElapsedEventHandler(this.SplashScreenDisplayTimeUp));         this._SplashScreenTimer.AutoReset = false; 
            Thread DisplaySpashScreenThread = new Thread(new ThreadStart(DisplaySplashScreen));         DisplaySpashScreenThread.Start(); 
        }     private void DisplaySplashScreen() 
        { 
            this._SplashScreenTimer.Enabled = true; 
            Application.Run(this._SplashScreenForm); 
        }     private void SplashScreenDisplayTimeUp(object sender, System.Timers.ElapsedEventArgs e) 
        { 
            this._SplashScreenTimer.Dispose(); 
            this._SplashScreenTimer = null; 
            this._bSplashScreenClosed = true; 
        }     private void MainFormLoad() 
        { 
            this.OnCreateMainForm(); 
         
            while (!(this._bSplashScreenClosed)) 
            { 
                Application.DoEvents(); 
            }         DisposeDelegate SplashScreenFormDisposeDelegate = new DisposeDelegate(this._SplashScreenForm.Dispose ); 
            this._SplashScreenForm.Invoke(SplashScreenFormDisposeDelegate); 
            this._SplashScreenForm = null;     
            //必须先显示,再激活,否则主窗体不能在启动窗体消失后出现 
            this._PrimaryForm.Show(); 
            this._PrimaryForm.Activate(); 
             
            this._PrimaryForm.Closed += new EventHandler(_PrimaryForm_Closed);     }     private void _PrimaryForm_Closed(object sender, EventArgs e) 
        { 
            base.ExitThread(); 
        } 
      

  5.   

    使用方法:定义一个启动类,应用程序从启动类启动,该类会使用继承自启动窗体虚基类的一个启动窗体类,在该类中定义启动窗体和主窗体。启动窗体和主窗体的代码略去,注意要删除机器生成的窗体代码的Main方法部分。     public class StartUpClass 
        { 
            [STAThread] 
            static void Main() 
            { 
                Application.Run(new mycontext()); 
            } 
        }     //启动窗体类(继承自启动窗体虚基类),启动画面会停留一段时间,该时间是设定的时间和主窗体构造所需时间两个的最大值 
        public class mycontext : SplashScreenApplicationContext 
        { 
            protected override void OnCreateSplashScreenForm() 
            { 
                this.SplashScreenForm = new FormStart();//启动窗体 
            }         protected override void OnCreateMainForm() 
            { 
                this.PrimaryForm = new FormMain();//主窗体 
            }         protected override void SetSeconds() 
            { 
                this.SecondsShow = 2;//启动窗体显示的时间(秒) 
            } 
        } 
    程序在vs2003下调试通过 
    HOW TO:溅射屏幕(Splash Screen),也叫程序启动画面的制作(.NET2003) Posted on 2005-10-31 20:40 水如烟(LzmTW) 阅读(1800) 评论(1)  编辑 收藏 网摘 所属分类: n、HOW TO系列  --> 
    Author:水如烟(LzmTW)      看到有人提起,就想动手做做。可能要花两天时间,因为时间是零零碎碎的。 
         哎,很多常用的东西,在2005版已经有了。当初看到好多人写基于2003的控件,这2005一出哪,全都没用了。心血白费了。这微软未免也太缺德了。应该说,2003是.NET的试用版,到了2005才算是正式版吧。或许基于2005的自写控件、组件寿命会长一些。否则,不骂娘才怪。 
         现在写写,也算是练练习吧。      溅射屏幕,即SplashScreenForm,有以下特点: 
         首先,程序是主窗体程序; 
         其次,SplashScreenForm在主窗体加载完毕后退出。      一般来说,SplashScreenForm比较简洁,窗体的内容只是显示程序主题、版权等信息;复杂些的,显示主程序的加载项目情况。 
         微软的SplashScreenForm向来简洁,Adobe的复杂些,就画窗体也花了一番心思。以下做的,以微软的作标准。      按照功能实现与界面分离的原则,这个类当然不能依赖于某个特定的SplashScreenForm或MainForm。参考了.NET2005的做法,继承了System.Windows.Forms.ApplicationContext做了一个SplashScreenApplicationContextClass基类。具体使用时,再继承这个类赋与特定参数,交Application.Run(ApplicationContext)来运行。因为基础知识不好,好多东西只知道用而不知为什么这样用,免不了的会出现这样那样的问题,请指正。      总体思路是:溅射屏幕显示的同时加载主窗体,主窗体加载完毕后关闭溅射屏幕,程序交给主窗体。溅射屏幕显示的时间由两个因素决定,一个是事前设定的溅射屏幕显示的时间,一个是主窗体加载所需要的时间,实际显示时间是两者中的最大值。      SplashScreenApplicationContextClass为什么要做为基类设计并要实现?主要考虑到主窗体在初始化时就需要时间,Sub New()是需要时间的,并非所有的程序都将初始事项放到Load()里头。      
    类:     Imports System.Windows.Forms 
    Imports System.Threading 
    Public MustInherit Class SplashScreenApplicationContextClass 
        Inherits System.Windows.Forms.ApplicationContext     Private _SplashScreenForm As Form 
        Private _SplashScreenTimer As System.Timers.Timer 
        Private _SplashScreenTimerInterVal As Integer = 5000 
        Private _MainFormFinshLoad As Boolean = False 
        Private _MainFormWindowState As Windows.Forms.FormWindowState 
        Private _CloseSplashScreen As Boolean = False     Private Delegate Sub DisposeDelegate()     Protected WriteOnly Property SplashScreenForm() As Form 
            Set(ByVal Value As Form) 
                Me._SplashScreenForm = Value 
            End Set 
        End Property     Protected WriteOnly Property SecondsShow() As Integer 
            Set(ByVal Value As Integer) 
                If Value <> 0 Then 
                    Me._SplashScreenTimerInterVal = 1000 * Value 
                End If 
            End Set 
        End Property 
        Sub New()         Me.ShowSplashScreen() 
            Me.MainFormLoad()     End Sub     Private Sub DoEvents() 
            Application.DoEvents() 
        End Sub     Protected MustOverride Sub OnCreateSplashScreenForm()     Protected MustOverride Sub OnCreateMainForm()     Protected MustOverride Sub SetSeconds()     Private Sub ShowSplashScreen() 
            Me.SetSeconds() 
            Me.OnCreateSplashScreenForm() 
            Me._SplashScreenTimer = New System.Timers.Timer(CType(Me._SplashScreenTimerInterVal, Double)) 
            AddHandler _SplashScreenTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf Me.SplashScreenDisplayTimeUp) 
            Me._SplashScreenTimer.AutoReset = False 
            Dim DisplaySpashScreenThread As New Thread(New ThreadStart(AddressOf Me.DisplaySplashScreen)) 
            DisplaySpashScreenThread.Start() 
        End Sub     Private Sub DisplaySplashScreen() 
            Me._SplashScreenTimer.Enabled = True 
            Application.Run(Me._SplashScreenForm) 
        End Sub     Private Sub SplashScreenDisplayTimeUp(ByVal sender As System.Object, ByVal e As System.timers.ElapsedEventArgs) 
            Me._SplashScreenTimer.Dispose() 
            Me._SplashScreenTimer = Nothing 
            Me._CloseSplashScreen = True 
        End Sub     Private Sub MainFormLoad() 
            Me.OnCreateMainForm() 
            _MainFormWindowState = Me.MainForm.WindowState '保存主窗体状态 
            Me.MainForm.WindowState = FormWindowState.Normal '非Normal情形下,主窗体会Show出来 
            AddHandler Me.MainForm.Load, New EventHandler(AddressOf Me.MainFormLoadingDone) 
        End Sub     Private Sub MainFormLoadingDone(ByVal sender As Object, ByVal e As EventArgs) 
            RemoveHandler Me.MainForm.Load, New EventHandler(AddressOf Me.MainFormLoadingDone) 
            Do While Not Me._CloseSplashScreen 
                Me.DoEvents() 
            Loop 
            Me.HideSplashScreen() 
        End Sub     Private Sub HideSplashScreen() 
            MainFormActivate() 
            '先激活主窗体再关闭启动窗体,是为了保证程序为当前活动程序 
            Dim SplashScreenFormDisposeDelegate As DisposeDelegate = New DisposeDelegate(AddressOf Me._SplashScreenForm.Dispose) 
            Me._SplashScreenForm.Invoke(SplashScreenFormDisposeDelegate) 
            Me._SplashScreenForm = Nothing 
        End Sub     Private Sub MainFormActivate() 
            If _MainFormWindowState = FormWindowState.Minimized Then _MainFormWindowState = FormWindowState.Normal 
            If Me.MainForm.WindowState <> _MainFormWindowState Then Me.MainForm.WindowState = _MainFormWindowState 
            Me.MainForm.Activate() 
        End Sub 
    End Class 使用:(SplashScreenForm我还是随便用一个Form来代替) Public Class App     Public Shared Sub Main() 
            Dim t As New MyContext 
            Application.Run(t) 
        End Sub End Class Public Class MyContext 
        Inherits SplashScreenApplicationContextClass     Protected Overrides Sub OnCreateMainForm() 
            Me.MainForm = New Form2 
        End Sub     Protected Overrides Sub OnCreateSplashScreenForm() 
            Me.SplashScreenForm = New Form1 
        End Sub     Protected Overrides Sub SetSeconds() 
            Me.SecondsShow = 3 '显示3秒,若是0则取默认值5秒 
        End Sub End Class 
      

  6.   

    如果存在正宗的  主,子关系的窗口,你还是HIDE吧.
    如果是名义上的主,子,但事实上子窗口跟主窗口没有主子关系...就简单了.如果不想HIDE,那你所谓的实现方法就等于是第二种了.而且,就.net而言,你HIDE.跟销毁所释放的资源差不多了.当然,如果你工程很大,要抓住每一丝资源.
    那我没话说...这是我的见解.
      

  7.   

    登录窗体在子窗体(应用程序主窗体)的Shown事件中ShowDialog()。frmLogin login = new frmLogin();
    if(login.ShowDialog()==DialogResult.OK)
    {
         //登录成功
    }else
    {
         //登录失败或未登录
    }
    参考
      

  8.   

    三楼的已经很好了!http://www.mybuffet.cn
      

  9.   

    两种方法 
    1.在项目入口直接弹出登陆窗口,对数据进行验证,成功即弹出主窗体
    2.在主窗体的Load事件中弹出登陆窗体,以ShowDialog(this)的方式,然后判断登陆
    正确的话就正常载入 。
      

  10.   

    非常感谢大家的回复,老师在讲课用的 登录窗体 是 子窗体,而 登录后 出现 的窗体 是主窗体。
    个人认为,使用hide方法比较好~
      

  11.   

    登陆的话一般在 Programe.cs 里做吧。进行判断。