Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

mvvm light - Page navigation through ViewModel using MVVMLight in windows 8

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I understand this is not the exact answer you may be looking for, but this may give you some ideas to explore.

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; }
}

And implement it as follows:

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:

public interface IViewModel : INotifyPropertyChanged, IDisposable
{
    void Initialise(object parameter);
    string ViewTitle { get; }
    void Refresh();
}

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);

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);

}

Hope this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...