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

时间:2011-01-21 13:29:33

标签: c# .net winforms

我的项目中有两个表单(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.");
    }         
}

如果登录过程成功,我尝试隐藏登录表单。但它困扰我,因为我知道当我的程序运行时,登录表单仍然存在,它应该关闭吗?

应该采用什么方法? 感谢...

13 个答案:

答案 0 :(得分:100)

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

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

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

答案 1 :(得分:8)

我会反过来这样做。

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

编辑代码示例

private void MainForm_Load(object sender, EventArgs e)
{
    this.Hide();

    LogonForm logon = new LogonForm();

    if (logon.ShowDialog() != DialogResult.OK)
    {
        //Handle authentication failures as necessary, for example:
        Application.Exit();
    }
    else
    {
        this.Show();
    }
}

另一个解决方案是在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());
    }
}

在此示例中,您的LogonForm必须公开LogonSuccessful bool属性,该属性在用户输入有效凭据时设置为true

答案 2 :(得分:5)

很简单。

这是代码。

 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();
  }

答案 3 :(得分:4)

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

Program.cs的

static class Program
{
    static ApplicationContext MainContext = new ApplicationContext();

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        MainContext.MainForm = new Authenticate();
        Application.Run(MainContext);
    }

    public static void SetMainForm(Form MainForm)
    {
        MainContext.MainForm = MainForm;
    }

    public static void ShowMainForm()
    {
        MainContext.MainForm.Show();
    }
}

登录过程完成后。

private void BtLogin_Click(object sender, EventArgs e)
    {
        //Login Process Here.

        Program.SetMainForm(new Portal());
        Program.ShowMainForm();

        this.Close();
    }

我希望这会对你有所帮助。

答案 4 :(得分:2)

这是一个简单的解决方案,您的问题是当您的登录表单关闭时您的整个应用程序关闭了吗?如果是这样,那么转到您的项目属性,并在应用程序选项卡上将关闭模式更改为“当最后一个表单关闭时”,这样您就可以在不关闭整个程序的情况下使用Me.close

答案 5 :(得分:2)

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Login();
    } 

    private static bool logOut;

    private static void Login()
    {
        LoginForm login = new LoginForm();
        MainForm main = new MainForm();
        main.FormClosed += new FormClosedEventHandler(main_FormClosed);
        if (login.ShowDialog(main) == DialogResult.OK)
        {
            Application.Run(main);
            if (logOut)
                Login();
        }
        else
            Application.Exit();
    }

    static void main_FormClosed(object sender, FormClosedEventArgs e)
    {
        logOut= (sender as MainForm).logOut;
    }
}

public partial class MainForm : Form
{
    private void btnLogout_ItemClick(object sender, ItemClickEventArgs e)
    {
        //timer1.Stop();
        this.logOut= true;
        this.Close();
    }
}

答案 6 :(得分:2)

这是最优雅的解决方案。

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

- )

答案 7 :(得分:0)

你应该反过来这样做:

首先加载mainform并在其onload活动中显示loginform showdialog() mainform,这将阻止loginform显示,直到您获得结果mainform

修改: 由于这是一个登录表单,如果您不需要{{1}}中的任何变量(,这在实践中是糟糕的设计),您应该真正实现它你的program.cs就像Davide和Cody建议的那样。

答案 8 :(得分:0)

我认为更好的方法是在Program.cs文件中执行此操作,您通常使用Application.Run(form1),这样您就可以获得更清晰的方法,登录表单不需要耦合到Main表单,您只需显示登录名,如果返回true,则显示主窗体,否则显示错误。

答案 9 :(得分:0)

试试这个:

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中)并且它是“儿童游戏”以传递你的安全性。您需要一个更强大的系统来保护您的软件,如混淆或远程登录或类似的东西。

希望这有帮助。

答案 10 :(得分:0)

在登录成功之前显示登录和关闭登录表单的最佳方式是在InitializeComponent之后将登录表单放入FrmMain中。

 public FrmMain()
 {
      FrmSplash FrmSplash = new FrmSplash();
      FrmSplash.ShowDialog();

      InitializeComponent();
      //Login Section
 {

答案 11 :(得分:0)

Evan这个帖子太旧了我想给你一个技巧,如果你想要显示启动/登录界面,当启动画面的进度条获得特定值/或成功登录时关闭启动/登录然后重新显示主要形式,frm-main将是启动形式而不是frm-spalash

在frm-main

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-Splash

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
        }
}

请注意,我使用计时器进度条来操纵您不需要这两项的操作只是为了完整答案,希望这有助于

答案 12 :(得分:-1)

试试这个

 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();