c# - net - ¿Cuándo puedo disponer de un control WPF IDisposable, por ejemplo, WindowsFormsHost?
override void dispose (4)
El WPF controla WindowsFormsHost hereda de IDisposable.
Si tengo un árbol visual complejo de WPF que contiene algunos de los controles anteriores, ¿qué evento o método puedo usar para llamar ID durante el cierre?
No necesita disponer de controles al cerrar un formulario, la API lo hará por usted automáticamente si el control está en el árbol visual del formulario (como elemento secundario del formulario u otro control en el formulario)
En el caso de cierre de la aplicación, no hay nada que deba hacer para eliminar correctamente el WindowsFormsHost. Como se deriva de HwndHost, la eliminación se realiza cuando el Dispatcher se cierra. Si usa Reflector, verá que cuando HwndHost se inicializa crea un WeakEventDispatcherShutdown.
Si lo está utilizando en un cuadro de diálogo, lo mejor que puedo sugerir es anular OnClosed y deshacerse de su Host, de lo contrario, HwndHost permanecerá suspendido hasta que se cierre el Dispatcher.
public partial class Dialog : Window
{
public Dialog()
{
InitializeComponent();
}
protected override void OnClosed(EventArgs e)
{
if (host != null)
host.Dispose();
base.OnClosed(e);
}
}
Una forma simple de probar cuándo se llama a disponer es derivar una clase personalizada de WindowsFormsHost y jugar con diferentes situaciones. Ponga un punto de quiebre en el desecho y vea cuándo se llama.
public class CustomWindowsFormsHost : WindowsFormsHost
{
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
}
A partir de la respuesta de Todd, se me ocurrió esta solución genérica para cualquier control de WPF alojado en una ventana y quiero garantizar la eliminación cuando esa ventana se cierre.
(Obviamente si puedes evitar heredar de IDisposable do, pero a veces simplemente no puedes)
Dispose se invoca cuando se cierra la primera ventana principal de la jerarquía.
(Posible mejora: cambie el manejo del evento para usar el patrón débil)
public partial class MyCustomControl : IDisposable
{
public MyCustomControl() {
InitializeComponent();
Loaded += delegate(object sender, RoutedEventArgs e) {
System.Windows.Window parent_window = Window.GetWindow(this);
if (parent_window != null) {
parent_window.Closed += delegate(object sender2, EventArgs e2) {
Dispose();
};
}
};
...
}
...
}
Los controles WPF no implementan la interfaz IDisposable porque no tienen nada que desechar (no hay identificadores para limpiar, no hay memoria no administrada para liberar). Todo lo que necesita hacer es asegurarse de que no tiene ninguna referencia a los controles y el GC los limpiará.
Por lo tanto, WPF emplea patrones de eventos débiles para garantizar que los controles se puedan recolectar como basura. Este es el patrón que necesita implementar para garantizar la limpieza, no IDisposable.