MVVMLight Toolkit在Windows Phone中的使用扩展之一:在ViewModel中实现导航,并传递参数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/coaxhappy/article/details/9419443

MVVMLight是MVVM开发模式在Windows Phone平台下的一个开发框架,关于MVVMLight的基础使用,已经有人写的很好了,可以参照:MVVM、MVVMLightMVVMLight Toolkit之我见 - 陈希章 - 博客园

但是有些业务逻辑写在Code-Behind里面是不合适的,而通过在ViewModel中实现导航,实现OnNavigated、OnBackPress事件则是一个比较好的方法,参照Prism框架的实现方式,我做了一个MvvmLight的一个Extension。

该DLL可在http://download.csdn.net/detail/coaxhappy/5800445下载,并可任意反编译。

简要介绍如下:

1、先看类库的结构图

     

    INavigateService.cs 是一个导航的接口类,定义了一系列导航的接口。

    NavigateService是对INavigateService的实现。

    NavigationParamsEventArgs继承了EventArgs,来实现导航时的参数传递

    NavigationUri封装了一个导航时的Uri对象,来实现在导航时可以传递对象,而非仅仅是字符串

    ViewModelBaseExtra是对MvvmLight框架的ViewModelBase的一个扩展,以实现在ViewModel中可以实现OnNaivgated事件、OnBackPress事件等。

    RelayCommandExtra本意是对RelayCommand的一个扩展,来保证在连续触发Command时,Command内的代码会顺序执行,在上一次触发未完成之前,不会进行下一次触发,但是由于异步的原因,这个效果不佳,有什么好的建议请联系我。

2、如何实现在ViewModel中实现导航

    MvvmLight框架是通过SimpleIoc来注册服务来管理服务的,依据这个原理将导航的Service也注册到SimpleIoc中,并传递RootFrame到INavigateService中,在NavigateService中对导航事件进行封装来实现导航。

    第一:在ViewModelLocator中注册INavigateService

  SimpleIoc.Default.Register<INavigateService>(() => new NavigateService(App.RootFrame));

    第二:将所有的ViewModel继承自ViewModelBaseExtra ,并实现构造函数

        public SearchOrdersViewModel(INavigateService navigateService)
            : base(navigateService)
        {
            this.navigationService = navigateService;
        }

    第三:在App.xaml.cs中注册View和ViewModel的对应关系

        private void InitializePhoneApplication()
        {
            if (phoneApplicationInitialized)
                return;

            // Create the frame but don't set it as RootVisual yet; this allows the splash
            // screen to remain active until the application is ready to render.
            RootFrame = new PhoneApplicationFrame();

            //RootFrame.Background = new SolidColorBrush(Colors.White);

            RootFrame.Navigated += CompleteInitializePhoneApplication;

            DispatcherHelper.Initialize();

            // Handle navigation failures
            RootFrame.NavigationFailed += RootFrame_NavigationFailed;

            // Handle reset requests for clearing the backstack
            RootFrame.Navigated += CheckForResetNavigation;

            // Ensure we don't initialize again
            phoneApplicationInitialized = true;

            //注册View和ViewModel的对应关系
            RegisterViewViewModel();
        }
        private void RegisterViewViewModel()
        {
            INavigateService navigateService = ServiceLocator.Current.GetInstance<INavigateService>();

            navigateService.Register<MainView, MainViewModel>();
            navigateService.Register<LoginView, LoginViewModel>();
            navigateService.Register<UserCenterView, UserCenterViewModel>();
            navigateService.Register<UpdatePasswordView, UpdatePasswordViewModel>();
            navigateService.Register<OrderCenterView, OrderCenterViewModel>();
            navigateService.Register<OrderDetailView, OrderDetailViewModel>();
            navigateService.Register<MessageSettingView, MessageSettingViewModel>();           
        }

    第四、在ViewModel中重写OnNavigated函数、或者OnBackPress函数

        protected override void OnNavigated(object sender, NavigationParamsEventArgs e)
        {
            base.OnNavigated(sender, e);
        }
        protected override void OnBackPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            base.OnBackPress(sender, e);
        }

    第五、通过navigationService的依赖注入实现导航

        private INavigateService navigationService;
        public MyNotesViewModel(INavigateService navigationService)
            : base(navigationService)
        {
            this.navigationService = navigationService;
        }
            NavigationUri uri = new NavigationUri(ConstValues.NAVIGATION_PAGE_URI_ORDERDETAILVIEW);
            uri.AddParameter<string, string>(ConstValues.NAVIGATION_KEY_ORDER_ID, orderId);
            navigationService.Navigate(uri);

    第六、在OnNavigated事件中接收参数

        protected override void OnNavigated(object sender, NavigationParamsEventArgs e)
        {
            if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New)
            {
                string orderId = e.GetParamater<string, string>(ConstValues.NAVIGATION_KEY_ORDER_ID);
            }
        }
有任何好的建议或意见请联系我
邮箱:[email protected]

猜你喜欢

转载自blog.csdn.net/coaxhappy/article/details/9419443