65.9K
CodeProject 正在变化。 阅读更多。
Home

Codon 入门 - 第 4 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (4投票s)

2017 年 4 月 4 日

CPOL

4分钟阅读

viewsIcon

11117

使用 Codon 的导航服务在页面之间导航。

Codon是一个零依赖的跨平台MVVM框架,用于创建基于UWP、WPF和Xamarin的应用程序。它提供了您快速创建复杂且可维护的应用程序所需的大部分功能。

引言

上一篇文章中,您学习了如何使用 Messenger 类启用应用程序组件之间的通信。在本文中,您将学习如何结合使用路由服务和导航服务来启用页面导航。

本文中提供的代码位于Samples 存储库中的 Sample001 中

页面导航 API 在不同平台之间存在显著差异。某些平台(如 UWP)允许您通过页面的 Type 进行导航。在 WPF 中,您导航到 Page 实例。而其他平台则使用完全不同的方案,例如 Android 及其 Intents 的使用。

为了缓解这些差异,Codon 采用了一个路由系统,允许您将一个字符串 URL 注册到一个关联的 Action。当导航服务收到导航到特定 URL 的请求时,将调用与该 URL 关联的 Action。

注意: URL 实际上可以是任何字符串,它仅作为查找关联 Action 的键。

理解路由服务

Codon 不需要引导。各种默认的 IoC 容器注册会自动执行。但是,如果您打算将 Codon 的导航服务用于除后退导航之外的任何其他用途,则需要配置其路由。

在示例中,您可以在每个平台项目中找到一个名为 Bootstrapper 的类。它的唯一目的是配置路由服务。

每个 Bootstrapper 类都包含一个 Run 方法,该方法在应用程序启动时调用。UWP 示例项目中的 Bootstrapper 从 IoC 容器中检索 IRoutingService,并将 URL“/Page2”(包含在 Routes 类中)与调用 BootstrapperNavigate 方法的 Action 关联起来。参见清单 1。

清单 1. UWP 示例 Bootstrapper 类。

public void Run()
{
	/* This method should be called when your app starts. 
	 * The IoC container knows about several default types, 
	 * that's why no type registrations are necessary. */
	var routingService = Dependency.Resolve<iroutingservice>();

	/* When the navigation service receives a request for "/Page2", 
	 * it uses the routing service to look up the path 
	 * and calls Navigate<page2>(). */
	routingService.RegisterPath(Routes.Page2, Navigate<page2>);
}

泛型 Navigate 方法调用非泛型导航方法,该方法从 Window 中检索 Frame 对象,并使用页面 Type 作为参数调用其 Navigate 方法。参见清单 2。

注意: 您不必像这样设置 Bootstrapper。它只是一个指南。请记住,路由服务接受一个 Action,因此您可以灵活地做任何您想做的事情。

清单 2. UWP Bootstrapper 导航方法

void Navigate<tpage>()
{
	Navigate(typeof(TPage));
}

void Navigate(Type pageType)
{
	/* Navigation in UWP is achieved using the root Frame. */
	var frame = (Frame)Window.Current.Content;
	frame.Navigate(pageType);
}

WPF 的示例 Bootstrapper 与 UWP Bootstrapper 非常相似,除了它的 Navigate 方法。参见清单 3。

Codon INavigationService 的 WPF 实现包含一个便捷的辅助方法,该方法从当前 FrameWindow 中查找内置的 System.Navigation.NavigationService。由于我们知道 Bootstrapper 在 WPF 上运行,我们可以安全地将 INavigationService 转换为其具体实现 NavigationService

WPF Bootstrapper 使用 Dependency 类来构建新页面,然后将其传递给内置的 NavigationService 对象。

清单 3. WPF 示例 Bootstrapper 导航方法

void Navigate(Type pageType)
{
	var navigationService = (NavigationService)Dependency.Resolve<inavigationservice>();
	var page = Dependency.ResolveWithType(pageType);

	/* The platform specific implementation of INavigationService 
	 * has a Navigate(object) method that we can use navigate. 
	 * It automatically resolves the root Frame or NavigationPage. */
	navigationService.Navigate(page);
}

示例 Android 应用中的 Bootstrapper 类与其他平台的工作方式基本相同。然而,主要区别在于它使用了 Android IntentsBootstrapper 类的 Run 方法检索 IRoutingService 实例,并将一个Page 2 路由注册到一个与调用 LaunchActivity 方法关联的项,如下所示

routingService.RegisterPath(Routes.Page2, () => LaunchActivity<page2activity>(1));

在 Xamarin Android 中导航需要一个 ActivityContext 对象。由于没有当前 Activity 的全局句柄,Codon 要求当一个 Activity 变为活动状态时,它需要注册到 IoC 容器。

Android 示例 Bootstrapper 的非泛型 LaunchActivity 方法从 IoC 容器中检索当前的 Activity。参见清单 4。然后它为新的 activity 创建一个 Intent。新 activity 使用 Intent 对象和一个请求代码启动。关于请求代码将在后续文章中详细介绍。

清单 4. Android 示例 Bootstrapper LaunchActivity 方法

void LaunchActivity<tactivity>(int requestCode)
{
	LaunchActivity(typeof(TActivity), requestCode);
}

void LaunchActivity(Type activityType, int requestCode)
{
	var activity = Dependency.Resolve<activity>();
			
	/* Launch an intent for the activity. */
	Intent intent = new Intent(activity, activityType);
	activity.StartActivityForResult(intent, requestCode);
}

回到 Page1ViewModel,您可以看到名为 NavigateToPage2CommandActionCommand 调用了 ViewModel 的 NavigateToPage2 方法,如下所示

ActionCommand navigateToPage2Command;

public ICommand NavigateToPage2Command => navigateToPage2Command
	?? (navigateToPage2Command = new ActionCommand(NavigateToPage2));

NavigateToPage2 方法使用导航服务导航到 Routes.Page2 (“/Page2”) 中定义的 URL。参见清单 5。然后,导航服务询问路由服务是否注册了与 URL “/Page2” 关联的路由,由于存在,它将调用与 URL 关联的 Action;导航到第二页。

清单 5. Page1ViewModel NavigateToPage2 方法

void NavigateToPage2(object arg)
{
	navigationService.Navigate(Routes.Page2);
}

总结一下:使用 IRoutingService 将 URL 与执行实际导航的 Actions 关联起来。使用 INavigationService 导航到 URL。

通过 ViewModel 命令后退导航

每个平台 Page1 视图上都有一个按钮,该按钮绑定到 NavigateToPage2Command。激活按钮时,UWP/WPF/Android 应用会导航到 Page 2。在 Page 2 上,有一个按钮绑定到 Page2ViewModel 类的 NavigateBackCommand。当命令执行时,INavigationService 被调用以执行后退导航,如下所示

void NavigateBack(object arg)
{
	navigationService.GoBack();
}

INavigationService 的每个平台特定实现都知道如何为特定平台执行后退导航。

结论

在本文中,您将学习如何结合使用路由服务和导航服务来启用页面导航。

我希望这个项目对您有用。如果觉得有用,请评分和/或在下方留言。

历史

2017年4月2日

  • 首次发布
© . All rights reserved.