Robert Garfoot のブログ「Silverlight Navigation With the MVVM Pattern」をフォローしました。
これにより、さまざまなエレガントな方法で、ページのコード ビハインドからナビゲーション処理を取得できます。
彼は、Navigate、GoBack、および GoForward を ViewModel で使用できるようにしているため、ナビゲーション コードのないコード ビハインドをそのままにしておくことができます。
それは美しく動作します。
しかし、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 にアクセスしたいと考えています。