无法使用 Prism 从回调方法内部导航

Posted

技术标签:

【中文标题】无法使用 Prism 从回调方法内部导航【英文标题】:Can't navigate from inside a callback method with Prism 【发布时间】:2013-10-24 19:10:21 【问题描述】:

我有一个使用 WPF 和 Prism 的小型应用程序。我有我的外壳和两个模块。我可以以“正常方式”成功地在它们之间导航(例如通过单击按钮),因此我知道它们已正确连接以进行导航。但是,如果我执行一些在完成时触发事件的异步操作,我将无法从该事件处理程序内部导航。我尝试的最后一件事是使用事件聚合将事件发布回 UI 线程,但它仍然无法导航。事件的订阅者成功获取事件并触发 RequestNavigate(...) 但 UI 没有更新。

现在,一些代码: 我的第一个模块的视图模型LoginModule

public class LoginViewModel : ViewModelBase, ILoginViewModel, INavigationAware

    ...

    [ImportingConstructor]
    public LoginViewModel(IRegionManager regionManager, IUnityContainer container, IEventAggregator eventAggregator)
    
        _regionManager = regionManager;
        _container = container;
        _eventAggregator = eventAggregator;
    

    private DelegateCommand _Login;
    public DelegateCommand Login
    
        get
        
            if (_Login == null)
                _Login = new DelegateCommand(() => LoginHandler());
            return _Login;
        
    
    private void LoginHandler()
    
        _client = new JabberClient();
        _client.Server = "gmail.com";
        _client.User = Username;
        _client.Password = Password;

        ...

        _client.OnAuthenticate += client_OnAuthenticate;
        _client.Connect();
    

    private void client_OnAuthenticate(object sender)
    
        Console.WriteLine("Authenticated!");
        _eventAggregator.GetEvent<UserAuthenticatedEvent>().Publish("");
    

    public bool IsNavigationTarget(NavigationContext navigationContext)
    
        return true;
    
    ...

我的第二个模块的 ViewModel RosterModule:

public class RosterViewModel : IRosterViewModel, INavigationAware

    private readonly IEventAggregator _eventAggregator;
    private readonly IRegionManager _regionManager;

    [ImportingConstructor]
    public RosterViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
    
        _regionManager = regionManager;
        _eventAggregator = eventAggregator;

        _eventAggregator.GetEvent<UserAuthenticatedEvent>().Subscribe(o =>
        
            Console.WriteLine("Requesting navigation...");
            _regionManager.RequestNavigate(RegionNames.ContentRegion, new Uri(WellKnownViewNames.RosterView, UriKind.Relative));
        );
    

    public bool IsNavigationTarget(NavigationContext navigationContext)
    
        return true;
    

    public void OnNavigatedFrom(NavigationContext navigationContext)
    

    

    public void OnNavigatedTo(NavigationContext navigationContext)
    
        Console.WriteLine("I'm here at the RosterViewModel");
    

关于我可能做错的任何提示?

【问题讨论】:

你为什么不把它作为答案? 请将已解决的 cmets 复制到答案中,然后回答。有朝一日,这可能会对其他人有所帮助。 @Jason:请将您的解决方案添加到答案中并将其标记为答案。如果您不将其标记为答案,正在寻找相同问题解决方案的人将不会查看此帖子在列表中显示为未答复。此外,知道解决方案并愿意回答的人在花时间阅读这篇文章后会感到失望。 【参考方案1】:

来自 OP,

好的,所以在发布几分钟后,我重读了一篇我昨天遇到的文章,看到了我错过的东西......

http://neverindoubtnet.blogspot.com/2009/05/event-aggregator-in-prism-explorer.html

他们解释说,Subscribe 方法的重载之一包括一个 ThreadOption。

所以:

_eventAggregator.GetEvent<UserAuthenticatedEvent>()
    .Subscribe(
    o =>
    
        Console.WriteLine("Requesting navigation...");
        _regionManager.RequestNavigate(
            RegionNames.ContentRegion,
            new Uri(WellKnownViewNames.RosterView, UriKind.Relative));
    );

成为:

_eventAggregator.GetEvent<UserAuthenticatedEvent>()
    .Subscribe(
    o =>
    
        Console.WriteLine("Requesting navigation...");
        _regionManager.RequestNavigate(
            RegionNames.ContentRegion,
            new Uri(WellKnownViewNames.RosterView, UriKind.Relative));
    , 
    ThreadOption.UIThread);

现在它可以工作了!

希望这可以帮助其他人。

享受吧!

【讨论】:

以上是关于无法使用 Prism 从回调方法内部导航的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:从 StreamBuilder 构建器回调内部导航到另一个屏幕

棱镜:贝壳之间的导航?

如何在android中的接口回调内部传输数据

在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]

在异步函数内部,从回调函数返回值返回 Promise(undefined) [重复]

如何从 Flutter 中的方法获取 AlertDialog 回调?