Search code examples
c#.netwpfmvvmnavigationservice

Pass Field from one page to another page in WPF using MVVM


We are making a project where we have one page of our WPF application which will choose a save game out of three, and then it navigates to the next page. We whould like to know how to pass the GameInstance we load from the first page, to the second.

We have already implemented this in the Code Behind, but we dont like having logic in code behind, since we are using the MVVM architecure.

Code Behind of save window

public SaveGameWindow()
{
    InitializeComponent();
}

private void LoadGame1_Click(object sender, RoutedEventArgs e)
{
    var comb = new SaveGameViewModel();
    comb.LoadGame1();
    this.NavigationService.Navigate(comb.TempCombatWindow);
}

private void LoadGame2_Click(object sender, RoutedEventArgs e)
{
    var comb = new SaveGameViewModel();
    comb.LoadGame2();
    this.NavigationService.Navigate(comb.TempCombatWindow);
}

private void LoadGame3_Click(object sender, RoutedEventArgs e)
{
    var comb = new SaveGameViewModel();
    comb.LoadGame3();
    this.NavigationService.Navigate(comb.TempCombatWindow);
}

What we would like to know, is how to implement the same thing as above, but in our ViewModel for the save game.

The issue is when we change pages, we use the NavigationService, but this is not available in the ViewModel, and we have not found a way to bind this property to said ViewModel so we can use some kind of delegate.

I hope the question was not to confusing.


Solution

  • You can do this using an ICommand and command parameter in your view model and using an event. You can implement an interface like this one for your commands.

    • In your View Model implement the interface and create a function like this:

      private void LoadGame(object parameter) { switch (parameter.ToString()) { case "1": LoadGame1(); break; case "2": LoadGame2(); break; case "3": LoadGame3(); break; } ComabtWindowHandler(); }

    • The handler will be the event handler that you will be implementing in code behind. But first you need an ICommand like this one:

      public ICommand Load { get { RelayCommand<object> load= new RelayCommand<object((parameter) => LoadGame(parameter)); return load; } }

    This Property will be Bound in your xaml inside the Command property of your Save Buttons.

    • For the handler, first declare an abstract event handler in your View model

      public EventHandler ComabtWindowHandler;

    • In your Main Window, when you load your View model just add the delagate that will handle the event, so add this piece of code(let's suppose that comb is the instance of your viewmodel):

      comb.ComabtWindowHandler += delegate { this.NavigationService.Navigate(comb.TempCombatWindow); };

    • Finally in the xaml, in your 3 buttons bind Command and define the CommandParameter properties (in my example, the command parameter are simply "1" or "2" or "3". Of course button 1 will have parameter = "1" ecc...) but you can do more complicated stuff