通过调用按钮单击事件处理 winForm 中的关闭事件会导致两种不同的行为

Posted

技术标签:

【中文标题】通过调用按钮单击事件处理 winForm 中的关闭事件会导致两种不同的行为【英文标题】:Handling Closing event in winForm by calling a button click event results in two different behaviour 【发布时间】:2021-09-17 15:36:29 【问题描述】:

我有一个简单的 winForm 并希望使用关闭事件并将用户重定向到注销过程。注销过程由按钮单击事件处理。当用户按下注销按钮并选择否时,它将保留在页面上,用户可以继续使用该应用程序。在关闭事件中,我调用了注销按钮事件方法,但是当用户选择否时,窗口关闭并且程序仍在运行。我想知道发送给方法的事件是否不同,或者基本上为什么会发生?

using System;
using System.Drawing;
using System.Windows.Forms;

namespace myApp 
public partial class frmMain : Form 

    readonly private string password = "user";
    readonly private string username = "pass";

    public frmMain() 
        InitializeComponent();
        this.MaximumSize = new Size(348, 247);
        this.MinimumSize = new Size(348, 247);
    

    private void frmMain_Load(object sender, EventArgs e) 

        txtPass.MaxLength = 8;
        txtPass.PasswordChar = '*';
    

    private void btnLogin_Click(object sender, EventArgs e) 
        bool goOn = txtPass.Text.Equals(this.password) && txtUser.Text.Equals(this.username);

        if (goOn) 
            this.Visible = false;
            Form2 f = new Form2();
            f.Show();
        
        else 
            MessageBox.Show("Username or Password is not correct", "Invalid Input", MessageBoxButtons.OK);
        

    

    private void frmMain_FormClosing(object sender, FormClosingEventArgs e) 
        Environment.Exit(0);
    
 // end main form

以及登录后的第二种形式:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;

namespace myApp
public partial class Form2 : Form 

        public Form2() 
        InitializeComponent();
        this.MaximumSize = new Size(1032, 691);
        this.MinimumSize = new Size(1032, 691);

    
private void Form2_Load(object sender, EventArgs e)
Button btnLogout = new Button();
btnLogout.Text = "Logout";
btn.Location = new Point(10, 10);
this.Controls.Add(btn);


private void btnLogout_Click(object sender, EventArgs e) 

            DialogResult result = MessageBox.Show("Do you want to logout?", "Logout",  MessageBoxButtons.YesNo);

            if (result == DialogResult.Yes) 
                this.Visible = false;
                frmMain f = new frmMain();
                f.Show();
            
            else 
                return;
            
         // end logout

        private void Form2_FormClosing(object sender, FormClosingEventArgs e) 
            btnLogout_Click(sender, e);
        

这张图显示了在closure 事件中没有选择任何选项后进程仍在运行,但没有打开窗口。

使用tasklist 命令检查 CMD 显示应用程序仍在运行。 myApp.exe 在任务列表中。

【问题讨论】:

哪个分支没有达到您的预期?是的还是没有的? @mjwills 没有人会有所不同。在 btnLogout_Click 它保持应用程序运行并打开窗口,但在 Form2_FormClosing 中关闭窗口但应用程序仍在运行。是的选项工作正常。 你怎么知道应用还在运行? 在调试会话中,它仍在 IDE 中运行。似乎它没有退出环境。我必须从 IDE 中阻止它。 为什么要在 btnLogout_Click 中创建另一个 frmMain 实例? 【参考方案1】:

FormClosing 方法将在最后关闭表单,您应该取消表单关闭过程。

试试这个Form2_FormClosing

private void Form2_FormClosing(object sender, FormClosingEventArgs e) 
    DialogResult result = MessageBox.Show("Do you want to logout?", "Logout",  MessageBoxButtons.YesNo);

    if (result == DialogResult.Yes) 
        this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing);
        this.Visible = false;
        frmMain f = new frmMain();
        f.Show();
    
    else 
        e.Cancel = true;
    

然后btnLogout点击:

private void btnLogout_Click(object sender, EventArgs e) 
    this.Close();

【讨论】:

【参考方案2】:

在表单关闭事件中,表单关闭后,与之关联的所有资源都将被释放并处置。为避免表单的 Cancel 属性可以设置为 true 以停止关闭表单。

  private void Form2_FormClosing(object sender, FormClosingEventArgs e)
       button1_Click( sender, e);
       e.Cancel = true;   
    

【讨论】:

以上是关于通过调用按钮单击事件处理 winForm 中的关闭事件会导致两种不同的行为的主要内容,如果未能解决你的问题,请参考以下文章

winform单击按钮重新加载本窗体

请问Winform里面怎么单击按钮来改变窗体背景图片?(C#)

delphi 如何通过单击一个窗体的按钮给一个frame的控件赋值

C#如何将方法传递给基本的WinForm按钮单击事件

如何模拟 Winforms 按钮单击上的“mailto:”调用?

winform中 怎样取消关闭窗体事件