使用MVVM模式的Silverlight导航

时间:2012-10-18 19:04:07

标签: c# mvvm navigation silverlight-5.0

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

0 个答案:

没有答案