CM支持通过ViewModel进行导航,并通过支持参数传递,但是内部只是通过反射的方式构造Uri的参数进行导航,所以只支持简单类型的参数传递,下面对其进行扩展,在页面导航时支持复杂类型的参数传递,并扩展了部分方法,比如,导航后删除上一个页面,清空导航,清空跳转等,详细的看代码

// *************************************************
//
// 作者:bomo
// 小组:WP开发组
// 创建日期:2014/5/22 23:03:26
// 版本号:V1.00
// 说明: 扩展 CM2.0 的INavigationService
//
// *************************************************
//
// 修改历史:
// Date WhoChanges Made
// 2014/5/22 23:03:26 bomo Initial creation
//
// ************************************************* using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Navigation;
using Caliburn.Micro; namespace XTuOne.Utility.Helpers
{
/// <summary>
/// INavigationService的扩展方法
/// </summary>
public static class NavigationExtensions
{
/// <summary>
/// 返回到第一个导航页面
/// </summary>
public static void BackToMainView(this INavigationService navigationService)
{
var count = navigationService.BackStack.Count();
for (int i = ; i < count; i++)
{
var entry = navigationService.RemoveBackEntry();
}
navigationService.GoBack();
} /// <summary>
/// 返回到匹配的导航页面(true:存在且返回成功,false:不存在不操作)
/// </summary>
public static bool Back2View(this INavigationService navigationService, string pageUri)
{
if (navigationService.ContainsView(pageUri))
{
var list = navigationService.BackStack.ToList(); foreach (var journalEntry in list)
{
if (!journalEntry.Source.OriginalString.Contains(pageUri))
{
var entry = navigationService.RemoveBackEntry();
}
else
{
break;
}
}
navigationService.GoBack();
return true;
}
return false;
} /// <summary>
/// 导航后删除上一个导航
/// </summary>
public static void NavAndRemoveBack<TViewModel>(this INavigationService navigationService) where TViewModel:class
{
navigationService.Navigate<TViewModel>(vm => navigationService.RemoveBackEntry());
} /// <summary>
/// 根据ViewModel类型跳转到指定页面(清空导航历史)
/// </summary>
public static void GoToView<T>(this INavigationService navigationService)
{
navigationService.UriFor<T>().Navigate();
ClearHistory(navigationService);
} /// <summary>
/// 判断导航历史是否存在ViewModel对应的View
/// </summary>
public static bool ContainsView<TViewModel>(this INavigationService navigationService)
{
return
navigationService.BackStack.Any(bs => bs.Source.OriginalString.Contains(GetViewUriString<TViewModel>()));
} /// <summary>
/// 判断导航历史是否存在Page
/// </summary>
public static bool ContainsView(this INavigationService navigationService, string pageUri)
{
return navigationService.BackStack.Any(bs=>bs.Source.OriginalString.Contains(pageUri));
} /// <summary>
/// 清空导航历史
/// </summary>
private static void ClearHistory(INavigationService navigationService)
{
var count = navigationService.BackStack.Count();
for (int i = ; i < count; i++)
{
navigationService.RemoveBackEntry();
}
} /// <summary>
/// 退出App
/// </summary>
public static void Exit(this INavigationService navigationService)
{
if (Environment.OSVersion.Version.Major < )
{
var asmb = Assembly.Load("Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553");
var type = asmb.GetType("Microsoft.Xna.Framework.Game");
var constructorInfo = type.GetConstructor(new Type[] {});
if (constructorInfo != null)
{
var obj = constructorInfo.Invoke(new object[] {});
type.GetMethod("Exit").Invoke(obj, new object[] {});
}
}
else
{
var type = Application.Current.GetType();
type.GetMethod("Terminate").Invoke(Application.Current, new object[] {});
}
} /// <summary>
/// 通过ViewModel获取View的字符串
/// </summary>
public static string GetViewUriString<TViewModel>()
{
var viewType = ViewLocator.LocateTypeForModelType(typeof (TViewModel), null, null);
if (viewType == null)
{
throw new InvalidOperationException(
string.Format("No view was found for {0}. See the log for searched views.",
typeof (TViewModel).FullName));
}
return ViewLocator.DeterminePackUriFromType(typeof (TViewModel), viewType);
} /// <summary>
/// 扩展INavigationService,让导航支持复杂对象赋值
/// </summary>
public static void Navigate<TViewModel>(this INavigationService navigationService, Action<TViewModel> action) where TViewModel : class
{
var uri = GetViewUriString<TViewModel>();
NavigatedEventHandler navigationServerOnNavigated = null;
navigationServerOnNavigated = (s, e) =>
{
var viewModel = ViewModelLocator.LocateForView(e.Content) as TViewModel;
if (viewModel != null)
{
action(viewModel);
}
navigationService.Navigated -= navigationServerOnNavigated;
}; navigationService.Navigated += navigationServerOnNavigated;
navigationService.Navigate(new Uri(uri, UriKind.Relative));
} /// <summary>
/// 扩展UriBuilder,让导航支持复杂对象赋值
/// </summary>
public static void Navigate<TViewModel>(this UriBuilder<TViewModel> uriBuilder, Action<TViewModel> action) where TViewModel :class
{
var navigationService = IoC.Get<INavigationService>();
NavigatedEventHandler navigationServerOnNavigated = null;
navigationServerOnNavigated= (s, e) =>
{
var viewModel = ViewModelLocator.LocateForView(e.Content) as TViewModel;
if (viewModel != null)
{
action(viewModel);
}
navigationService.Navigated -= navigationServerOnNavigated;
}; navigationService.Navigated += navigationServerOnNavigated; uriBuilder.Navigate();
}
}
}

【WP8】扩展CM的INavigationService方法的更多相关文章

  1. ORA-01652:无法通过128(在表空间temp中)扩展temp段 解决方法

    ORA-01652:无法通过128(在表空间temp中)扩展temp段 解决方法 (2016-10-21 16:49:53)   今天在做一个查询的时候,报了一个"ORA-01652无法通过 ...

  2. Easyui扩展或者重载(方法和属性)

    1: 使用$.fn.datagrid.defaults.editors重载默认值. 每个编辑器都有以下方法: 名称 属性 描述 init container, options 初始化编辑器并返回目标对 ...

  3. php安装扩展的几种方法

    转自:http://doc3.workerman.net/appendices/install-extension.html 安装扩展 注意 与Apache+PHP或者Nginx+PHP的运行模式不同 ...

  4. Scala中使用implict 扩展现有类的方法

    Scala中implict的一种用法就是扩展现有类的方法,有点类似于.Net中的扩展方法(MS对扩展方法的介绍:扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改 ...

  5. Python扩展之类的魔术方法

    Python中类的魔术方法 在Python中以两个下划线开头的方法,__init__.__str__.__doc__.__new__等,被称为"魔术方法"(Magic method ...

  6. PHP Socket(套接字连接)扩展简介和使用方法

    PHP socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 使用这些函数时请注意,虽然他们中有很多和C函数同名的 ...

  7. UWP 扩展/自定义标题栏的方法,一些概念和一些注意事项

    原文 UWP 扩展/自定义标题栏的方法,一些概念和一些注意事项 在 Windows 10 的前几个版本中将页面内容扩展到标题栏上还算简单,主要是没什么坑.直到一些新控件的引入和一些外观设计趋势变化之后 ...

  8. swap分区扩展的三种方法

    redhat linux swap分区扩展的三种方法 2016-12-26 11:41:08 分类: LINUX 原文地址:redhat linux swap分区扩展的三种方法 作者:quanshen ...

  9. 【WP8】扩展CM的WindowManager

    14-09-09更新:修复AppBar冲突bug 关于WindowManager,一直都很想写一篇博客分享一下,一直在忙别的,今天抽空把这个分享一下 在弹窗在移动开发是一个很常见的交互,很多时候我们都 ...

随机推荐

  1. Java并发编程 ReentrantLock 源码分析

    ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...

  2. 依赖注入:Ninject学习笔记

    依赖注入(DI)就不多说了,可以自行百度,本笔记整理自Pro ASP.NET MVC5. 1,Ninject安装 Ninject是一个开源的注入容器,可以通过VS的Nuget进行安装.由于是在mvc中 ...

  3. genymotion 前端调试

    1. genymotion的安装见这里 注: a. 要先装VirtualBox, 再装genymotion b. VirtualBox不能太高,我装的是VirtualBox-4.1.40-101594 ...

  4. org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/ template might not exist or might not be accessible by any of the configured

    异常现象:在本地打包部署完全没有问题,资源文件也都可以映射上,但是打包成jar包部署到服务器上时,就一直报异常,异常信息如下: 严重: Servlet.service() for servlet [d ...

  5. 【Java集合源码剖析】Hashtable源码剖析

    转载出处:http://blog.csdn.net/ns_code/article/details/36191279 Hashtable简介 Hashtable同样是基于哈希表实现的,同样每个元素是一 ...

  6. .NET Framework posters with Namespaces & Types

    Framework is platform containing a huge library of types, methods, classes, etc., cataloged into nam ...

  7. Android 8 AudioPolicy 初始化

    记录一下AudioPolicy初始化过程. frameworks\av\media\audioserver\audioserver.rc service audioserver /system/bin ...

  8. Linux系统中如何校验SHA1和MD5?

    来自:系统之家:http://www.xitongzhijia.net/xtjc/20160316/69125.html 我们在网络上下载或在U盘中复制的文件正常来说和源文件是一样的,但有时在下载或拷 ...

  9. 适合Eclipse Juno的UML插件

    今天给Eclipse安装UML插件,试了很多都不兼容,我用的Ecllipe版本是4.2 最后终于找到一个叫做AmatersUML的插件还能用,不过还是不够顺手,比如对泛型支持不够,不能从图形直接跳到相 ...

  10. Maven创建Java项目

    Maven使用 archetype 来创建项目.要创建一个简单的 Java 应用程序,我们使用 maven-archetype-quickstart 插件.在下面的例子中,我们将创建一个基于Maven ...