Как использовать одноразовые модели просмотра в WPF? - PullRequest
12 голосов
/ 08 августа 2011

Как убедиться, что модели представлений должным образом удаляются, если они ссылаются на неуправляемые ресурсы или имеют обработчики событий, такие как обработка по таймеру диспетчера.В первом случае финализатор - это вариант, хотя и не идеальный, но во втором он никогда не будет вызван.Как мы можем узнать, когда к модели представления больше не присоединено представление.

Ответы [ 2 ]

8 голосов
/ 15 ноября 2012

Я сделал это, выполнив следующее:

  1. Удаление свойства StartupUri из App.xaml.
  2. Определение класса моего приложения следующим образом:

    public partial class App : Application
    {
        public App()
        {
            IDisposable disposableViewModel = null;
    
            //Create and show window while storing datacontext
            this.Startup += (sender, args) =>
            {
                MainWindow = new MainWindow();
                disposableViewModel = MainWindow.DataContext as IDisposable;
    
                MainWindow.Show();
            };
    
            //Dispose on unhandled exception
            this.DispatcherUnhandledException += (sender, args) => 
            { 
                if (disposableViewModel != null) disposableViewModel.Dispose(); 
            };
    
            //Dispose on exit
            this.Exit += (sender, args) =>
            { 
                if (disposableViewModel != null) disposableViewModel.Dispose(); 
            };
        }
    }
    
7 голосов
/ 08 августа 2011

Одно возможное, хотя и не идеальное решение:

Реализация ID, доступного для модели представления, затем используйте этот метод расширения в конструкторе представления.

    public static void HandleDisposableViewModel(this FrameworkElement Element)
    {
        Action Dispose = () =>
            {
                var DataContext = Element.DataContext as IDisposable;
                if (DataContext != null)
                {
                    DataContext.Dispose();
                }
            };
        Element.Unloaded += (s, ea) => Dispose();
        Element.Dispatcher.ShutdownStarted += (s, ea) => Dispose();
    }
...