2010-05-10 17 views
7

Esto debe ser una pregunta tonta, pero no puedo resolverlo. Tampoco puedo usar el diseñador porque los codificadores antes que yo logramos lanzar la GUI y la lógica, todo en uno, por lo que ahora está confundido. Tengo que hacerlo a la vieja usanza..NET Windows Forms: interceptando el evento Close X

Tengo un formulario que se puede cerrar de 3 formas: botón Cerrar, menú Archivo/Cerrar y el ícono X. Quiero que todos hagan lo mismo. Interceptar el botón y los eventos del menú es fácil. De hecho, ambos están conectados a un método onCloseConfig. Por cierto, ¿hay un mejor nombre para este método?

private void onCloseConfig(object sender, System.EventArgs e) 
{ 
    if (! m_configControl.Modified) 
    { 
     Application.Exit(); // Or should it be this.Close(); 
    } 
    .... 
    // Else present a dialog, ask if they want to save. 
} 

Por lo tanto, para interceptar el X Traté: this.FormClosing +=new FormClosingEventHandler(this.onCloseConfig); Creo que esto es lo que causa un bucle infinito. No quiero eso :) FormClosed es otra opción, pero parece demasiado tarde. Solo quiero interceptar el hecho de que se hizo clic en la X, no el hecho de que el formulario se está cerrando.

Respuesta

12

Creo que desea cerrar el formulario, lo que puede faltar es verificar el motivo del cierre y solo cancelarlo si es del usuario, p.

private void my_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (e.CloseReason == CloseReason.UserClosing) 
    { 
    e.Cancel = true; //I'm sorry Dave, I'm afraid I can't do that. 
    } 
} 

para ocultar la 'X' establece Form.ControlBox = false, pero esto se librará de mínimo/máximo también.

+0

¡Genial! ¿Hay alguna manera de ocultar X por completo? –

+0

No sin rodar su propia ventana cromada. – Nate

+1

usted puede deshacerse del mínimo y cerca de cero –

0

Esto debería dejar de ventana de cierre: FormClosing (remitente objeto, System.EventArts e) { si (e.CloseReason == CloseReason.UserClosing) e.Cancel = true; }

+1

System.EventArts [sic] o EventArgs no tienen un miembro de CloseReason, necesita FormClosingEventArgs como en mi respuesta –

1

Btw, ¿hay un mejor nombre para este método ?

Cerrar [FormName] podría ser una mejor opción.

O debería ser esto. Cerrar();

Sí, si todo lo que desea es cerrar el formulario.

Debe crear un nuevo controlador de eventos para el evento FormClosing. Toma FormClosingEventArgs y no EventArgs como parámetro. En los manejadores de clics del botón y del elemento del menú, simplemente haga esto. Cerrar().

Esto llamará al evento y puede colocar allí todos sus cheques.

3

crear un método independiente para el botón/cerrar el menú:

private void myButton_Click(object sender, EventArgs e) 
{ 
    this.Close(); 
} 

private void myMenuButton_Click(object sender, EventArgs e) 
{ 
    this.Close(); 
} 

private void myForm_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (m_configControl.Modified) 
    { 
     var result = MessageBox.Show("Name Of Application", "Would you like to save before closing?", MessageBoxButtons.YesNoCancel); 
     if(result == DialogResult.Yes) 
      //Save here 
     else if(result == DialogResult.Cancel) 
      e.Cancel = true; 
    } 
} 

O bien, puede desactivar el botón de cierre ("X") por completo mediante el establecimiento de this.ControlBox = false

+0

+1 Para crear un método independiente y explicar la respuesta. =) –

1

El FormClosed event se produce una vez que el formulario está cerrado. Eso definitivamente no es lo que quieres.

Es más probable que FormClosing event sea lo que necesita.

El evento FormClosing se desencadena independientemente del botón o del enlace de menú. Todo lo que intente cerrar el formulario desencadenará el evento FormClosing.

Ahora, el camino más apropiado utilizar el FormClosingEventArgs sería lo siguiente dentro de su método de control de eventos FormClosing:

if(m_configControl.Modified) 
    e.Cancel = true; 

por lo menos que se modifique el control de configuración, la forma mantendrá el cierre. Desea evitar que se cierre solo si hay cambios o cambios no guardados.

EDIT 2 Después de volver a leer su pregunta, ver más abajo mis cambios al código superior:

if(m_configControl.Modified) 
    if(DialogResult.OK == MessageBox.Show("Do you want to save changes?", "Changes detected") 
     SaveChanges(); 

Esto entonces solicitar al usuario cambios sin guardar y guardar sólo si el usuario hace clic en Aceptar en el cuadro de mensaje. Tenga en cuenta que deberá agregar los botones según corresponda en los parámetros adicionales del método MessageBox.Show().

Si usted quiere lograr un Sí/No/Cancel en FormClosing, entonces usted tendrá que ir de esta manera:

if(m_configControl.Modified) { 
    DialogResult dr = MessageBox.Show(...); 
    switch(dr) { 
     case DialogResult.OK: 
      SaveChanges(); 
      break; 
     case DialogResult.No: 
      // Do nothing... 
      break; 
     case DialogResult.Cancel: 
      e.Cancel = true; 
    } 
} 

Así, cuando el usuario hace clic en Sí, la aplicación va a guardar los cambios. Cuando hace clic en No, la aplicación no hará nada al respecto y continuará su cierre. Cuando el usuario desea volver a la aplicación, se evitará Cerrar.

EDIT 1 Eche un vistazo a mi respuesta a This Question, que parece todo lo que desea lograr.

Cuestiones relacionadas