Nếu bạn đã sử dụng MVVM Light, một tùy chọn là sử dụng bus thông báo mà nó bao gồm. Vì vậy, bạn liên kết nút của bạn với một RelayCommand trên mô hình xem, như bạn đã nói bạn đã làm. Trong trình xử lý cho RelayCommand của bạn, bạn có thể đưa ra quyết định về chế độ xem để điều hướng đến. Điều này giữ tất cả logic đó trong mô hình khung nhìn.
Khi trình xử lý lệnh của bạn đã quyết định xem điều hướng nào, nó có thể xuất bản một tin nhắn trên xe buýt tin nhắn. Chế độ xem của bạn sẽ lắng nghe thông điệp đó và sau đó sử dụng NavigationService để thực sự thực hiện điều hướng. Vì vậy, nó không làm bất cứ điều gì khác hơn là chờ đợi để được thông báo để điều hướng một nơi nào đó và sau đó điều hướng nơi nó được nói.
Tôi đã làm điều này bằng cách xác định lớp NavigationMessage mà các kiểu xem của tôi có thể xuất bản và lớp cơ sở chế độ xem mà lượt xem của tôi kế thừa từ đó chứa trình nghe. NavigationMessage trông giống như sau:
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;
}
}
Điều này cho phép chỉ cần chuyển tên trang hoặc tùy chọn cũng bao gồm bất kỳ tham số chuỗi truy vấn cần thiết nào. Một handler RelayCommand sẽ công bố thông điệp này như thế này:
private void RelayCommandHandler()
{
//Logic for determining next view, then ...
Messenger.Default.Send(new NavigationMessage("ViewToNavigate"));
}
Cuối cùng, lớp xem cơ sở trông như thế này:
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));
}
}
này là giả định một quy ước mà tất cả các quan điểm đang ở trong một "Views" thư mục trong thư mục gốc của ứng dụng. Điều này làm việc tốt cho ứng dụng của chúng tôi nhưng tất nhiên điều này có thể được mở rộng để hỗ trợ các kịch bản khác nhau về cách bạn tổ chức các quan điểm của mình.
Đề xuất tuyệt vời, cảm ơn! –
Tôi sẽ thừa nhận rằng tôi không quá quen thuộc với hệ thống Messenger mà MVVM-Light cung cấp.Upon phản ánh thêm, điều này không có nghĩa là tất cả các chế độ xem sẽ đăng ký và nghe điều hướng này không? –
Tôi cho rằng đó có thể là một vấn đề. Tôi đang sử dụng kỹ thuật này trong ngữ cảnh của một ứng dụng Windows Phone 7, nơi tôi chỉ có một chế độ xem hoạt động tại một thời điểm để nó hoạt động hoàn hảo. Nếu bạn đang làm việc trong phiên bản Silverlight trên máy tính để bàn hoặc WPF và bạn có nhiều chế độ xem đang hoạt động cùng một lúc, tôi có thể thấy đây có thể là vấn đề. Sẽ phải suy nghĩ về điều đó một số chi tiết. –