wojg21
wojg21

Reputation: 93

Is this the correct way to use the MVVM Light Messenger class

I started out with this article on how to implement navigation in a MVVM environment. Then I started reading about the Messenger class and how useful it would be to communicate between ViewModels. I set out to implement the same navigation concept using the messenger class and came up with this:

MainViewModel:

public sealed class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        PageViewModels.Add(new Page1ViewModel());
        PageViewModels.Add(new Page2ViewModel());

        Messenger.Default.Register<PageNavigationMessage>(this, (pageViewModel) =>
        {
            switch (pageViewModel.CurrentViewModel.Name)
            {
                case "Page1":
                    CurrentPageViewModel = PageViewModels[0];
                    break;
                case "Page2":
                    CurrentPageViewModel = PageViewModels[1];
                    break;
            }
        });
    }

    private List<IPageViewModel> _pageViewModels;

    public List<IPageViewModel> PageViewModels
    {
        get
        {
            if (_pageViewModels == null)
                _pageViewModels = new List<IPageViewModel>();
            return _pageViewModels;
        }
    }

    private IPageViewModel _currentPageViewModel;

    public IPageViewModel CurrentPageViewModel
    {
        get { return _currentPageViewModel; }
        set
        {
            if (_currentPageViewModel != value)
            {
                _currentPageViewModel = value;
                RaisePropertyChanged("CurrentPageViewModel");
            }
        }
    }

    private ICommand _changePageCommand;
    public ICommand ChangePageCommand
    {
        get
        {
            if (_changePageCommand == null)
            {
                _changePageCommand =
                    new RelayCommand<IPageViewModel>(pn => Messenger.Default.Send(new PageNavigationMessage{CurrentViewModel = pn}));
            }

            return _changePageCommand;
        }
    }

In the corresponding Page1 and Page2 viewmodels I have the Name property that gives content to the button. So this will produce Page1 button and Page2 button.

I will show only the Page1ViewModel because the second page is pretty much identical apart from the Name property string.

public class Page1ViewModel : ViewModelBase, IPageViewModel
{
    public string Name
    {
        get { return "Page1"; }
    }
}

Here I implemented a basic PageNavigationMessage class:

public class PageNavigationMessage
{
    public IPageViewModel CurrentViewModel { get; set; }
}

This works very well but I was wondering if this is the correct way to implement the Messenger class in the MVVM Light toolkit.

I would like to thank Rachel Lim's blog post, referenced above, for the detailed post and example.

Any comments, suggestions, etc are greatly appreciated.

Upvotes: 1

Views: 641

Answers (1)

Lennart
Lennart

Reputation: 10324

This is pretty much the same way we do it in our application.

Some thing we also do for the messenger:

  • Make a common MessageTypes class, that contains all the different messages. Since most of them are just a declaration with inheritance of MessageBase, a class for each message would be a mess.
  • If your class registeres for more than one or two messages, we refactored the message registration in a separate method to easily add/remove messages
  • If the logic for your message is more than a line or two, we generally put them in an extra method, so e.g. for your example that would be:

public MainViewModel()
{
    Messenger.Default.Register<PageNavigationMessage>(this, SetPageViewModel);
}

private void SetPageViewModel(IPageViewmodel selectedVm)
{

    switch (selectedVm.CurrentViewModel.Name)
    {
       case "Page1":
             CurrentPageViewModel = PageViewModels[0];
             break;
       case "Page2":
             CurrentPageViewModel = PageViewModels[1];
             break;
    }    
}

Upvotes: 1

Related Questions