简体   繁体   English

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

[英]How can I close a login form and show the main form without my application closing?

I have two forms in my project (Login and Main).我的项目中有两个 forms(Login 和 Main)。

What I'm trying to accoomplish is, if the login is successful, I must show the Main form and close the Login form.我想要完成的是,如果登录成功,我必须显示主窗体并关闭登录窗体。

I have this method in Login form that closes the Login form when the login is successful.我在登录表单中有这个方法,当登录成功时关闭登录表单。 But the Main form doesn't show.但是主窗体不显示。

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.");
    }         
}

I tried hiding the Login form if the login process is successful.如果登录过程成功,我尝试隐藏登录表单。 But it bothers me because I know while my program is running the login form is still there too, it should be closed right?但这让我很困扰,因为我知道当我的程序运行时登录表单也仍然存在,它应该关闭,对吗?

What should be the right approach for this?正确的方法应该是什么? Thanks...谢谢...

The reason your main form isn't showing is because once you close the login form, your application's message pump is shut down, which causes the entire application to exit. 无法显示主表单的原因是因为一旦关闭登录表单,应用程序的消息泵就会关闭,这将导致整个应用程序退出。 The Windows message loop is tied to the login form because that's the one you have set as the startup form in your project properties. Windows消息循环与登录表单相关联,因为这是您在项目属性中设置为启动表单的表单。 Look in your "Program.cs" file, and you'll see the responsible bit of code: Application.Run(new LoginForm()) . 查看“ Program.cs”文件,您将看到负责的代码: Application.Run(new LoginForm()) Check out the documentation for that method here on MSDN , which explains this in greater detail. MSDN上查看有关该方法的文档,这将对此进行更详细的说明。

The best solution is to move the code out of your login form into the "Program.cs" file. 最好的解决方案是将代码从登录表单中移出到“ Program.cs”文件中。 When your program first starts, you'll create and show the login form as a modal dialog (which runs on a separate message loop and blocks execution of the rest of your code until it closes). 程序首次启动时,您将创建并以模式对话框形式显示登录表单(该对话框在单独的消息循环上运行,并阻止其余代码的执行,直到关闭为止)。 When the login dialog closes, you'll check its DialogResult property to see if the login was successful. 登录对话框关闭后,您将检查其DialogResult属性以查看登录是否成功。 If it was, you can start the main form using Application.Run (thus creating the main message loop); 如果是这样,则可以使用Application.Run启动主窗体(从而创建主消息循环)。 otherwise, you can exit the application without showing any form at all. 否则,您可以退出应用程序而无需显示任何形式。 Something like this: 像这样:

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

I would do this the other way round. 我会反过来做。

In the OnLoad event for your Main form show the Logon form as a dialog. 在您的Main窗体的OnLoad事件中,将Logon窗体显示为对话框。 If the dialog result of that is OK then allow Main to continue loading, if the result is authentication failure then abort the load and show the message box. 如果对话框结果确定,则允许Main继续加载,如果结果是身份验证失败,则中止加载并显示消息框。

EDIT Code sample(s) 编辑代码示例

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

Another solution would be to show the LogonForm from the Main method in program.cs, something like this: 另一个解决方案是从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());
    }
}

In this example your LogonForm would have to expose out a LogonSuccessful bool property that is set to true when the user has entered valid credentials 在此示例中,您的LogonForm必须公开一个LogonSuccessful bool属性,该属性在用户输入有效凭据时设置为true

It's simple. 这很简单。

Here is the code. 这是代码。

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

This is my solution. 这是我的解决方案。 Create ApplicationContext to set mainform of application and change mainform when you want to open new form and close current form. 创建ApplicationContext来设置应用程序的主窗体,并在您要打开新窗体和关闭当前窗体时更改主窗体。

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

When login process is complete. 登录过程完成后。

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

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

        this.Close();
    }

I hope this will help you. 我希望这能帮到您。

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

This is the most elegant solution. 这是最优雅的解决方案。

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

;-) ;-)

Here's a simple solution, your problem is that your whole application closes when your login form closes right? 这是一个简单的解决方案,您的问题是,当您关闭登录表单时,整个应用程序也会关闭吗? If so, then go to your projects properties and on the Application Tab change the shutdown mode to "When last form closes" that way you can use Me.close without closing the whole program 如果是这样, 请转到项目属性 ,然后在“应用程序”选项卡上将关闭模式更改为“当最后一个表单关闭时” ,这样就可以使用Me.close而不关闭整个程序

Evan the post is too old i like to give you a trick to do this if you wants to show splash/login screen and when the progress bar of splash screen get certain value/or successful login happen and closed the splash/login then re show the main form, frm-main will be the startup form not frm-spalash 埃文(Evan)的帖子太旧了,如果您想显示启动画面/登录屏幕,并且当启动画面的进度条获得特定值/或者成功登录并关闭启动画面/登录,然后重新显示,我想给您一个窍门主要形式,frm-main将是启动形式,而不是frm-spalash

in frm-main 在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();
    }
 }

in the frm-Splash 在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;
}

if you use it for login form 如果用于登录表单

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

note that i use a timer and a progress bar to manipulate the actions you don't need those two it just for sake of complete answer only, hope this helps 请注意,我使用计时器进度条来操作您不需要这两个动作的动作,仅是为了完整回答,希望这对您有所帮助

you should do it the other way round: 您应该反过来做:

Load the mainform first and in its onload event show your loginform with showdialog() which will prevent mainform from showing until you have a result from the loginform 首先加载主mainform并在其onload事件中使用showdialog()显示您的loginform ,这将阻止mainform显示,直到您从loginform获得结果loginform

EDIT : As this is a login form and if you do not need any variables from your mainform ( which is bad design in practice ), you should really implement it in your program.cs as Davide and Cody suggested. 编辑 :这是一个登录表单,如果你不从你需要的任何变量mainform这是在实践中不好的设计 ),你应该实现它在你的Program.cs作为达维德和科迪建议。

我认为更好的方法是在通常具有Application.Run(form1)的Program.cs文件中执行此操作,以这种方式获得更简洁的方法,Login表单不需要与Main表单耦合,您只需显示登录名,如果返回true,则显示主表单,否则显示错误。

Try this: 尝试这个:

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

   }

You must call the new form in a diferent thread apartment, if I not wrong, because of the call system of windows' API and COM interfaces. 如果我没有记错的话,由于Windows的API和COM接口的调用系统,您必须在不同的线程单元中调用新表单。

One advice: this system is high insecure, because you can change the if condition (in MSIL) and it's "a children game" to pass out your security. 一个建议:该系统是高度不安全的,因为您可以更改if条件(在MSIL中),并且它是“孩子游戏”以传递安全性。 You need a stronger system to secure your software like obfuscate or remote login or something like this. 您需要一个功能更强大的系统来保护软件,例如混淆或远程登录或类似的东西。

Hope this helps. 希望这可以帮助。

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.");
        }         
   }

best way for show login for and close login form before login successfully put login form in FrmMain after InitializeComponent. 在成功登录之前显示登录并关闭登录表单的最佳方法是将登录表单放在InitializeComponent之后的FrmMain中。

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

      InitializeComponent();
      //Login Section
 {

try this 尝试这个

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

and when you exit the Application you can use 当您退出应用程序时,您可以使用

 Application.Exit();

1.Go to MainMenu Design properties> Go to my events 1.Go 到 MainMenu 设计属性 > Go 到我的事件在此处输入图像描述

2.Click MainMenu event Shown and show LoginForm 2.点击MainMenu事件显示并显示LoginForm 在此处输入图像描述

3.Leave MainMenu as the First run in Program.cs 3.将MainMenu保留为Program.cs中的First run

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 首页&gt; C#&gt;如何关闭主窗体而不让应用程序关闭? - c# - How to close the main form without letting the application close? 如何从另一个子表单中关闭子表单而不关闭主表单C# - How to close a sub form from another sub form without closing main form c# 在不关闭主窗体的情况下关闭第二个窗体时遇到问题 - Having problem to close a second windows form without closing the main form 如何成功从取消的登录表单中缩短我的应用程序,并在登录成功后调用我的主表单? - How can I cleanly shortcircuit my app from a canceled login form, and invoke my main form when login is successful? 是否允许在不关闭C#中的应用程序的情况下关闭Form1? - Allow Form1 to close without closing Application in C#? 当主表单出现时如何关闭登录表单? - How to close login form when main form appear? this.close()也关闭主窗体 - This.close() closing main form aswell 如何在不关闭表单2或不显示表单1的情况下从另一个表单刷新数据网格 - how can refresh a datagrid from another form without close form 2 or show form 1 C#-如何与子窗体一起关闭主窗体(而子窗口必须仅在主窗体关闭时关闭) - C# - How Do I Close Main Form Together With Child Forms (while child windows must close ONLY when main form is closing) 如何通过单击另一个表单中的按钮打开我的“登录”主表单? 并且无需再次登录 - How to open my "logged in" main form, by clicking a button from another Form? and without login again
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM