Когда я могу использовать одноразовый элемент управления WPF, например WindowsFormsHost? - PullRequest
12 голосов
/ 31 октября 2008

Элемент управления WPF WindowsFormsHost наследует от IDisposable.

Если у меня сложное визуальное дерево WPF, содержащее некоторые из приведенных выше элементов управления, какое событие или метод я могу использовать для вызова IDispose во время завершения работы?

Ответы [ 4 ]

8 голосов
/ 03 ноября 2008

В случае закрытия приложения вам ничего не нужно делать, чтобы правильно утилизировать WindowsFormsHost. Так как это происходит из HwndHost, утилизация обрабатывается, когда Диспетчер выключен. Если вы используете Reflector, вы увидите, что при инициализации HwndHost создается WeakEventDispatcherShutdown.

Если вы используете его в диалоге, лучшее, что я могу предложить, - это переопределить OnClosed и утилизировать ваш хост, в противном случае HwndHost будет зависать до тех пор, пока Dispatcher не будет остановлен.

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

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

        base.OnClosed(e);
    }
}

Простой способ проверить, когда вызывается утилита dispose, - это извлечь собственный класс из WindowsFormsHost и поэкспериментировать с различными ситуациями. Поместите точку останова в утилизацию и посмотрите, когда она будет вызвана.

public class CustomWindowsFormsHost : WindowsFormsHost
{
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
    }
}
4 голосов
/ 03 ноября 2008

Построение по ответу Тодда. Я придумал это общее решение для любого элемента управления WPF, размещенного в Window, и хочу гарантировать удаление при закрытии этого окна.

(Очевидно, если вы можете избежать наследования от IDisposable do, но иногда вы просто не можете)

Удаление вызывается, когда первое родительское окно в иерархии закрыто.

(Возможное улучшение - измените обработку событий, чтобы использовать слабый шаблон)

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

            ...

        }

        ...
    }
0 голосов
/ 04 ноября 2008

Элементы управления WPF не реализуют интерфейс IDisposable, поскольку им нечего утилизировать (нет ручек для очистки, нет неуправляемой памяти для освобождения). Все, что вам нужно сделать, это убедиться, что у вас нет ссылок на элементы управления, и GC их очистит.

Поэтому WPF использует шаблоны слабых событий , чтобы гарантировать, что элементы управления могут быть удалены. Это шаблон, который необходимо реализовать для обеспечения очистки, а не IDisposable.

0 голосов
/ 01 ноября 2008

Вам не нужно располагать элементы управления при закрытии формы, API сделает это за вас автоматически, если элемент управления находится в визуальном дереве формы (как дочерний элемент формы или другой элемент управления в форме)

...