Question

Le contrôle WPF WindowsFormsHost hérite d’IDisposable.

Si j’ai un arbre visuel WPF complexe contenant certaines des commandes ci-dessus, quel événement ou quelle méthode puis-je utiliser pour appeler IDispose à l’arrêt?

Était-ce utile?

La solution 2

En me basant sur la réponse de Todd, j’ai proposé cette solution générique pour tout contrôle WPF hébergé par une fenêtre et souhaitant garantir son élimination lorsque cette fenêtre est fermée.

(Évidemment, si vous pouvez éviter d'hériter d'IDisposable, mais que parfois vous ne le pouvez pas)

Dispose est appelé lorsque la première fenêtre parente de la hiérarchie est fermée.

(Amélioration possible - modifier le traitement des événements pour utiliser le modèle faible)

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

            ...

        }

        ...
    }

Autres conseils

En cas d'arrêt de l'application, vous ne devez rien faire pour éliminer correctement WindowsFormsHost. Comme il dérive de HwndHost, l'élimination est gérée lorsque le Dispatcher est arrêté. Si vous utilisez Reflector, vous verrez que lorsque HwndHost est initialisé, il crée un WeakEventDispatcherShutdown.

Si vous l'utilisez dans une boîte de dialogue, le mieux que je puisse vous suggérer est de remplacer OnClosed et d'éliminer votre hôte, sinon, HwndHost restera en place jusqu'à ce que Dispatcher soit arrêté.

public partial class Dialog : Window
{
    public Dialog()
    {
        InitializeComponent();
    }

    protected override void OnClosed(EventArgs e)
    {
        if (host != null)
            host.Dispose();

        base.OnClosed(e);
    }
}

Un moyen simple de tester quand dispose d'un appel est de dériver une classe personnalisée de WindowsFormsHost et de jouer avec différentes situations. Mettez un point d'arrêt à disposition et voyez quand il sera appelé.

public class CustomWindowsFormsHost : WindowsFormsHost
{
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }
}

Il n'est pas nécessaire de disposer des contrôles lors de la fermeture d'un formulaire, l'API le fera automatiquement pour vous si le contrôle se trouve dans l'arborescence visuelle du formulaire (en tant qu'enfant du formulaire ou d'un autre contrôle du formulaire)

Les contrôles WPF n'implémentent pas l'interface IDisposable, car ils n'ont rien à disposer (aucun descripteur à nettoyer, aucune mémoire non gérée à libérer). Tout ce que vous avez à faire est de vous assurer que vous n'avez aucune référence aux contrôles et que le GC les nettoiera.

Par conséquent, WPF utilise modèles d'événements faibles pour s'assurer que les contrôles peuvent être ramassés. C’est le modèle que vous devez mettre en œuvre pour assurer le nettoyage, pas identifiable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top