上周我刚开始使用 mvvm light 开发我全新的 windows 8 应用程序.我熟悉 mvvmlight WP7 导航.我如何在 Windows 8 中实现相同的功能.任何人都可以建议一种更好的方法在 Windows 8 中实现相同功能.我找到了一个解决方案,我们在 vm 中覆盖 onnavigated 事件并处理导航到其他页面.但我认为这种方法已经过时了.任何人请指导我正确实施.提前致谢.
I just started developing my brand new windows 8 application last week using mvvm light.I am familiar with mvvmlight WP7 navigation. How i can achieve the same in windows 8. Can any one suggest a better method to achieve the same in windows 8. I found a solution, where we override onnavigated events in vm and handle navigate to other page. But i think that method is obsolete. Any one please guide me with the proper implementation. Thanks in advance.
我知道这不是您可能正在寻找的确切答案,但这可能会给您一些探索的想法.
I understand this is not the exact answer you may be looking for, but this may give you some ideas to explore.
就我而言,我没有使用 MVVMLight - 而是我自己的简单 MVVM 实现.我使用 BindableBase
类(带有默认的 VS 2012 RC 模板)进行属性通知.我想,您可以使用 MVVMLight 为您提供一些基础架构,您可以使用以下内容进行补充.
In my case, I'm not using MVVMLight - but my own simple MVVM implementation. I use the BindableBase
class (which comes with the default VS 2012 RC templates) for property notifications. I imagine, you could use MVVMLight to give you some of the infrastructure, which you can complement with something like the below.
对于导航,我定义了一个如下所示的界面:
For navigation, I define an interface that looks like:
public interface INavigationService
{
void Navigate(Type type);
void Navigate(Type type, object parameter);
void EnsureNavigated(Type pageType, object parameter);
bool CanGoBack { get; }
bool CanGoForward { get; }
void GoBack();
void GoForward();
IView CurrentView { get; }
}
并实现如下:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
public class NavigationService : INavigationService
{
private readonly Frame _frame;
public NavigationService(Frame frame)
{
_frame = frame;
_frame.Navigated += OnFrameNavigated;
}
private void OnFrameNavigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
var view = e.Content as IView;
if (view == null)
return;
var navMsg = new NavigationMessage()
{
Sender = this,
NewView = view,
Parameter = e.Parameter,
NavigationMode = (int)e.NavigationMode
};
EventManager.Current.Publish(navMsg);
//Anything that the parent needs to be notified should happen in of after this method
var viewModel = view.ViewModel;
if (viewModel != null)
viewModel.Initialise(e.Parameter);
}
public void Navigate(Type pageType)
{
DisposePreviousView();
_frame.Navigate(pageType);
}
public void Navigate(Type pageType, object parameter)
{
DisposePreviousView();
_frame.Navigate(pageType, parameter);
}
private void DisposePreviousView()
{
var currentView = this.CurrentView;
var currentViewDisposable = currentView as IDisposable;
if (currentViewDisposable != null)
{
currentViewDisposable.Dispose();
currentViewDisposable = null;
} //view model is disposed in the view implementation
}
public void EnsureNavigated(Type pageType, object parameter)
{
var currentView = this.CurrentView;
if (currentView == null || currentView.GetType() != pageType)
{
Navigate(pageType, parameter);
}
}
public IView CurrentView
{
get { return _frame.Content as IView; }
}
public bool CanGoBack
{
get { return _frame != null && _frame.CanGoBack; }
}
public void GoBack()
{
// Use the navigation frame to return to the previous page
if (_frame != null && _frame.CanGoBack) _frame.GoBack();
}
public bool CanGoForward
{
get { return _frame != null && _frame.CanGoForward; }
}
public void GoForward()
{
// Use the navigation frame to return to the previous page
if (_frame != null && _frame.CanGoForward) _frame.GoForward();
}
}
IView:
public interface IView : IDisposable
{
IViewModel ViewModel { get; }
void Refresh();
}
IViewModel:
IViewModel:
public interface IViewModel : INotifyPropertyChanged, IDisposable
{
void Initialise(object parameter);
string ViewTitle { get; }
void Refresh();
}
最后,在 XAML 页面中,定义一个 Frame
元素:
Finally, in the XAML page, define a Frame
element:
<Frame x:Name="ContentFrame" />
在页面的代码隐藏中:(这是我认为唯一丑陋的部分 - 但希望不会太糟糕):
And in the code-behind of the page: (this in the only ugly part in my opinion - but its hopefully not too bad):
var _navigationService = new NavigationService(this.ContentFrame);
您现在可以将 _navigationService
传递给视图模型.就我而言,我在页面的代码隐藏中创建视图模型:
You can now pass the _navigationService
to the viewmodel. In my case I create the viewmodel in the code-behind of the page:
public HomePage()
{
this.InitializeComponent();
var _navigationService = NavigationService.GetFor(this.ContentFrame);
DataContext = new HomePageViewModel(_navigationService);
}
希望这会有所帮助.