导航后未放置ViewModel实例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了导航后未放置ViewModel实例相关的知识,希望对你有一定的参考价值。
UWP应用程序(Prism.Unity NuGetPackage 6.3.0)
当多次导航到同一页面时,会创建其视图模型的新实例,旧的实例将保留在内存中并且不会被丢弃。
这会导致崩溃,因为全局事件会使用事件聚合器多次触发,也会被侦听它的旧ViewModel接收。
我们使用NavigationService来浏览页面。我们的页面和用户控件绑定到XAML中带有prismMvvm:ViewModelLocator.AutoWireViewModel="True"
的视图模型。
我们已经看到了一些关于类似问题的线索,解决方案是使用Regions添加区域行为。但是,据我所知,Prism UWP在当前版本中不支持区域。
我们认为该问题与ViewModelLocator和NavigationService有关,因为使用Container.RegisterType注册viewmodels并使用不同的LifetimeManager无效。
崩溃的样本可以从GitHub下载:App1.zip
演讲嘉宾:
- 执行申请
- 在Test1和Test2之间多次导航
- 点击“RaiseEvent”执行全局事件
- 所有实例都记录其哈希码
- 应用程序应该在某些时候崩溃
答案
这会导致崩溃,因为全局事件会使用事件聚合器多次触发,也会被侦听它的旧ViewModel接收。
当您从一个页面导航到另一个页面时,您可以取消订阅该事件。
例如:
public class Test1PageViewModel : ShellIntegratedViewModel
{
private readonly IEventAggregator _eventAggregator;
private readonly INavigationService _navigationService;
Action action;
public Test1PageViewModel(IEventAggregator eventAggregator, INavigationService navigationService)
: base(eventAggregator)
{
_eventAggregator = eventAggregator;
_navigationService = navigationService;
NavigateCommand = new DelegateCommand(OnNavigateCommand);
action = new Action(()=> {
_eventAggregator.GetEvent<LogEvent>().Publish("Test1 Hashcode: " + this.GetHashCode());
});
_eventAggregator.GetEvent<TestEvent>().Subscribe(action);
}
private void OnNavigateCommand()
{
_eventAggregator.GetEvent<TestEvent>().Unsubscribe(action);
_navigationService.Navigate("Test2", null);
}
public DelegateCommand NavigateCommand { get; private set; }
}
以上是关于导航后未放置ViewModel实例的主要内容,如果未能解决你的问题,请参考以下文章