Pergunta

Os herda WPF controle WindowsFormsHost de IDisposable.

Se eu tiver uma árvore visual WPF complexo contendo alguns dos controles acima do que evento ou método que pode usar para chamar IDispose durante o encerramento?

Foi útil?

Solução 2

Construção de resposta de Todd Eu vim com essa solução genérica para qualquer controle WPF que está hospedado por uma janela e quer da disposição garantia quando essa janela é fechada.

(Obviamente, se você pode evitar herdando de IDisposable fazer, mas às vezes você simplesmente não pode)

Dispose é chamado quando a janela do primeiro pai na hierarquia está fechada.

(melhoria Possível - mudar a manipulação de eventos para usar o padrão fraco)

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

            ...

        }

        ...
    }

Outras dicas

No caso de desligamento do aplicativo não há nada que você precisa fazer para descartar corretamente o WindowsFormsHost. Uma vez que deriva de HwndHost descarte é tratado quando o Dispatcher é desligamento. Se você usar o refletor você vai ver que quando HwndHost é inicializado ele cria um WeakEventDispatcherShutdown.

Se você estiver usando-lo em uma caixa de diálogo o melhor que posso sugerir é substituir OnClosed e dispor de seu anfitrião, em seguida, caso contrário o HwndHost vai pendurar ao redor até que até que o Dispatcher é desligamento.

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

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

        base.OnClosed(e);
    }
}

Uma maneira simples de teste quando descarte é chamado é derivar uma classe personalizada a partir WindowsFormsHost e brincar com diferentes situações. Coloque um ponto de ruptura em dispor e ver quando ele é chamado.

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

Você não precisa de controles dispose ao fechar um formulário, o API irá fazer isso por você automaticamente se o controle está na árvore visual da forma (como um filho do formulário ou outro controle no formulário)

Controles

WPF não implementar a interface IDisposable, porque nada têm de dispor (Sem alças para limpar, sem memória não gerenciado para liberação). Tudo que você precisa fazer é se certificar de que você não tem quaisquer referências aos controles e ao GC irá limpá-los.

Portanto WPF emprega padrões de eventos fracos para garantir que os controles podem ser lixo coletado. Este é o padrão que você precisa implementar para garantir a limpeza, não IDisposable.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top