c# winforms

c# - ¿Cuál es la forma correcta de deshacerse de un nuevo formulario sin que se cierre de inmediato?



winforms (4)

Entonces, en mis aplicaciones, tiendo a crear nuevas instancias de formularios sobre la marcha, luego uso Form.Show () para mostrarlos (no modal).

private void test_click(object sender, EventArgs e) { var form = new myForm(); form.Show(); }

Sin embargo, Code Cracker me dice que estos formularios deben eliminarse. Entonces, los envolví con la declaración "usar", pero luego se cierran inmediatamente después de abrirlos.

using (var form = new myForm()) { form.Show(); }

No quiero usar Form.ShowDialog (), porque en algunos casos estoy abriendo nuevas ventanas que solo muestran informes; No necesito que sean modales.


Entonces, de acuerdo con la respuesta en thread , los formularios no modales se eliminan automáticamente cada vez que los cierra.

Decidí probar esto abriendo mi formulario de prueba varias veces y cerrándolos. Incluso abrí varias instancias al mismo tiempo. Después de un segundo o dos, se recuperó la memoria utilizada por estas formas, lo que indicaría que se estaban eliminando correctamente.


Hmm, "descifrador de código" parece ser un término muy apropiado para esa herramienta, su consejo ciertamente te hizo escribir código que rompe tu programa. La regla de oro es no confiar nunca en los consejos desechables de una herramienta de análisis de código estático, ninguno de ellos tiene suficiente información sobre la ejecución del código. Nunca pueden averiguar qué llamada Dispose () hace el trabajo.

Lo que no puede ver es que la clase Form ya sabe cómo deshacerse. Es muy fácil hacerlo, el objeto queda inutilizable cuando se cierra la ventana. Cuando no hay más ventanas, entonces no hay razón para seguir usando el objeto Form. Un lujo que de otra manera no es muy común en .NET, pero ciertamente inspirado por programadores muy inteligentes que trabajaron para Xerox hace 45 años.

Solo debe tener en cuenta una regla especial: no se elimina cuando usa ShowDialog () para mostrar la ventana. Eso fue intencional, hace que recuperar los resultados del diálogo sea demasiado arriesgado. Usar la instrucción de uso para una llamada ShowDialog () es muy fácil de hacer, la llamada no regresa hasta que se cierra la ventana.


Puede implementar una especie de administrador de formularios que se suscribirá al OnFormClosedEvent para cada formulario que muestre, luego puede eliminarlos ... algo como:

public class FormManager { public T ShowForm<T>() where T : Form, new() { var t = new T(); t.OnFormClosing += DisposeForm; return t; } void DisposeForm(object sender, FormClosedEventArgs args) { ((Form)sender).Dispose(); } }

Incluso podría ir tan lejos como para implementar IDisposable y eliminar todos los formularios no desechados cuando se elimine el administrador :)


¿Necesito desechar un formulario después de que se cerró el formulario?

Cuando cierre un Form , se enviará un mensaje WM_CLOSE a la ventana. Si observa el código fuente del método WmClose que maneja el mensaje WM_CLOSE , verá:

  • Para los formularios modales (que mostró usando ShowDialog ), no se llamará al método Dispose y el formulario existe después del cierre y puede usar sus propiedades para obtener algunos datos o puede volver a mostrarlo.

  • Para los formularios no modales (que mostró usando Show ), después de que se cerró el formulario, se llamará al método Dispose .

Así que aquí está la conclusión:

  • Cuando muestra un formulario utilizando el método Show , no necesita (y no puede) llamar a Dispose . El formulario se eliminará solo después de cerrarse.

  • Cuando muestra un formulario usando ShowDialog , debe llamar a Dispose manualmente. Una buena práctica es usar formas modales en un bloque de using .