1

我关注了 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。

4

0 回答 0