I\'m having a serious headache with this problem. I really dislike store apps but am forced to use it in this case. I\'ve only worked with XAML for a few weeks.
My q
I don't really like when a ViewModel references Views to navigate to. So I prefer to a ViewModel-first approach. By using ContentControls, DataTemplates for ViewModel types & some kind of navigation pattern in my ViewModels.
My navigation looks like this:
[ImplementPropertyChanged]
public class MainNavigatableViewModel : NavigatableViewModel
{
public ICommand LoadProfileCommand { get; private set; }
public ICommand OpenPostCommand { get; private set; }
public MainNavigatableViewModel ()
{
LoadProfileCommand = new RelayCommand(() => Navigator.Navigate(new ProfileNavigatableViewModel()));
OpenPostCommand = new RelayCommand(() => Navigator.Navigate(new PostEditViewModel { Post = SelectedPost }), () => SelectedPost != null);
}
}
My NavigatableViewModel looks like:
[ImplementPropertyChanged]
public class NavigatableViewModel
{
public NavigatorViewModel Navigator { get; set; }
public NavigatableViewModel PreviousViewModel { get; set; }
public NavigatableViewModel NextViewModel { get; set; }
}
And my Navigator:
[ImplementPropertyChanged]
public class NavigatorViewModel
{
public NavigatableViewModel CurrentViewModel { get; set; }
public ICommand BackCommand { get; private set; }
public ICommand ForwardCommand { get; private set; }
public NavigatorViewModel()
{
BackCommand = new RelayCommand(() =>
{
// Set current control to previous control
CurrentViewModel = CurrentViewModel.PreviousViewModel;
}, () => CurrentViewModel != null && CurrentViewModel.PreviousViewModel != null);
ForwardCommand = new RelayCommand(() =>
{
// Set current control to next control
CurrentViewModel = CurrentViewModel.NextViewModel;
}, () => CurrentViewModel != null && CurrentViewModel.NextViewModel != null);
}
public void Navigate(NavigatableViewModel newViewModel)
{
if (newViewModel.Navigator != null && newViewModel.Navigator != this)
throw new Exception("Viewmodel can't be added to two different navigators");
newViewModel.Navigator = this;
if (CurrentViewModel != null)
{
CurrentViewModel.NextViewModel = newViewModel;
}
newViewModel.PreviousViewModel = CurrentViewModel;
CurrentViewModel = newViewModel;
}
}
My MainWindows.xaml:
App.xaml.cs:
public partial class App
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new MainWindow {DataContext = new MyAppViewModel()}.Show();
}
}
MyAppViewModel:
[ImplementPropertyChanged]
public class MyAppViewModel
{
public NavigatorViewModel Navigator { get; set; }
public MyAppViewModel()
{
Navigator = new NavigatorViewModel();
Navigator.Navigate(new MainNavigatableViewModel());
}
}
App.xaml:
The downside is that you have more ViewModel-code which manages the state of what you are looking at. But obviously that is also a huge advantage in terms of Testability. And of course your ViewModels do not need to depend on your Views.
Plus I use Fody/PropertyChanged, that's what the [ImplementPropertyChanged] is about. Keeps me from writing OnPropertyChanged code.