我如何在使用 Prism 的视图模型中从我的应用程序 class 执行导航
How do i perform navigation from my App class while in a viewmodel with Prism
我目前正在开发一个应用程序,其中我们有一个名为 "tips" 的功能,它本质上是微博。在这些基于 html 的博客中,您可以通过普通的 hyperlinks link 访问我们应用程序中存在的其他 "Content"。
该应用程序设置为打开这些 link 的 url 方案,并且所有平台都有自己的代码,通过 MessagingCenter 将新的 uri 汇集到 xamarin 表单应用程序中,该消息中心具有应用内的订阅者 class 像这样:
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;
}
导航从不触发,但没有抛出异常并且任务成功完成(我已经检查过)。请注意,上面的代码是在应用程序已经 运行 并且已经具有活动视图模型时执行的。
是否有明显的错误,是否有更好的方法来实现这一点?
干杯!
我测试了你的代码,得到的结果如下图所示,这个问题与uri类型有关。
您已设置 UriKind.Absolute
,因此您 uri
类型应为 www.example.com/main/nav/test?userid=0
。
如果设置UriKind.Relative
,拆分uri后,可以设置这种类型的uri。
最后,在VS中没有抛出任何异常,这就是有线。
所以我最终找到了一个非常有效的解决方法。
这有点粗略,但因为我所有的视图模型都继承了一个共同的基础 class
我可以在 Prism PageUtils
的帮助下获取当前视图模型
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);
}
});
然后只在当前视图模型中执行导航
public async Task HandleNewUriAsync(string uri)
{
await _navigationService.NavigateAsync(new Uri(uri, UriKind.Relative));
}
我目前正在开发一个应用程序,其中我们有一个名为 "tips" 的功能,它本质上是微博。在这些基于 html 的博客中,您可以通过普通的 hyperlinks link 访问我们应用程序中存在的其他 "Content"。
该应用程序设置为打开这些 link 的 url 方案,并且所有平台都有自己的代码,通过 MessagingCenter 将新的 uri 汇集到 xamarin 表单应用程序中,该消息中心具有应用内的订阅者 class 像这样:
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;
}
导航从不触发,但没有抛出异常并且任务成功完成(我已经检查过)。请注意,上面的代码是在应用程序已经 运行 并且已经具有活动视图模型时执行的。
是否有明显的错误,是否有更好的方法来实现这一点?
干杯!
我测试了你的代码,得到的结果如下图所示,这个问题与uri类型有关。
您已设置 UriKind.Absolute
,因此您 uri
类型应为 www.example.com/main/nav/test?userid=0
。
如果设置UriKind.Relative
,拆分uri后,可以设置这种类型的uri。
最后,在VS中没有抛出任何异常,这就是有线。
所以我最终找到了一个非常有效的解决方法。 这有点粗略,但因为我所有的视图模型都继承了一个共同的基础 class 我可以在 Prism PageUtils
的帮助下获取当前视图模型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);
}
});
然后只在当前视图模型中执行导航
public async Task HandleNewUriAsync(string uri)
{
await _navigationService.NavigateAsync(new Uri(uri, UriKind.Relative));
}