Если вы уже используете MVVM Light, один из вариантов заключается в использовании шины сообщений, которую он включает. Таким образом, вы привязываете свою кнопку к RelayCommand на модели представления, как вы уже сказали, что уже делаете. В обработчике вашего RelayCommand вы можете принять решение о том, на какой взгляд перейти. Это сохраняет всю эту логику в модели представления.
После того, как ваш обработчик задал, к какому виду перейти, он может опубликовать сообщение на шине сообщений. Ваше представление будет прослушивать это сообщение, а затем использовать NavigationService для фактического выполнения навигации. Таким образом, это ничего не значит, кроме как ждать, когда ему скажут, что нужно куда-то перемещаться, а затем переходить туда, где сказано.
Я делал это, определяя класс NavigationMessage, который могут публиковать мои модели просмотра, и базовый класс представления, которые наследуют мои представления, из которых содержит слушателя. NavigationMessage выглядит следующим образом:
public class NavigationMessage : NotificationMessage
{
public string PageName
{
get { return base.Notification; }
}
public Dictionary<string, string> QueryStringParams { get; private set; }
public NavigationMessage(string pageName) : base(pageName) { }
public NavigationMessage(string pageName, Dictionary<string, string> queryStringParams) : this(pageName)
{
QueryStringParams = queryStringParams;
}
}
Это позволяет просто передавая имя страницы, или, возможно, также включая все необходимые строки запроса параметров. Обработчик RelayCommand бы опубликовать это сообщение так:
private void RelayCommandHandler()
{
//Logic for determining next view, then ...
Messenger.Default.Send(new NavigationMessage("ViewToNavigate"));
}
Наконец, вид базового класса выглядит следующим образом:
public class BasePage : PhoneApplicationPage
{
public BasePage()
{
Messenger.Default.Register<NavigationMessage>(this, NavigateToPage);
}
protected void NavigateToPage(NavigationMessage message)
{
//GetQueryString isn't shown, but is simply a helper method for formatting the query string from the dictionary
string queryStringParams = message.QueryStringParams == null ? "" : GetQueryString(message);
string uri = string.Format("/Views/{0}.xaml{1}", message.PageName, queryStringParams);
NavigationService.Navigate(new Uri(uri, UriKind.Relative));
}
}
Это предполагает, что конвенции, где все виды находятся в папке «Views» в корне приложения. Это отлично подходит для нашего приложения, но, конечно, это может быть расширено для поддержки различных сценариев для того, как вы упорядочиваете свои представления.
Отличное предложение, спасибо! –
Я признаю, что я не слишком хорошо знаком с системой Messenger, которую предлагает MVVM-Light. Что касается дальнейшего размышления, значит ли это, что все взгляды будут регистрироваться и слышать этот NavigationMessage? –
Я полагаю, это может быть проблемой. Я использую эту технику в контексте приложения Windows Phone 7, где у меня есть только один вид активности за один раз, поэтому он работает отлично. Если вы работаете в настольной версии Silverlight или WPF, и у вас одновременно есть несколько представлений, я вижу, где это может быть проблемой. Подумайте об этом еще немного. –