Подтвердить что ты не робот

Каков наилучший способ обработки GoBack для разных платформ MvvmCross (v3)?

В MvvmCross v3 я использую ShowViewModel для перехода на разные страницы. Прежде чем перейти к Mvx, я бы использовал метод NavigationService.GoBack(), чтобы вернуться на предыдущую страницу. Преимущество в том, что страница не воссоздана.

Поскольку метод GoBack является платформой, специфичной для WP, WInRT, Silverlight, как лучше всего обращаться с возвратом на предыдущую страницу, чтобы модель представления оставалась независимой от платформы?

Одним из решений может быть использование ShowViewModel передачи некоторых данных, которые может видеть вид, а затем в случае WP/WinRT, вызывая RemoveBackEntry из представления. Но с Mvx, вероятно, лучший способ.

4b9b3361

Ответ 1

В MvvmCross v3 мы предоставили конкретный механизм, позволяющий ViewModels отправлять сообщения в пользовательский интерфейс, чтобы они хотели изменить текущую презентацию.

Этот механизм ChangePresentation(MvxPresentationHint hint) и обеспечивает маршрутизацию сообщений - подсказки представления - от ViewModels до Presenter.

Как Presenter обрабатывает эти сообщения, зависит от платформы и приложения.

Этот механизм сообщений очень общий, и он может использоваться для всех видов в будущем - например, разработчики могут предлагать подсказки, которые делают такие вещи, как изменение макета пользовательского интерфейса, которые выделяют часть пользовательского интерфейса, которые заставляют пользователя сосредоточиться на определенном элементе управления, что приводит к отображению или скрытию SIP и т.д.


В случае закрытия модели представления мы предоставили специализацию MvxPresentationHint - MvxClosePresentationHint - и вспомогательный метод в базовом классе MvxViewModel:

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

Чтобы использовать это, ViewModel может просто вызвать Close(this)

Когда это вызывается, презентатор в вашем пользовательском интерфейсе получит сообщение по методу ChangePresentation:

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

Для общего/типичного случая, когда закрываемый ViewModel прикрепляется к представлению, которое является самым верхним Activity/Page/UIViewController, ведущие по умолчанию в MvvmCross смогут обрабатывать это сообщение и сможет GoBack в Windows, Finish в Android и PopViewController в iOS.

Однако, если ваш пользовательский интерфейс более сложный, чем тот, например. если ViewModel, который вы хотите Close, действительно соответствует Tab, a Flyout, a SplitView и т.д., или если ViewModel соответствует чему-то другому, кроме текущего верхнего вида в иерархия - тогда вам нужно будет предоставить пользовательскую реализацию презентатора - и для реализации этой задачи потребуется обработать платформу и конкретную прикладную логику для обработки Close.


Вышеуказанный совет - это то, что я рекомендую вам использовать...

Однако, как альтернативный:

Если бы вы почувствовали, что этот механизм ChangePresentation(MvxPresentationHint hint) был просто слишком тяжелым/избыточным для вашего приложения, то вы также можете, конечно же, перейти к настраиваемому или Message механизму.

Один образец, который делает это, представляет собой образец CustomerManagement - он предоставляет пользовательскую реализацию IViewModelCloser на каждой платформе - см.:

Ответ 2

Я не совсем уверен в mvvmcross, но в MVVM Light обычно делается так, чтобы создать интерфейс INavigationService, который предоставляет эти методы.

Затем каждая платформа реализует этот Интерфейс в зависимости от платформы (в WP, например, путем получения ссылки на текущий кадр и его содержимое). Этот конкретный экземпляр платформы может выполнить все правильные действия, чтобы убедиться, что шаблон навигации правильно реализован.

Затем ваши модели ViewModels могут получить ссылку на экземпляр службы INavigationService через контейнер зависимостей. Таким образом, ваша виртуальная машина независима от специфики навигации на платформе.

Я также написал сообщение в блоге о том, как использовать интерфейсы для раскрытия общего API для конкретных функций платформы: http://www.kenneth-truyers.net/2013/02/24/patterns-for-sharing-code-in-windows-phone-and-windows-8-applications/

Пример в блоге - об изолированном хранилище, но те же принципы применимы к навигации (или любой функции, которая имеет разные реализации на разных платформах, если на то пошло)