Выход из приложения или закрытие элемента управления при использовании MVVM - PullRequest
0 голосов
/ 10 марта 2012

В своем приложении WPF я использую ViewModelLocator без IoC.Я вызываю статический метод ViewModelLocator.Cleanup(), предоставляемый платформой MVVM-Light, из моей собственной кнопки, которая связана с «командой закрытия окна».Эта команда вызывает статический ViewModelLocator.Cleanup(), который вызывает метод Cleanup () экземпляра в моем экземпляре MainWindowViewModel.Затем экземплярный метод Cleanup () устанавливает свойство, с которым MainWindow связывает его DataContext, со значением NULL.Сеттер на объекте вызывает событие PropertyChanged.Любопытно, что установка этого свойства в null не приводит к закрытию окна.

Я пытаюсь понять, почему это так?Если я установлю значение DataContext в MainWindow на null, не должно ли оно быть таким же, как Window.Close()?В моем случае окно и все его элементы остаются на экране.Однако, если я попытаюсь предпринять дальнейшие действия, я получу исключения нулевого указателя, указывая на то, что свойство привязки DataContext действительно установлено в значение null;это также было подтверждено в отладчике.

Я создал обходной путь, перехватив событие Application.Exit и выполнив Window.Close () в обработчике событий, чтобы создать собственную кнопку «Закрыть окно».(т.е. создать ту же функциональность для моей собственной кнопки / команды, что и нажатие кнопки X в правом верхнем углу окна).Поскольку вызов элемента пользовательского интерфейса (т. Е. Экземпляра Window) непосредственно из MVVM не является дружественным к MVVM, я использовал ViewService для реализации функциональности Window.Close (), чтобы обеспечить обходной обход MVVM.Я большой поклонник идиомы ViewService (или шаблона), но я просто не думаю, что это необходимо здесь;кроме того, я мог видеть, что выход из приложения - это особый случай, который, возможно, должен быть связан с жизненным циклом приложения, и .Net, по-видимому, позволяет выходить из приложения WPF только с помощью метода Window.Close ().

Мысли оценены.

1 Ответ

1 голос
/ 11 марта 2012

Мне кажется, я нашел ответ на свой первоначальный вопрос, в дополнение к тому, который был поднят в обсуждении моих комментариев с flq.

Во-первых, ответ на первоначальный вопрос заключается в том, что правильный способ закрыть окно - это то же, что я делал в описанном мной «обходном пути». Закрытие приложения - это процесс, инициируемый View, поскольку именно элемент управления Window имеет биты для того, как это сделать. Конечно, вы можете перехватить событие Application.Exit, чтобы выполнить очистку ваших ViewModels, предложить пользователю сохранить данные и т. Д.

Вопрос, поднятый мной после некоторого интересного обсуждения с flq, заключается в том, что если я просто не установлю DataContext элемента управления (т. Е. ViewModel) в значение null, чтобы освободить ресурсы View и ViewModel, как мне это сделать?

Интересное обсуждение с некоторыми нюансами можно найти здесь , но основной ответ заключается в том, что вы нашли родительский элемент управления и удалили элемент управления, который хотите закрыть, из его списка детей. Обратите внимание, что это другой метод с другой целью, чем просто сделать элемент управления невидимым, установив для свойства Visibility значение Collapsed. В следующем примере «this» - это удаляемый элемент управления (т. Е. «Closed»):

Panel p = (Panel) this.Parent;
p.Children.Remove(this);

Я не уверен, что вам все еще нужно установить потомок (т. Е. «This») в null, чтобы повторно запросить его ресурсы, или, если простое удаление его из визуального дерева, заставит WPF повторно запросить Ресурсы; вышеупомянутое связанное обсуждение не упоминает. Как упомянуто в исходном обсуждении , вышеупомянутая техника может быть дополнена путем привязки ее к определенным событиям или использования другой логики, специфичной для приложения.

...