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. shell 删除文件过期文件

    删除创建时间大于30天的文件 find /archivelog -ctime + | xargs rm -rf -amin n #查找系统中最后N分钟访问的文件 -atime n #查找系统中最后n* ...

  2. 【转】 oracle 层次查询判断叶子和根节点

    Oracle 9i判断是叶子或根节点,是比较麻烦的一件事情,SQL演示脚本如下: DROP TABLE idb_hierarchical; create TABLE idb_hierarchical ...

  3. 加快Terminal的打开加载速度

    加快Terminal的打开加载速度html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirr ...

  4. Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; ...

  5. log_bin_trust_function_creators

    log_bin_trust_function_creators错误解决 当有mysql本地或远程建立function或procedure时报上面的错误 或者如果开启了二进制日志,但是用户没有suppe ...

  6. js 空数组是true还是false

    var arr = new Array(); // 或 var arr = []; 我们知道,初始化后,即使数组arr中没有元素,也是一个object. typeof arr; // "ob ...

  7. git基本操作:上传代码

    利用git将本地代码提交到远程服务器一般分为如下5个步骤: 一.查看当前文件的状态 使用git status命令可以查看有那些文件进行了修改,一般有下面几个状态: 1.Untracked: 未跟踪, ...

  8. Sword redis补充

    Redis 键(key) Redis 键命令用于管理 redis 的键. redis任何数据类型都有key --删除key的命令 redis> del key Redis 事务 Redis 事务 ...

  9. Apche Kafka 的生与死 – failover 机制详解

    转自:http://www.cnblogs.com/fxjwind/p/4972244.html Kafka 作为 high throughput 的消息中间件,以其性能,简单和稳定性,成为当前实时流 ...

  10. 自然语言交流系统 phxnet团队 创新实训 项目博客 (六)

    从你进入软件开始,你就建立了和服务器的联系.这是一段和服务器的长连接,直到你退出此软件. 2D文字聊天界面大致实现了文字输入.发送消息.接收消息.你可以通过点击按钮让机器人开启聊天模式或者学习模式.又 ...