我关注了Robert Garfoot的博客"Silverlight Navigation With the MVVM Pattern"。
它允许您以不同的优雅方式从页面的代码隐藏中进行导航处理。
他为您的ViewModel提供了Navigate,GoBack和GoForward,因此您可以使代码隐藏免于导航代码。
它很漂亮。
但是我想从ViewModel访问一些事件(Navigated,Navigating,NavigationFailed等)。 我不知道怎么做。这是使用接口和掌握c#的问题。
对不起,如果它有点长,但我会尽量简短说明:
我将把所有这些类放在一个名为LibrariesSL.MVVMNavigation的名称空间中:
他创建了一个INavigationService接口:
public interface INavigationService {
void NavigateTo(string url);
void GoBack();
void GoForward();
}
一个NavigationService类:
public class NavigationService : INavigationService {
private readonly System.Windows.Navigation.NavigationService _navigationService;
public NavigationService(System.Windows.Navigation.NavigationService navigationService) {
_navigationService = navigationService;
}
public void NavigateTo(string url) {
_navigationService.Navigate(new Uri(url, UriKind.Relative));
}
public void GoBack() {
...
}
public void GoForward() {
...
}
}
然后是一个可用于扩展ViewModel的INavigable接口:
public interface INavigable {
INavigationService NavigationService { get; set; }
}
在ViewModel中,我们只是继承并使用它:
public class CustomerViewModel : ViewModelsBase, INavigable {
MyDomainContext _Context = new MyDomainContext ();
...
...
public void OnShowCustomer(object param) {
int selectedCustomerID = SelectedCustomer.CustomerID;
// Here we perform navigation
NavigationService.NavigateTo(string.Format("/CustomerDetails?CustomerID={0}",
selectedCustomerID));
}
#region INavigable
public INavigationService NavigationService { get; set; }
#endregion
我们还必须创建一个附加到视图的依赖项属性:
public static class Navigator {
public static INavigable GetSource(DependencyObject obj) {
return (INavigable)obj.GetValue(SourceProperty);
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.RegisterAttached("Source", typeof(INavigable), typeof(Navigator),
new PropertyMetadata(OnSourceChanged));
private static void OnSourceChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e) {
Page page = (Page)d;
page.Loaded += PageLoaded;
}
private static void PageLoaded(object sender, RoutedEventArgs e) {
Page page = (Page)sender;
INavigable navSource = GetSource(page);
if (navSource != null) {
navSource.NavigationService = new NavigationService(page.NavigationService);
}
}
}
然后在视图中我们这样做:
<navigation:Page x:Class="UsingQueryStrings.Views.Customers"
...
xmlns:MVVMNavigation="clr-namespace:LibrariesSL.MVVMNavigation"
MVVMNavigation:Navigator.Source="{Binding}"
>
我想访问System.Windows.Navigation.NavigationService中存在的Navigated,Navigating和NavigationFailed事件。