Passing parameters between viewmodels

As far as I understand, you want something like this:

Main screen showing the list
So that when you click Add, it shows this:
Main screen showng the add form

Right?

So you need the following behaviour:

  • Add doesn’t needs any ID.
  • List must reload after Add finishes.
  • Edit receives the list’s selected item ID .
  • List must reload after Add finishes.

I will assume that you are working with some repository.

I propose the following MVVM structure:

  • MainViewModel: The DataContext for the main screen.
    • BaseViewModel RightViewModel: The container for viewmodels shown on the right part of the screen.
    • ICommand ViewListCommand: Shows the list by creating a new instance of ListViewModel and assigning it to the BaseViewModel property.
    • ICommand AddNewCommand: Shows the addnew screen by creating a new isntance of AddViewModel and assigning it to the BaseViewModel property.

Then:

  • ListViewModel: The DataContext for the right part of the screen when List is clicked.
    • List<Items> Items: Provides the items to be shown.
    • Item SelectedItem: The property that will be binded to the SelectedItem on the UI.
    • ICommand EditCommand: The command that will get the selected item and notify the MainViewModel that has to be edited.

So at some point, a viewmodel will receive a notification from a child viewmodel (i.e. list will tell main to edit somethin). I recommend to do this by using events as:

public class Item
{
    public string Name { get; set; }
}

public class ItemEventArgs : EventArgs
{
    public Item Item { get; set; }

    public ItemEventArgs(Item selectedItem)
    {
        this.Item = selectedItem;
    }
}

public class BaseViewModel
{

}

public class ListViewModel : BaseViewModel
{
    public event EventHandler<ItemEventArgs> EditItem;

    public Item SelectedItem { get; set; }

    public ICommand EditItemCommand { get; private set; }

    public ListViewModel()
    {
        this.EditItemCommand = new DelegateCommand(() => this.EditItem(this, new ItemEventArgs(this.SelectedItem)));
    }
}

public class EditViewModel : BaseViewModel
{

}

public class MainViewModel
{
    public BaseViewModel RightViewModel { get; private set; }

    public ICommand ViewListCommand { get; private set; }

    public MainViewModel()
    {
        this.ViewListCommand = new DelegateCommand(() =>
        {
            // unhook possible previous events
            var listViewModel = new ListViewModel();
            listViewModel.EditItem += listViewModel_EditItem;
            this.RightViewModel = listViewModel;
        });
    }

    void listViewModel_EditItem(object sender, ItemEventArgs e)
    {
        // unhook possible previous events
        var editViewModel = new EditViewModel();
        this.RightViewModel = editViewModel;
    }

}

The xaml binding is not necessary since it will be quite forward.

This is a very basic example about how I think this kind of stuff can be handled. The important thing here is to properly unhook the events, otherwise you can run into problems.

For this kind of stuff you can also have a look at Reactive UI.

Leave a Comment