背景
对于MVVM 架构的WP程序,一个很关键的问题就是导航,以及导航传参。有过经验的人很清楚WP导航只能在View中进行,并且导航参数也只能在NavigatedTo等View的事件中获取,如此我们便不得不在xaml.cs文件中加上处理,以获取导航参数然后再通过导航参数构造ViewModel。这个过程很痛苦,因为我们不得不再两个文件中来回切换来看我们的逻辑代码。
那么接下来我们看下CM作者的厉害之处(必须承认,真的很厉害),
让我们看下CM框架中导航是什么样子的:
不带参数的情况下:
在ViewModel中定义以下函数:
这两行涵盖的很多的信息,我们首先看下初次看到这几行时会存在的疑问:
1、navigatoinService是什么?
这个成员是如此定义的:
通过代码我们不难看出,这里通过依赖注入,MainPageViewModel会得到INavigationService接口类型的对象事例(CM采用容器进行对象的获取,上文提到我们在Bootstrapper里面定义了一个Container,此处不做展开,读者清楚通过此方式得到实例即可)。
2、UriFor是做什么的?
CM的页面导航是基于ViewModel的导航,自处我们调用UriFor<ActionPractisePageViewModel>,那么调用了UriFor之后,CM内部会自动定位到工程中定义的ActionPractisePage.xaml中(注意:此处定位基于命名协定,命名规则需匹配APage.xaml->APageViewModel)并自动构建出导航的Uri。
3、Navigate?
这个函数是导航执行的操作,找到ActionPractisePage.xaml后,便可导航到此页面,并且CM会根据命名协定通过Container再次得到ActionPractisePageViewModel,并将ViewModel自动Binding到View上。
4、其他呢?
事实上很神奇的一件事情就是,我们甚至可以删除ActionPractisePage.xaml.cs,因为CM内的导航执行后会自动调用ActionPractisePage的InitializeComponent()完成页面的构造工作。如此我们的工程目录看起来使这个样子:-)
5、难道只需要这一行代码么?
前面提到导航后会通过Container得到viewModel的一个事例,因此我们需要在Bootstrapper内配置ActionPractisePageViewModel:
看起来很不错,通过CM提供的导航我们可以在ViewModel中基于ViewModel进行定位并且导航。调用十分简洁,流畅接口让调用也十分容易,不易出错。