Jeśli korzystasz już z MVVM Light, jedną z opcji jest skorzystanie z dołączonej magistrali komunikatów. Wiążesz więc przycisk z RelayCommand w modelu widoku, jak już powiedziałeś, że już robisz. W programie obsługi RelayCommand możesz podjąć decyzję, do którego widoku nawigować. Zachowuje to całą logikę w modelu widoku.
Po tym, jak program obsługi zdecyduje, do którego widoku nawigować, może opublikować komunikat na magistrali komunikatów. Twój widok będzie nasłuchiwał tego komunikatu, a następnie użyje usługi NavigationService do wykonania nawigacji. Więc nie robi nic innego niż czekanie na polecenie nawigacji gdzieś, a następnie nawigację tam, gdzie jest to powiedziane.
Robiłem to, definiując klasę NavigationMessage, którą moje modele widoku mogą publikować, i widok klasy bazowej, której moje widoki dziedziczą, z której składa się słuchacz. NavigationMessage wygląda następująco:
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;
}
}
Pozwala to po prostu przekazując nazwę strony, lub ewentualnie w tym również wszelkie niezbędne parametry ciągu zapytania. Procedura obsługi RelayCommand opublikuje tę wiadomość tak:
private void RelayCommandHandler()
{
//Logic for determining next view, then ...
Messenger.Default.Send(new NavigationMessage("ViewToNavigate"));
}
Wreszcie klasa widok baza wygląda tak:
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));
}
}
to zakładając konwencję gdzie wszystkie poglądy są w folderze „Widoki” w katalogu głównym aplikacji. Działa to dobrze dla naszej aplikacji, ale oczywiście można ją rozszerzyć, aby obsługiwać różne scenariusze organizowania swoich poglądów.
Doskonała sugestia, dzięki! –
Przyznam, że nie jestem zbyt zaznajomiony z systemem Messenger, który oferuje MVVM-Light. Czy w związku z dalszą refleksją nie oznacza to, że wszystkie widoki zarejestrują się i usłyszą ten komunikat NavigationMessage? –
Przypuszczam, że to może być problem. Używam tej techniki w kontekście aplikacji Windows Phone 7, w której mam tylko jeden aktywny widok na raz, więc działa to doskonale. Jeśli pracujesz w wersji Silverlight lub WPF dla komputerów stacjonarnych i masz jednocześnie wiele aktywnych widoków, widzę, gdzie może to być problem. Będę musiał pomyśleć o tym więcej. –