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. Excel中功能清单转Project任务

    接:http://www.cnblogs.com/vipsoft/p/8495220.html 1.在E列输入公式: =IF(LEN(A2)>1,1,IF(LEN(B2)>1,2,IF(L ...

  2. ARKit从入门到精通(2)-ARKit工作原理及流程介绍

    转载:http://blog.csdn.net/u013263917/article/details/73038519 1.1-写在前面的话 1.2-ARKit与SceneKit的关系 1.3-ARK ...

  3. java---简单的ATM存取系统,

    新手练手必备~ 密码账户为: 先创建账户类: package cn.Atm; /** * @author 偶my耶 */ import java.io.*; import com.project.pr ...

  4. Mongodb 的常用方法,在可视化工具执行

    查询: db.getCollection('message').find({"userId":"31257"}) 查询总数: db.getCollection( ...

  5. # Writing your first Django app--part 3 about view

    添加更多的view 写actually有用的view 使用模版来设计view 使用模版设计view的捷径:render() 抛出异常404 抛出异常404-快捷方法: get_object_or_40 ...

  6. 【Java】使用pinyin4j获取汉字的全拼或首字母

    汉字转拼音的工具类,常用于做汉字拼音的模糊查询. https://www.cnblogs.com/htyj/p/7891918.html

  7. C#中的装箱拆箱

    在C#中,经常需要把值类型和引用类型相互转换. 首先明确两条法则: 1.引用类型总是被分配到“堆”上. 2.值类型总是分配到它声明的地方: a.作为引用类型的成员变量分配到“堆”上 b.作为方法的局部 ...

  8. Android View.MeasureSpec

    有时,Android系统控件无法满足我们的需求,因此有必要自定义View. 一般来说,自定义控件都会去重写View的onMeasure方法,因为该方法指定该控件在屏幕上的大小,[protected v ...

  9. CPP_template

    泛型编程是独立于任何特定类型的方式编写代码.模板是泛型编程的基础,模板使程序员能够快速建立具有类型安全的类库集合和函数集合,它的实现,方便了大规模的软件开发. 模板提供通用类型和通用函数,定义中包含t ...

  10. [数据结构]A*寻路算法

    简易地图 如图所示简易地图, 其中绿色方块的是起点 (用 A 表示), 中间蓝色的是障碍物, 红色的方块 (用 B 表示) 是目的地. 为了可以用一个二维数组来表示地图, 我们将地图划分成一个个的小方 ...