简体   繁体   中英

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.

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 eg 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;
    }    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM