13

在 MvvmCross v3 中,我使用ShowViewModel导航到不同的页面。在转换为 Mvx 之前,我会使用该NavigationService.GoBack()方法返回上一页。优点是不会重新创建页面。

由于该GoBack方法是特定于 WP、WInRT、Silverlight 的平台,因此处理返回上一页以使视图模型保持平台独立的最佳方法是什么?

一种解决方案可能是使用ShowViewModel传递视图可以看到的一些数据,然后在 WP/WinRT 的情况下,RemoveBackEntry从视图调用。但是对于 Mvx,可能有更好的方法。

4

2 回答 2

18

在 MvvmCross v3 中,我们提供了一种特定的机制来允许 ViewModel 向 UI 发送他们想要更改当前呈现的消息。

这种机制是ChangePresentation(MvxPresentationHint hint)并且它提供了从ViewModelsPresenter.

Presenter处理这些消息的方式取决于平台和应用程序。

这种消息机制非常通用,将来可能会用于各种事情 - 例如,开发人员可能会提供一些提示,例如更改 UI 布局,突出显示部分 UI,迫使用户专注于某个控制,导致 SIP 显示或隐藏等。


对于关闭视图模型的情况,我们提供了一个特殊化的MvxPresentationHint- MvxClosePresentationHint- 和一个基类中的辅助方法MvxViewModel

    protected bool Close(IMvxViewModel viewModel)
    {
        return ChangePresentation(new MvxClosePresentationHint(viewModel));
    }

要使用这个 ViewModel 可以调用Close(this)

调用此方法时,UI 中的 Presenter 将收到有关该ChangePresentation方法的消息:

public interface IMvxViewPresenter
{
    void Show(MvxViewModelRequest request);
    void ChangePresentation(MvxPresentationHint hint);
}

对于一般/典型情况 -ViewModel正在关闭的视图附加到最顶层的视图Activity// , PageMvvmCrossUIViewController中的默认演示者将能够处理此消息,并且能够GoBack在 Windows、FinishAndroid 和在PopViewControlleriOS 中。

但是,如果您的 UI 比这更复杂 - 例如,如果ViewModel您想要Close实际对应于 a Tab、 a FlyoutSplitView窗格等,或者如果ViewModel对应于层次结构中当前最顶层视图以外的其他内容 - 那么您将需要提供一个自定义的 Presenter 实现——并且该实现必须做平台和应用程序特定的逻辑来处理Close.


以上提示是我建议您使用的...

但是,作为替代方案

如果您觉得这种ChangePresentation(MvxPresentationHint hint)机制对您的应用程序来说太重/过大了,那么您当然也可以改为使用自定义或Message基于机制的机制。

执行此操作的一个示例是 CustomerManagement 示例 - 它在每个平台上提供了一个自定义 IViewModelCloser 实现 - 请参阅:

于 2013-04-23T00:30:27.260 回答
3

我不完全确定 mvvmcross,但在 MVVM Light 中,通常所做的是创建一个 INavigationService 接口来公开这些方法。

然后,每个平台以特定于平台的方式实现此接口(例如在 WP 中,通过获取对当前帧及其内容的引用)。然后,此平台特定实例可以执行所有正确操作,以确保正确实施导航模式。

然后,您的 ViewModel 可以通过 Dependency Container 获取对 INavigationService 实例的引用。这样,您的 VM 就独立于导航的平台细节。

我还写了一篇关于如何使用接口为平台特定功能公开通用 API 的博客文章:http: //www.kenneth-truyers.net/2013/02/24/patterns-for-sharing-code-in-windows -phone-and-windows-8-applications/

博客文章中的示例是关于独立存储的,但同样的原则适用于导航(或任何在不同平台上具有不同实现的特性)

于 2013-04-22T22:13:29.217 回答