从Windows Phone 8.1通用应用程序中的视图模型导航到新页面

And*_*wJE 8 c# mvvm mvvm-light windows-phone-8.1

我正在开发一个Windows Phone 8.1通用应用程序,并希望找到处理页面导航的最佳方法,而不会在后面的代码中有大量逻辑.我希望尽可能整洁地将代码保留在我的视图中.为响应按钮点击,导航到新页面的MVVM方式是什么?

我目前必须从ViewModel向视图发送一条RelayComnmand消息,其中包含要导航到的页面的详细信息.这意味着后面的代码必须按如下方式连接:

    public MainPage()
    {
      InitializeComponent();
      Messenger.Default.Register<OpenArticleMessage>(this, (article) => ReceiveOpenArticleMessage(article));
...
}

    private object ReceiveOpenArticleMessage(OpenArticleMessage article)
    {
     Frame.Navigate(typeof(ArticleView));
   }
Run Code Online (Sandbox Code Playgroud)

虽然它确实有效,但这似乎并不是最好的方法.如何直接从ViewModel进行页面导航?我在我的项目中使用MVVM-Light.

And*_*wJE 10

好的,我找到了这个问题的答案.进行了一些调查,但我最终找到了首选的MVVM-Light方式.无论如何我都不赞成这个答案,只是在这里发帖,以防人们正在寻找这个问题的答案.

创建一个INavigationService接口,如下所示:

public interface INavigationService
{
    void Navigate(Type sourcePageType);
    void Navigate(Type sourcePageType, object parameter);
    void GoBack();
}
Run Code Online (Sandbox Code Playgroud)

创建一个NavigationService类,如下所示:

public class NavigationService : INavigationService
{
    public void Navigate(Type sourcePageType)
    {
        ((Frame)Window.Current.Content).Navigate(sourcePageType);
    }

    public void Navigate(Type sourcePageType, object parameter)
    {
        ((Frame)Window.Current.Content).Navigate(sourcePageType, parameter);
    }

    public void GoBack()
    {
        ((Frame)Window.Current.Content).GoBack();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在ViewModelLocator中,将其设置如下:

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }

    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        if (ViewModelBase.IsInDesignModeStatic)
        {
            SimpleIoc.Default.Register<INavigationService, Design.DesignNavigationService>();
        }
        else
        {
            SimpleIoc.Default.Register<INavigationService>(() => new NavigationService());
        }

        SimpleIoc.Default.Register<MainViewModel>();
    }
Run Code Online (Sandbox Code Playgroud)

接下来设置导航服务的设计时间如下:

public class DesignNavigationService : INavigationService
{
    // This class doesn't perform navigation, in order
    // to avoid issues in the designer at design time.

    public void Navigate(Type sourcePageType)
    {
    }

    public void Navigate(Type sourcePageType, object parameter)
    {
    }

    public void GoBack()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我的MainViewModel构造函数如下:

   public MainViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;

        ...
Run Code Online (Sandbox Code Playgroud)

现在您可以使用它在viewmodel中导航:

_navigationService.Navigate(typeof(WelcomeView));
Run Code Online (Sandbox Code Playgroud)

有关原作者Laurent Bugnion的更多详细信息,请参阅此文章和相关代码. http://msdn.microsoft.com/en-us/magazine/jj651572.aspx

  • 这里的问题是你的视图模型与视图类(typeof(...))有一个依赖关系,应该在严格的MVVM环境中避免... (5认同)