代码之家  ›  专栏  ›  技术社区  ›  scottyaim

在使用Prism的viewmodel中,如何从应用程序类执行导航

  •  0
  • scottyaim  · 技术社区  · 7 年前

    我目前正在开发一个应用程序,其中有一个叫做“提示”的功能,基本上就是微博。在这些基于html的博客中,您可以通过普通超链接链接到我们应用程序中存在的其他“内容”。

    该应用程序设置为打开这些链接的url方案,所有平台都有自己的代码,通过MessagingCenter将新uri导入xamarin表单应用程序,MessagingCenter在应用程序类中有一个子用户,如下所示:

     MessagingCenter.Subscribe(Current, DoshiMessages.NewUri, async (Application app, string uri) =>
     {
         var result = await HandleUriNavAsync(uri);
    
         if (!result)
            await Container.Resolve<IUserDialogs>().AlertAsync("Link was invalid");
     });
    

    这要求:

        private async Task<bool> HandleUriNavAsync(string uri)
        {
            if (uri == null)
                return false;
    
            await NavigationService.NavigateAsync(new Uri(uri, UriKind.Absolute));
            return true;
        }
    

    现在这对绝对uri很好,但是如果我将它改为

            //Example: uri = www.example.com/main/nav/test?userid=0
        private async Task<bool> HandleUriNavAsync(string uri)
        {
            if (uri == null)
                return false;
    
            //Example: relative = test?userid=0
            var relative = uri.Split('/').Last();
            await NavigationService.NavigateAsync(new Uri(relative, UriKind.Relative));
            return true;
        }
    

    导航从不触发,但不会引发异常,并且任务成功完成(我已检查)。注意:上面的代码是在应用程序已经运行并且已经有活动的viewmodels时执行的。

    有没有什么明显的我做错了,有没有更好的方法来实现这一点?

    干杯

    0 回复  |  直到 7 年前
        1
  •  0
  •   Leon    7 年前

    我测试了你的代码,得到了如下截图所示的结果,这个问题与uri类型有关。

    你已经设定了目标 UriKind.Absolute ,那么你呢 uri 类型应该是 www.example.com/main/nav/test?userid=0 .

    如果你设定 UriKind.Relative ,拆分uri后,可以设置此类型的uri。

    最后,在VS中没有抛出异常,这是非常有关联的。 enter image description here

        2
  •  0
  •   scottyaim    7 年前

    所以我最终找到了一个很好的解决办法。 这有点粗略,但因为我所有的viewmodels都继承了一个公共基类 我可以在Prism PageUtils的帮助下获得当前的viewmodel

    MessagingCenter.Subscribe(Current, DoshiMessages.NewUri, async (Application app, string uri) =>
    {
        try
        {
            var relative = uri.Split('/').LastOrDefault();
    
            if(relative != null)
            {
                var currentVM = PageUtilities.GetCurrentPage(MainPage).BindingContext as ViewModelBase;
                await currentVM.HandleNewUriAsync(relative);
            }
        }
        catch(Exception ex)
        {
           Crashes.TrackError(ex);
        }
    });
    

    然后在当前viewmodel中执行导航

        public async Task HandleNewUriAsync(string uri)
        {
            await _navigationService.NavigateAsync(new Uri(uri, UriKind.Relative));
        }