首页 > 代码库 > 【WP8】扩展CM的INavigationService方法

【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();        }    }}