Search code examples
wpfmvvmprismxceedprism-6

Prism NotificationRequest vs Xceed MessageBox


When we use MVVM we are told to avoid using System.Windows.MessageBox in our ViewModel, and I guess it is because it would not be good for our tests. Is it true?

With Prism NotificationRequest, we can comunicate with our users, but it is a little more complicated than a simple MessageBox.

Another way is to use Xceed Wpf Toolkit MessageBox, which is simplier than Prism NotificationRequest.

My question is: are both of them equivalent? Can we use any of them in a MVVM way? If NO, when do we need to use NotificationRequest and when can we use Xceed MessageBox?

Thank you


Solution

  • If you call MessageBox.Show() from a service that can be replaced with a mock when testing, you're fine.

    After all, what you do not want is a message box popping up when running your view models unit tests...

    Example:

    public interface IMessageBoxService
    {
        ClickedButten ShowMessageBox( string message, Buttons buttons );
    }
    
    internal class SomeViewModel
    {
        public SomeViewModel( IMessageBoxService messageBoxService )
        {
            _messageBoxService = messageBoxService;
        }
    
        public void SomeMethodThatNeedsAMessageBox()
        {
            var theClickedButton = _messageBoxService.ShowMessageBox( "Click me!", Buttons.Ok | Buttons.Cancel );
            // react to the click...
        }
    }
    
    internal class SystemMessageBoxService : IMessageBoxService
    {
        public ClickedButten ShowMessageBox( string message, Buttons buttons )
        {
            // adapt parameters...
            MessageBox.Show(...);
            // adapt result...
        }
    }
    
    internal class XceedMessageBoxService : IMessageBoxService
    {
        public ClickedButten ShowMessageBox( string message, Buttons buttons )
        {
            // adapt parameters...
            Xceed.ShowMessageBox(...);
            // adapt result...
        }
    }
    

    Now just bind the service that you want to use (could even be decided at runtime), and inject a mock when testing.