【WP8】扩展CM的INavigationService方法

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 = 1; 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 = 0; i < count; i++)
            {
                navigationService.RemoveBackEntry();
            }
        }

        /// <summary>
        /// 退出App
        /// </summary>
        public static void Exit(this INavigationService navigationService)
        {
            if (Environment.OSVersion.Version.Major < 8)
            {
                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方法

时间: 2024-08-28 19:24:36

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

HTML扩展类的所有方法都有2个参数:

——摘自Rocky Ren 以textbox为例子 public static string TextBox( this HtmlHelper htmlHelper, string name, Object value, IDictionary<string, Object> htmlAttributes ) public static string TextBox( this HtmlHelper htmlHelper, string name, Object value, Object h

Thinkphp编辑器扩展类kindeditor使用方法

一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp网站项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们复制到你的网站项目的ThinkPHP\Lib\ORG\Net 文件夹下. 2,editor文件夹是kindeditor的核心包.将其复制到你项目的Public文件夹下(和入口文件同级的那个Public),并在Public下再建立一个Upload文件夹,用于存放使用编辑器上传的图片. 3,KeditorAction.clas

linux系统下php安装mbstring扩展的二种方法

.执行 复制代码代码如下: yum install php-mbstring 2. 修改php.ini (这一步非常重要, 部分lxadmin版本无法自动修改) 复制代码代码如下: echo ‘extension=mbstring.so' >>/etc/php.ini #更具php安装目录而定 3. 重启web service 如果是apache: service httpd restart 方法二:php 5.36安装目录:/usr/local/php 复制代码代码如下: #cd /usr/

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

PHP socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 使用这些函数时请注意,虽然他们中有很多和C函数同名的,但声明却很可能不同.未避免混淆,请仔细阅读函数描述. 不熟悉socket编程的可以在Unix手册上找到很多有用的信息,网上也有很多C socket编程方面的教程,简单修改一下就可以应用于PHP socket编程. 第一步:开启socket 到php.ini开启extension=php_socke

关系型数据库横向扩展的三种方法

本文是 Oracle Coherence 3.5一书,第一章: Achieving Performance, Scalability, and Availability Objectives,第二节:Achieving scalability中,数据库横向扩展部分的读书笔记. 传统的关系型数据库很难扩展,通常是纵向扩展,但到达一定程度时只能横向扩展. 数据库的横向扩展支持三种方法,即主从复制,集群和分片(sharding). 主从复制 主从复制(Master-slave replication)

MVC扩展之HtmlHelper辅助方法

1.什么是HtmlHelper辅助方法?其实就是HtmlHelper类的扩展方法,如下所示: namespace System.Web.Mvc.Html { public static class FormExtensions//表单相关扩展方法,例如创建表单标签等. public static class InputExtensions//这里包含了所有input,例如:text,button,readiobutton等等. public static class LinkExtensions

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

Scala中implict的一种用法就是扩展现有类的方法,有点类似于.Net中的扩展方法(MS对扩展方法的介绍:扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.) Scala中有两种方式做到方法的扩展,以扩展String为列: 第一种(code:10-12,29):创建一个以implict修饰的新类并以String类型入参.在新的类型(代码中是mystring)中添加要扩展的方法(read2) 第二种(code:3-5,9,28): 创建一个以i

php安装扩展的几种方法

转自:http://doc3.workerman.net/appendices/install-extension.html 安装扩展 注意 与Apache+PHP或者Nginx+PHP的运行模式不同,WorkerMan是基于PHP命令行 PHP CLI 运行的,使用的是不同的PHP可执行程序,使用的php.ini文件也可能不同.所以在网页中打印phpinfo()看到安装了某个扩展,不代表命令行的PHP CLI也安装了对应的扩展. 如何确定PHP CLI安装了哪些扩展 运行 php -m 会列出

【WP8】扩展CM的WindowManager

关于WindowManager,一直都很想写一篇博客分享一下,一直在忙别的,今天抽空把这个分享一下 在弹窗在移动开发是一个很常见的交互,很多时候我们都需要进行弹窗,比如我们需要询问用户的一些操作,提供更丰富的交互,又比如我们需要弹出一个框提示用户给我们好评 WP系统提供关于对话框的操作只有一个MessageBox,MessageBox样式简单,并且无法扩展,比如我们需要自定义按钮的文字都不可以,极大限制了我们的发挥,如果我们需要弹窗,还有Popup控件可以用,比如Coding4fun就对Popu