【问题标题】:Page navigation through ViewModel using MVVMLight in windows 8在 Windows 8 中使用 MVVMLight 通过 ViewModel 进行页面导航
【发布时间】:2012-06-10 18:01:59
【问题描述】:

上周我刚开始使用 mvvm light 开发我全新的 windows 8 应用程序。我熟悉 mvvmlight WP7 导航。我如何在 Windows 8 中实现相同的功能。任何人都可以建议一种更好的方法在 Windows 8 中实现相同功能。我找到了一个解决方案,我们在 vm 中覆盖 onnavigated 事件并处理导航到其他页面。但我认为这种方法已经过时了。任何人请指导我正确实施。提前致谢。

【问题讨论】:

  • 您能否分享一下您的解决方案,您是如何在 vm 中覆盖 OnNavigatedTo 的?

标签: mvvm-light windows-8


【解决方案1】:

我知道这不是您可能正在寻找的确切答案,但这可能会给您一些探索的想法。

就我而言,我没有使用 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 传递给视图模型。就我而言,我在页面的代码隐藏中创建视图模型:

public HomePage()
{
    this.InitializeComponent();

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

    DataContext = new HomePageViewModel(_navigationService);

}

希望这会有所帮助。

【讨论】:

  • +1 - 我喜欢这种方法。对于“丑陋的部分”,您可以使用 DI 容器,这样您就不必将服务传递给视图代码隐藏中的视图模型。
  • 最新版本的 MVVMLight 有一个 SimpleIoc,只需几行代码就可以开箱即用。
【解决方案2】:

阅读 Laurent Bugnion 本人最近在 MSDN 杂志上发表的关于使用 MVVM Light Toolkit 和 Windows 8 的文章。

在文章的最后,他详细解释了如何设置您需要的 NavigationService

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

【讨论】:

    【解决方案3】:

    MVVMLight 中的 NavigationService 已迁移到名为 WinRTBehaviors 的新包中。您还可以从 nuget 获取 Win8nl 中的 EventToCommand。请参阅我在此处发布的博客:

    使用适用于 Windows 8、EventToCommand 和行为的 MVVM Light 入门 http://blog.tattoocoder.com/2012/08/getting-started-w-windows-8-mvvm-light.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多