C# 单击关闭按钮时隐藏表单而不是关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2021681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:45:30  来源:igfitidea点击:

Hide form instead of closing when close button clicked

c#.netwinforms

提问by iTEgg

When a user clicks the Xbutton on a form, how can I hide it instead of closing it?

当用户单击X表单上的按钮时,如何隐藏它而不是关闭它?

I have tried this.hide()in FormClosingbut it still closes the form.

我试过了this.hide()FormClosing但它仍然关闭了表单。

采纳答案by Alex

Like so:

像这样:

private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing) 
    {
        e.Cancel = true;
        Hide();
    }
}

(via Tim Huffman)

(通过蒂姆霍夫曼

回答by Jorge Córdoba

From MSDN:

MSDN

To cancel the closure of a form, set the Cancelproperty of the FormClosingEventArgspassed to your event handler to true.

要取消关闭表单,请将传递给事件处理程序的Cancel属性设置FormClosingEventArgstrue

So cancel then hide.

所以取消然后隐藏。

回答by Michael Bray

Note that when doing this (several answers have been posted) that you also need to find a way to ALLOW the user to close the form when they really want to. This really becomes a problem if the user tries to shut down the machine when the application is running, because (at least on some OS) this will stop the OS from shutting down properly or efficiently.

请注意,在执行此操作时(已经发布了几个答案),您还需要找到一种方法来允许用户在他们真正想要关闭表单时关闭表单。如果用户在应用程序运行时试图关闭机器,这确实会成为一个问题,因为(至少在某些操作系统上)这将阻止操作系统正确或有效地关闭。

The way I solved this was to check the stack trace - there are differences between when the user tries to click the Xvs when the system tries to end the application in preparation for shutdown.

我解决这个问题的方法是检查堆栈跟踪 - 用户尝试单击X与系统尝试结束应用程序以准备关闭时之间存在差异。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    StackTrace trace = new StackTrace();
    StackFrame frame;
    bool bFoundExitCommand = false;
    for (int i = 0; i < trace.FrameCount; i++)
    {
        frame = trace.GetFrame(i);
        string methodName = frame.GetMethod().Name;
        if (methodName == "miExit_Click")
        {
            bFoundExitCommand = true;
            Log("FormClosing: Found Exit Command ({0}) - will allow exit", LogUtilityLevel.Debug3, methodName);
        }
        if (methodName == "PeekMessage")
        {
            bFoundExitCommand = true;
            Log("FormClosing: Found System Shutdown ({0}) - will allow exit", LogUtilityLevel.Debug3, methodName);
        }
        Log("FormClosing: frame.GetMethod().Name = {0}", LogUtilityLevel.Debug4, methodName);
    }
    if (!bFoundExitCommand)
    {
        e.Cancel = true;
        this.Visible = false;
    }
    else
    {
        this.Visible = false;
    }
}

回答by John Knoeller

This is the behavior of Modal forms. When you use form.ShowDialog()you are askingfor this behavior. The reason for this is that form.ShowDialog doesn't return until the form is hidden or destroyed. So when the form is hidden, the pump inside form.ShowDialog destroys it so that it can return.

这是模态形式的行为。当您使用时,form.ShowDialog()您是在要求这种行为。这样做的原因是 form.ShowDialog 在表单被隐藏或销毁之前不会返回。所以当表单被隐藏时,form.ShowDialog 中的泵会破坏它以便它可以返回。

If you want to show and hide a form, then you should be using the Modeless dialog model http://msdn.microsoft.com/en-us/library/39wcs2dh(VS.80).aspx

如果要显示和隐藏表单,则应使用无模式对话框模型 http://msdn.microsoft.com/en-us/library/39wcs2dh(VS.80).aspx

form.Show()returns immediately, you can show and hide this window all you want and it will not be destroyed until you explicitly destroy it.

form.Show()立即返回,您可以随心所欲地显示和隐藏此窗口,并且在您明确销毁它之前它不会被销毁。

When you use modeless forms that are not children of a modal form, then you also need to run a message pump using Application.Runor Application.DoEventsin a loop. If the thread that creates a form exits, then the form will be destroyed. If that thread doesn't run a pump then the forms it owns will be unresponsive.

当您使用不是模态表单的子级的无模式表单时,您还需要使用Application.RunApplication.DoEvents在循环中运行消息泵。如果创建表单的线程退出,则该表单将被销毁。如果该线程不运行泵,则它拥有的表单将无响应。

Edit: this sounds like the sort of thing that the ApplicationContextis designed to solve. http://msdn.microsoft.com/en-us/library/system.windows.forms.applicationcontext.aspx

编辑:这听起来像是ApplicationContext旨在解决的事情。http://msdn.microsoft.com/en-us/library/system.windows.forms.applicationcontext.aspx

Basically, you derive a class from ApplicationContext, pass an instance of your ApplicationContext as an argument to Application.Run()

基本上,您从 ApplicationContext 派生一个类,将 ApplicationContext 的实例作为参数传递给 Application.Run()

// Create the MyApplicationContext, that derives from ApplicationContext,
// that manages when the application should exit.

MyApplicationContext context = new MyApplicationContext();

// Run the application with the specific context. 
Application.Run(context);

Your application context will need to know when it's ok to exit the application and when having the form(s) hidden should not exit the application. When it's time for the app to exit. Your application context or form can call the application context's ExitThread()method to terminate the message loop. At that point Application.Run()will return.

您的应用程序上下文需要知道何时可以退出应用程序以及何时隐藏表单不应退出应用程序。应用程序何时退出。您的应用程序上下文或表单可以调用应用程序上下文的ExitThread()方法来终止消息循环。到时候Application.Run()就会回来。

Without knowing more about the heirarchy of your forms and your rules for deciding when to hide forms and when to exit, it's impossible to be more specific.

如果不了解表单的层次结构以及决定何时隐藏表单和何时退出的规则,就不可能更具体。

回答by LizB

I've commented in a previous answer but thought I'd provide my own. Based on your question this code is similar to the top answer but adds the feature another mentions:

我在之前的回答中发表过评论,但我想我会提供我自己的。根据您的问题,此代码类似于最佳答案,但添加了另一个提到的功能:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing) 
    {
        e.Cancel = true;
        Hide();
    }
}

If the user is simply hitting the Xin the window, the form hides; if anything else such as Task Manager, Application.Exit(), or Windows shutdown, the form is properly closed, since the returnstatement would be executed.

如果用户只是点击X窗口中的 ,表单就会隐藏;如果有其他任何东西,例如任务管理器、Application.Exit()或 Windows 关闭,则该表单将被正确关闭,因为该return语句将被执行。

回答by Craig

If you want to use the show/hide method I've actually done this myself for a menu structure a game I've recently done... This is how I did it:

如果你想使用显示/隐藏方法,我实际上已经为我最近完成的一个游戏的菜单结构做了这个......我是这样做的:

Create yourself a button and for what you'd like to do, for example a 'Next' button and match the following code to your program. For a next button in this example the code would be:

为自己创建一个按钮和您想做的事情,例如“下一步”按钮,并将以下代码与您的程序相匹配。对于此示例中的下一个按钮,代码将是:

btnNext.Enabled = true; //This enabled the button obviously
this.Hide(); //Here is where the hiding of the form will happen when the button is clicked
Form newForm = new newForm(); //This creates a new instance object for the new form
CurrentForm.Hide(); //This hides the current form where you placed the button.

Here is a snippet of the code I used in my game to help you understand what I'm trying to explain:

这是我在游戏中使用的代码片段,以帮助您理解我要解释的内容:

    private void btnInst_Click(object sender, EventArgs e) 
    {
        btnInst.Enabled = true; //Enables the button to work
        this.Hide(); // Hides the current form
        Form Instructions = new Instructions(); //Instantiates a new instance form object 
        Instructions.Show(); //Shows the instance form created above
    }

So there is a show/hide method few lines of code, rather than doing a massive piece of code for such a simple task. I hope this helps to solve your problem.

所以有一个显示/隐藏方法几行代码,而不是为这样一个简单的任务做大量的代码。我希望这有助于解决您的问题。

回答by Orace

Based on other response, you can put it in your form code :

根据其他回复,您可以将其放入表单代码中:

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        base.OnFormClosing(e);
        if (e.CloseReason == CloseReason.UserClosing)
        {
            e.Cancel = true;
            Hide();
        }
    }

The override is preferred: MSDN"The OnFormClosing method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class. "

首选覆盖:MSDN“OnFormClosing 方法还允许派生类在不附加委托的情况下处理事件。这是在派生类中处理事件的首选技术。”