C# 如何在不关闭应用程序的情况下关闭登录表单并显示主表单?

C# 如何在不关闭应用程序的情况下关闭登录表单并显示主表单?,c#,.net,winforms,C#,.net,Winforms,我的项目中有两个表单(Login和Main) 我试图完成的是,如果登录成功,我必须显示主窗体并关闭登录窗体 我在登录表单中有这个方法,当登录成功时关闭登录表单。但是主形式没有显示出来 public void ShowMain() { if(auth()) // a method that returns true when the user exists. { var main = new Main(); main.Sho

我的项目中有两个表单(Login和Main)

我试图完成的是,如果登录成功,我必须显示主窗体并关闭登录窗体

我在登录表单中有这个方法,当登录成功时关闭登录表单。但是主形式没有显示出来

public void ShowMain()
{
    if(auth()) // a method that returns true when the user exists.
    {             
        var main = new Main();
        main.Show();
        this.Close();
    }
    else
    {
        MessageBox.Show("Invalid login details.");
    }         
}
如果登录过程成功,我尝试隐藏登录表单。但这让我很烦恼,因为我知道当我的程序运行时,登录表单也在那里,它应该被关闭,对吗

正确的方法应该是什么?
谢谢…

我会反过来做

在主窗体的OnLoad事件中,将登录窗体显示为对话框。如果对话框结果为OK,则允许Main继续加载,如果结果为身份验证失败,则中止加载并显示消息框

编辑代码示例

另一种解决方案是在program.cs中显示Main方法中的LogonForm,类似于:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    LogonForm logon = new LogonForm();

    Application.Run(logon);

    if (logon.LogonSuccessful)
    {
        Application.Run(new MainForm());
    }
}
static void Main()
{
    LoginForm fLogin = new LoginForm();
    if (fLogin.ShowDialog() == DialogResult.OK)
    {
        Application.Run(new MainForm());
    }
    else
    {
        Application.Exit();
    }
}

在此示例中,您的LogonForm必须公开LogonSuccessful bool属性,当用户输入有效凭据时,该属性设置为true。您应该以另一种方式执行此操作:

首先加载
mainform
,然后在其
onload
事件中,使用
showlealog()
显示您的
loginform
,这将阻止
mainform
显示,直到您得到
loginform

编辑
由于这是一个登录表单,如果您不需要来自
main表单的任何变量(实际上这是一个糟糕的设计),您应该按照Davide和Cody的建议在program.cs中实现它。

我认为更好的方法是在program.cs文件中实现它,通常在该文件中有Application.Run(form1),通过这种方式,您可以获得一种更简洁的方法,登录表单不需要与主表单耦合,您只需显示登录,如果返回true,则显示主表单,否则显示错误。

主表单不显示的原因是,一旦您关闭登录表单,应用程序的消息泵就会关闭,这将导致整个应用程序退出。将绑定到登录表单,因为在项目属性中将该表单设置为启动表单。查看“Program.cs”文件,您将看到负责的代码:
Application.Run(new LoginForm())
。请在此处查看该方法的文档,其中详细解释了这一点

最好的解决方案是将代码从登录表单移到“Program.cs”文件中。当您的程序第一次启动时,您将创建登录表单并将其显示为一个模式对话框(该对话框在单独的消息循环上运行,并在关闭之前阻止其余代码的执行)。当登录对话框关闭时,您将检查其
DialogResult
属性以查看登录是否成功。如果是,您可以使用
应用程序启动主窗体。运行
(从而创建主消息循环);否则,您可以退出应用程序而不显示任何表单。大概是这样的:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    LogonForm logon = new LogonForm();

    Application.Run(logon);

    if (logon.LogonSuccessful)
    {
        Application.Run(new MainForm());
    }
}
static void Main()
{
    LoginForm fLogin = new LoginForm();
    if (fLogin.ShowDialog() == DialogResult.OK)
    {
        Application.Run(new MainForm());
    }
    else
    {
        Application.Exit();
    }
}
试试这个:

public void ShowMain()
    {
        if(auth()) // a method that returns true when the user exists.
        { 
            this.Close();
            System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(Main));
            t.Start();
        }
        else
        {
            MessageBox.Show("Invalid login details.");
        }         
    }
   [STAThread]
   public void Main()
   {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new Main());

   }
如果我没有错的话,您必须在不同的线程单元中调用新表单,因为windows的API和COM接口的调用系统

一个建议:这个系统是高度不安全的,因为你可以改变if条件(在MSIL中),这是一个“儿童游戏”来传递你的安全性。你需要一个更强大的系统来保护你的软件,比如模糊或远程登录之类的

希望这有帮助。

很简单

这是代码

 private void button1_Click(object sender, EventArgs e)
 {  
        //creating instance of main form
        MainForm mainForm = new MainForm();

        // creating event handler to catch the main form closed event
        // this will fire when mainForm closed
        mainForm.FormClosed += new FormClosedEventHandler(mainForm_FormClosed);
        //showing the main form
        mainForm.Show();
        //hiding the current form
        this.Hide();
  }

  // this is the method block executes when main form is closed
  void mainForm_FormClosed(object sender, FormClosedEventArgs e)
  {
       // here you can do anything

       // we will close the application
       Application.Exit();
  }

这里有一个简单的解决方案,您的问题是当您的登录表单关闭时,您的整个应用程序都会关闭,对吗?如果是这样,请转到您的项目属性,并在“应用程序”选项卡上将关闭模式更改为“上次表单关闭时”,这样您就可以使用Me.close而不关闭整个程序

在登录前显示登录并关闭登录表单的最佳方式在初始化组件后将登录表单放入FrmMain

public void ShowMain()
  {
       if(auth()) // a method that returns true when the user exists.
       {        
         this.Hide();
         var main = new Main();
         main.Show();
       }
      else
       {
              MessageBox.Show("Invalid login details.");
        }         
   }
 public FrmMain()
 {
      FrmSplash FrmSplash = new FrmSplash();
      FrmSplash.ShowDialog();

      InitializeComponent();
      //Login Section
 {
试试这个

 private void cmdLogin_Click(object sender, EventArgs e)
    {
        if (txtUserName.Text == "admin" || txtPassword.Text == "1")
        {

            FrmMDI mdi = new FrmMDI();
            mdi.Show();
            this.Hide();
        }
        else {

            MessageBox.Show("Incorrect Credentials", "Library Management System", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
    }
当您退出应用程序时,您可以使用

 Application.Exit();

这是最优雅的解决方案

private void buttonLogin_Click(object sender, EventArgs e)
{
    MainForm mainForm = new MainForm();
    this.Hide();
    mainForm.ShowDialog();
    this.Close();
}

;-)

这是我的解决方案。创建ApplicationContext以设置应用程序的mainform,并在要打开新表单和关闭当前表单时更改mainform

Program.cs
我希望这能对你有所帮助。

Evan这篇文章太老了,如果你想显示启动/登录屏幕,并且当启动屏幕的进度条获得一定值/或成功登录时,关闭启动/登录,然后重新显示主窗体,frm main将是启动窗体,而不是frm spalash

在frm主

public partial class frmMain : Form
{
    public frmMain()
    { 
        frmSplash frm = new frmSplash();
        frm.Show(); // new splash screen will shows
        this.Opacity=0; // will hide your main form
        InitializeComponent();
    }
 }
在frm飞溅中

private void timer1_Tick(object sender, EventArgs e)
{
 int cnt = progressBar1.Value;

    switch (cnt)
    {
        case 0:
                //Do sum stuff
            break;
        case 100:

            this.Close(); //close the frm-splash
            frmMain.ActiveForm.Opacity = 100; // show the frm-main

            break;
    }

    progressBar1.Value = progressBar1.Value+1;
}
如果您使用它作为登录表单

private void btlogin_Click(object sender, EventArgs e)
{
 bool login = false;

    //try your login here 
    //connect your database or whatever
    //and then when it success update login variable as true

        if(login == true){

            this.Close(); //close the frm-login
            frmMain.ActiveForm.Opacity = 100; // show the frm-main

        }else{
              //inform user about failed login
        }
}

请注意,我使用了一个计时器和一个进度条来操作您不需要这两个操作的操作。这仅仅是为了完整的答案,希望这有助于尝试调用this.Close(),而不是作为第一个操作name,整个应用程序将关闭。您可以尝试,main.ShowDialog();而不是main.Show();。它应该很好用。由于ShowDialog是无模式窗体。最初隐藏主窗体是否也可以。然后在登录成功时显示它?但是这样,如果在主窗体的加载中有一些逻辑,它仍然会被执行。。。您正在更改其他表单中显示工作流的表单。。。听起来有点脏和意大利面编程。为什么加载主窗体直到登录成功?1.当我使登录窗体显示在窗体加载上时。它仍然显示在背景上的主要形式。当我添加代码“this.hide();”时。现在是工作,看起来更专业。2.但是,当我看到其他注释时,其他注释在用户登录成功之前不应该执行主表单过程,所以我使用了您的第二个示例代码,这也是有效的。谢谢我真的无法想象
private void timer1_Tick(object sender, EventArgs e)
{
 int cnt = progressBar1.Value;

    switch (cnt)
    {
        case 0:
                //Do sum stuff
            break;
        case 100:

            this.Close(); //close the frm-splash
            frmMain.ActiveForm.Opacity = 100; // show the frm-main

            break;
    }

    progressBar1.Value = progressBar1.Value+1;
}
private void btlogin_Click(object sender, EventArgs e)
{
 bool login = false;

    //try your login here 
    //connect your database or whatever
    //and then when it success update login variable as true

        if(login == true){

            this.Close(); //close the frm-login
            frmMain.ActiveForm.Opacity = 100; // show the frm-main

        }else{
              //inform user about failed login
        }
}