Немного опоздал на этот вопрос, но он актуален и, надеюсь, будет кому-то полезен. Я должен был создать приложение SL4 с MvvmLight и хотел использовать обертку службы навигации, которая была бы смоделированной и могла быть введена в ViewModel. Здесь я нашел хорошую отправную точку: примеры кода Лорана Буньона SL4 из Mix11, который включает демонстрацию навигационного сервиса: Deep Dive MVVM Mix11
Вот основные части для реализации моделируемого навигационного сервиса, который может использоваться с Silverlight 4. Ключевой вопрос - получение ссылки на основной фрейм навигации, который будет использоваться в пользовательском классе NavigationService.
1) В MainPage.xaml рамке навигации присваивается уникальное имя, для этого примера это будет ContentFrame :
<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
Source="/Home" Navigated="ContentFrame_Navigated"
NavigationFailed="ContentFrame_NavigationFailed">
<!-- UriMappers here -->
</navigation:Frame>
2) В MainPage.xaml.cs рамка навигации отображается как свойство:
public Frame NavigationFrame
{
get { return ContentFrame; }
}
3) Класс обслуживания навигации реализует интерфейс INavigationService и использует свойство NavigationFrame файла MainPage.xaml.cs для получения ссылки на фрейм навигации:
public interface INavigationService
{
event NavigatingCancelEventHandler Navigating;
void NavigateTo(Uri uri);
void GoBack();
}
public class NavigationService : INavigationService
{
private Frame _mainFrame;
public event NavigatingCancelEventHandler Navigating;
public void NavigateTo(Uri pageUri)
{
if (EnsureMainFrame())
_mainFrame.Navigate(pageUri);
}
public void GoBack()
{
if (EnsureMainFrame() && _mainFrame.CanGoBack)
_mainFrame.GoBack();
}
private bool EnsureMainFrame()
{
if (_mainFrame != null)
return true;
var mainPage = (Application.Current.RootVisual as MainPage);
if (mainPage != null)
{
// **** Here is the reference to the navigation frame exposed earlier in steps 1,2
_mainFrame = mainPage.NavigationFrame;
if (_mainFrame != null)
{
// Could be null if the app runs inside a design tool
_mainFrame.Navigating += (s, e) =>
{
if (Navigating != null)
{
Navigating(s, e);
}
};
return true;
}
}
return false;
}
}