导航后未放置ViewModel实例

问题描述 投票:0回答:1

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

演讲嘉宾:

  1. 执行申请
  2. 在Test1和Test2之间多次导航
  3. 点击“RaiseEvent”执行全局事件
  4. 所有实例都记录其哈希码
  5. 应用程序应该在某些时候崩溃
c# uwp prism
1个回答
1
投票

这会导致崩溃,因为全局事件会使用事件聚合器多次触发,也会被侦听它的旧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; }
}
© www.soinside.com 2019 - 2024. All rights reserved.