¿Cómo deshabilitar el formulario de cierre Alt + F4?

79

¿Cuál es la mejor manera de deshabilitar Alt+ F4en el formulario ac # win para evitar que el usuario cierre el formulario?

Estoy usando un formulario como cuadro de diálogo emergente para mostrar una barra de progreso y no quiero que el usuario pueda cerrarlo.

Ryan Sampson
fuente
Dentro del controlador de eventos FormClosing, ¿no podría interrogar al búfer del teclado (¿tiene siquiera acceso a esto?) Para ver si se presionó [Alt] + [F4], cancelar si es verdadero, continuar si no?
TK.

Respuestas:

107

Esto hace el trabajo:

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

Editar: En respuesta a la inquietud de pix0rs, sí, tiene razón en que no podrá cerrar programáticamente la aplicación. Sin embargo, simplemente puede eliminar el controlador de eventos para el evento form_closing antes de cerrar el formulario:

this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Close();
Martín
fuente
4
Sospecho que la mayoría de la gente está implementando este método en el formulario en cuestión (Form1). En este caso, se recomienda que no adjunte un delegado, sino que anule el método OnFormClosing. "El método OnFormClosing también permite que las clases derivadas manejen el evento sin adjuntar un delegado. Esta es la técnica preferida para manejar el evento en una clase derivada". tinyurl.com/3dzzljq
antsyawn
10
Me hubiera hecho el controlador de eventos, tales como: e.Cancel = (e.Reason == CloseReason.UserClosing);. De esta forma garantizas que no cerrarás solo cuando el USUARIO intente cerrar el formulario.
Paulo Santos
Este enfoque tiene un gran problema: si desea apagar / reiniciar su PC, también cancelará esa solicitud (al menos en Windows XP)
conceptacid
¡Eso es brillante! Especialmente me encanta eliminar el evento cuando quieres cerrar el formulario. ¡¡¡Es tan simple!!!
Será el
@Will: He editado la respuesta. Ahora hay una solución que funciona sin eliminar el controlador de eventos.
Thomas Weller
59

Si observa el valor de FormClosingEventArgs e.CloseReason, le dirá por qué se cierra el formulario. A continuación, puede decidir qué hacer, los valores posibles son:

Nombre del miembro - Descripción


Ninguno : la causa del cierre no se definió o no se pudo determinar.

WindowsShutDown : el sistema operativo cierra todas las aplicaciones antes de apagarse.

MdiFormClosing : el formulario principal de este formulario de interfaz de múltiples documentos (MDI) se está cerrando.

UserClosing : el usuario cierra el formulario a través de la interfaz de usuario (UI), por ejemplo, al hacer clic en el botón Cerrar en la ventana del formulario, seleccionar Cerrar en el menú de control de la ventana o presionar ALT+ F4.

TaskManagerClosing : el Administrador de tareas de Microsoft Windows está cerrando la aplicación.

FormOwnerClosing : el formulario del propietario se está cerrando.

ApplicationSalirCall : se invocó el método Exit de la clase Application.

Matt Warren
fuente
8
Si solo rompieran UserClosing para ser más granular para que pudiera apuntar a Alt + F4 específicamente ...
blak3r
if (e.CloseReason == CloseReason.UserClosing) {e.Cancel = true; }
adnan 2 de
Combine CloseReasony DialogResultpara obtener mejores resultados.
Thomas Weller
25

Creo que esta es la forma correcta de hacerlo:

protected override void OnFormClosing(FormClosingEventArgs e)
{
  switch (e.CloseReason)
  {
    case CloseReason.UserClosing:
      e.Cancel = true;
      break;
  }

  base.OnFormClosing(e);
}
Antsyawn
fuente
mejor reemplace el descanso con regreso
Bahadır Yağan
En realidad, creo que el patrón correcto es establecer el indicador de cancelación en verdadero y luego llamar a la clase base. Al anular los métodos On [Event], es importante llamar a la clase base para que los suscriptores del evento también sean notificados del evento. Sí, en este caso es fácil pensar que, dado que canceló el evento, nadie más necesita saberlo, pero no creo que sea correcto hacer esa suposición.
antsyawn
No estoy seguro del motivo, pero si llamo a la clase base, mi aplicación se bloquea después de otra pulsación posterior de Alt + F4. Al principio pensé que era porque F4 simple tiene algún otro significado en mi aplicación, pero una larga sesión de depuración mostró lo contrario. De todos modos, todavía puede ser un caso específico de mi lado. Gracias por esta gran respuesta.
Bahadır Yağan
Llamar a la clase base también hace que mi aplicación se bloquee en Alt + F4 posteriores. Sospecho que la clase base no marca e.Cancel e intenta destruir el formulario de todos modos.
Natan Yellin
Debe investigar por qué su aplicación se bloquea; es probable que esté haciendo algo mal en otro lugar. Los documentos dicen "El evento FormClosing ocurre mientras se cierra el formulario. Cuando se cierra un formulario, se elimina, liberando todos los recursos asociados con el formulario. Si cancela este evento, el formulario permanece abierto. Para cancelar el cierre de un formulario, establezca la propiedad Cancel de FormClosingEventArgs pasado a su controlador de eventos en true. " tinyurl.com/3tb7y9q
antsyawn
16

Tenga en cuenta que se considera de mala forma que una aplicación evite por completo el cierre. Debe verificar los argumentos del evento para el evento de cierre para determinar cómo y por qué se solicitó el cierre de su aplicación. Si se debe a un cierre de Windows, no debe evitar que se produzca el cierre.

Lasse V. Karlsen
fuente
13

Se podía manejar el FormClosingevento y conjunto FormClosingEventArgs.Cancela true.

Timbo
fuente
12

Estoy usando un formulario como cuadro de diálogo emergente para mostrar una barra de progreso y no quiero que el usuario pueda cerrarlo.

Si el usuario está decidido a cerrar su aplicación (y tiene el conocimiento suficiente para presionar alt + f4, lo más probable es que también tenga el conocimiento suficiente para ejecutar el administrador de tareas y eliminar su aplicación en su lugar.

Al menos con alt + f4 su aplicación puede hacer un cierre elegante, en lugar de simplemente hacer que la gente la mate. Por experiencia, las personas que matan su aplicación significan archivos de configuración corruptos, bases de datos rotas, tareas a medio terminar que no puede reanudar y muchas otras cosas dolorosas.

Al menos incítelos con "¿estás seguro?" En lugar de prevenirlo.

Orion Edwards
fuente
8

Este es un truco para deshabilitar Alt+ F4.

private void test_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.ModifierKeys == Keys.Alt || this.ModifierKeys == Keys.F4) 
    { 
        e.Cancel = true; 
    }    
}
Brahim Bourass
fuente
Puedo confirmar que esto funciona. Sin embargo, si lo usa System.Windows.Forms, deberá verificar la Control.ModifierKeyspropiedad estática , en lugar de la this.ModifierKeyspropiedad (como se muestra en el fragmento de arriba).
Salsa especial
Este enfoque es mejor porque de esta manera puede permitir que su aplicación se cierre con el método Close (), que comparte el motivo CloseReason.UserClosing. Mi preocupación con este enfoque es que la información de la tecla presionada actualmente es siempre precisa.
Adam LS
4

Formulario de suscripción Evento de clausura

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

Solo una línea en el cuerpo del método.

linquizar
fuente
3

Esto hace el trabajo:

bool myButtonWasClicked = false;
private void Exit_Click(object sender, EventArgs e)
{
  myButtonWasClicked = true;
  Application.Exit();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
  if (myButtonWasClicked)
  {
    e.Cancel = false;
  }
  else
  {
    e.Cancel = true;
  }


}
Condorkunka
fuente
2

¿Se llamaría a FormClosing incluso cuando esté cerrando la ventana mediante programación? Si es así, probablemente desee agregar algún código para permitir que el formulario se cierre cuando haya terminado con él (en lugar de cancelar siempre la operación)

pix0r
fuente
La respuesta a tu pregunta es sí". No publique preguntas adicionales como respuesta. Ya hay una respuesta realmente buena, muy votada y aceptada. Si no le importa, ¿podría eliminar el suyo? Realmente no agrega valor. He votado a favor de 3 de sus respuestas para compensar la eliminación.
Thomas Weller
-3

Oculte el botón de cierre en el formulario utilizando lo siguiente en el constructor del formulario:

this.ControlBox = false;
Bharat theorare
fuente