Навигация по странице через ViewModel с помощью MVVMLight в windows 8


Я только начал разрабатывать свое новое приложение для windows 8 на прошлой неделе, используя MVVM light.Я знаком с навигацией mvvmlight WP7. Как я могу добиться того же в windows 8. Может ли кто-нибудь предложить лучший метод для достижения того же самого в windows 8. Я нашел решение, где мы переопределяем onnavigated события в vm и обрабатываем переход на другую страницу. Но я думаю, что этот метод устарел. Любой, пожалуйста, направьте меня с надлежащей реализацией. Заранее спасибо.

3 10

3 ответа:

Я понимаю, что это не тот точный ответ, который вы ищете, но это может дать вам некоторые идеи для изучения.

В моем случае я использую не MVVMLight,а свою собственную простую реализацию MVVM. Я использую класс BindableBase (который поставляется с шаблонами по умолчанию VS 2012 RC) для уведомлений о свойствах. Я думаю, вы могли бы использовать MVVMLight, чтобы дать вам некоторую инфраструктуру, которую вы можете дополнить чем-то вроде приведенного ниже.

Для навигации я определяю интерфейс, который выглядит так:

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:

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

Наконец, на странице XAML определите элемент Frame:

<Frame x:Name="ContentFrame" />

И в коде-позади страницы: (это в единственной уродливой части на мой взгляд - но, надеюсь, не слишком плохой):

var _navigationService = new NavigationService(this.ContentFrame);

Теперь вы можете передать _navigationService в viewmodel. В моем случае я создаю viewmodel в коде позади страницы:

public HomePage()
{
    this.InitializeComponent();

    var _navigationService = NavigationService.GetFor(this.ContentFrame);

    DataContext = new HomePageViewModel(_navigationService);

}

Надеюсь, это поможет.

Прочитайте статью, опубликованную в журнале MSDN совсем недавно самим Лораном Бугнионом о работе с инструментарием MVVM Light Toolkit и Windows 8.

Ближе к концу статьи он объясняет, как именно настроить NavigationService, который вам нужен.

Http://msdn.microsoft.com/en-us/magazine/jj651572.aspx

Служба навигации, которая была в MVVMLight, была перенесена в новый пакет WinRTBehaviors. Вы также можете получить EventToCommand в Win8nl, как из nuget. Смотрите мой блог, размещенный здесь:

Начало работы w / MVVM Light для Windows 8, EventToCommand и поведения http://blog.tattoocoder.com/2012/08/getting-started-w-windows-8-mvvm-light.html