Skip to content
canton7 edited this page Nov 27, 2014 · 9 revisions

As we all know, WPF comes with its own MessageBox implementation - System.Windows.MessageBox. And that's fine, except that you can't call it from your ViewModel (well, you can, but it makes your ViewModel untestable). The usual workaround suggested online is "write your own".

Well, Stylet comes with its own MessageBox clone, which looks and behaves almost identically to the WPF one (including appearance, buttons, icons, auto-sizing, sounds, alignment, etc).

Usage

To use, simply call the ShowMessageBox extension method on IWindowManager, like this:

public MyViewModel
{
   private IWindowManager windowManager;

   public MyViewModel(IWindowManager windowManager)
   {
      this.windowManager = windowManager;
   }

   public void ShowMessagebox()
   {
      var result = this.windowManager.ShowMessageBox("Hello");
   }
}

Important: If you're using an IoC container other than StyletIoC (i.e. you've written your own bootstrapper, which extends BootstrapperBase<T>), you must bind IMessageBoxViewModel to MessageBoxViewModel for this to work.

The MessageBox accepts all of the same options as as the WPF MessageBox, plus a few more.

Customising the MessageBox

Stylet's MessageBox is implemented as a ViewModel, MessageBoxViewModel, and its corresponding View, MessageBoxView. The ViewModel implements an interface, IMessageBoxViewModel, and the ShowMessageBox() extension method uses this interface to retrieve an instance of the ViewModel.

Therefore, you can provide you own custom implementation of MessageBoxViewModel and MessageBoxView by writing a ViewModel which implements IMessageBoxViewModel, and registering it with your IoC container. This will then be used by ShowMessageBox().

If you just want to tweak the behaviour of the existing MessageBoxViewModel, you can. The following options are available:

Custom Button Text

You can edit the button text for any of the buttons on a per-application basis by modifying MessageBoxViewModel.ButtonLabels, which is a dictionary holding the text to display for each button. If you just want to edit the text for a particular MessageBox, ShowMessageBox will accept a dictionary allowing you to do just that:

MessageBoxViewModel.ButtonLabels[MessageBoxButton.No] = "No, thanks";

this.windowManager.ShowMessageBox("Do you want breakfast?", buttons: MessageBoxButton.YesNo, buttonText: new Dictionary<MessageBoxResult, string>()
{
   { MessageBoxResult.Yes, "Yes please!" },
});

// Will display a MessageBox with the buttons "Yes please!" and "No, thanks"

Custom Button Sets

The MessageBoxViewModel.ButtonToResults dictionary specifies which buttons are shown for each MessageBoxButton enumeration value. Want to be able to display the buttons "OK", "Yes" and "No" together? Fiddle with this dictionary.

Custom Icons

The MessageBoxViewModel.IconMapping dictionary specifies while icon is shown for which MessageBoxImage value. This dictionary must contain an entry for each MessageBoxImage value (note that different enum entries have the same value here), but a value may be null, in which case no icon is shown.

Custom Sounds

MessageBoxViewModel.SoundMapping is a dictionary of which sound should be played for each MessageBoxImage. As with IconMapping, an entry must exist for each value in the MessageBoxImage enum, but null is a valid value (in which case no sound is played).

Clone this wiki locally