MVVMLight是MVVM开发模式在Windows Phone平台下的一个开发框架,关于MVVMLight的基础使用,已经有人写的很好了,可以参照:MVVM、MVVMLight、MVVMLight 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]