Ocultar formulario en lugar de cerrar cuando se hace clic en el botón Cerrar

Cuando un usuario hace clic en el botón X de un formulario, ¿cómo puedo ocultarlo en lugar de cerrarlo?

He intentado this.hide() en FormClosing pero todavía cierra el formulario.

Al igual que:

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

(a través de Tim Huffman )

Ya lo comenté en una respuesta anterior, pero pensé en proporcionar la mía. En función de su pregunta, este código es similar a la respuesta principal, pero agrega la función que otro menciona:

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

Si el usuario simplemente está presionando la X en la ventana, el formulario se esconde; en todo caso, como el Administrador de tareas, Application.Exit() o el cierre de Windows, el formulario se cierra correctamente, ya que se ejecutará la statement de return .

Desde MSDN :

Para cancelar el cierre de un formulario, configure la propiedad Cancel de FormClosingEventArgs pasada a su manejador de eventos en true .

Entonces cancela y luego oculta.

Si quieres usar el método show / hide, lo he hecho yo mismo para una estructura de menú, un juego que he hecho recientemente … Así es como lo hice:

Cree usted mismo un botón y lo que le gustaría hacer, por ejemplo un botón ‘Siguiente’ y haga coincidir el siguiente código con su progtwig. Para un próximo botón en este ejemplo, el código sería:

 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. 

Aquí hay un fragmento del código que utilicé en mi juego para ayudarte a comprender lo que trato de explicar:

  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 } 

Entonces, hay un método mostrar / esconder algunas líneas de código, en lugar de hacer una pieza masiva de código para una tarea tan simple. Espero que esto ayude a resolver tu problema.

Tenga en cuenta que al hacer esto (se han publicado varias respuestas), también debe encontrar la forma de PERMITIR que el usuario cierre el formulario cuando realmente lo desee. Esto realmente se convierte en un problema si el usuario intenta apagar la máquina cuando la aplicación se está ejecutando, porque (al menos en algunos sistemas operativos) esto impedirá que el sistema operativo se cierre correctamente o de manera eficiente.

La forma en que resolví esto fue verificar el seguimiento de la stack: hay diferencias entre cuando el usuario intenta hacer clic en la X y cuando el sistema intenta finalizar la aplicación en preparación para el apagado.

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

Este es el comportamiento de las formas modales. Cuando usa form.ShowDialog() , está pidiendo este comportamiento. La razón de esto es que form.ShowDialog no regresa hasta que el formulario está oculto o destruido. Entonces, cuando el formulario está oculto, la bomba dentro de la forma. ShowDialog lo destruye para que pueda regresar.

Si desea mostrar y ocultar un formulario, entonces debe usar el modelo de diálogo sin forma http://msdn.microsoft.com/en-us/library/39wcs2dh(VS.80).aspx

form.Show() devuelve inmediatamente, puede mostrar y ocultar esta ventana todo lo que desee y no se destruirá hasta que la destruya explícitamente.

Cuando utiliza formularios no modales que no son secundarios de un formulario modal, entonces también necesita ejecutar un mensaje de bomba usando Application.Run o Application.DoEvents en un bucle. Si el hilo que crea un formulario sale, entonces el formulario será destruido. Si ese hilo no ejecuta una bomba, las formas que posee no responderán.

Editar: esto suena como el tipo de cosa que el ApplicationContext está diseñado para resolver. http://msdn.microsoft.com/en-us/library/system.windows.forms.applicationcontext.aspx

Básicamente, deriva una clase de ApplicationContext, pasa una instancia de su ApplicationContext como argumento a 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); 

El contexto de la aplicación necesitará saber cuándo está bien salir de la aplicación y si no se debe salir de la forma. Cuando es hora de que la aplicación salga. El contexto o formulario de su aplicación puede llamar al método ExitThread() del contexto de la aplicación para finalizar el ciclo de mensajes. En ese punto, Application.Run() volverá.

Sin saber más sobre la jerarquía de sus formularios y sus reglas para decidir cuándo ocultar formularios y cuándo salir, es imposible ser más específico.

En función de otra respuesta, puede ponerlo en su código de formulario:

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

Se prefiere la anulación: MSDN “El método OnFormClosing también permite que las clases derivadas manejen el evento sin asociar un delegado. Esta es la técnica preferida para manejar el evento en una clase derivada”.