Skip to content
ImminentFate edited this page Mar 31, 2018 · 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 method on IWindowManager, like this:

 

C# VB.NET
public MyViewModel
{
   private readonly IWindowManager windowManager;
 
   public MyViewModel(IWindowManager windowManager)
   {
      this.windowManager = windowManager;
   }
 
   public void ShowMessagebox()
   {
      var result = this.windowManager.ShowMessageBox("Hello");
   }
}
Public Class MyViewModel
 
    Private ReadOnly windowManager As IWindowManager
 
    Public Sub New(ByVal windowManager As IWindowManager)
        Me.windowManager = windowManager
    End Sub
 
    Public Sub ShowMessagebox()
        Dim result = Me.windowManager.ShowMessageBox("Hello")
    End Sub
End Class

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() 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:  

C# VB.NET
MessageBoxViewModel.ButtonLabels[MessageBoxResult.No] = "No, thanks";
 
this.windowManager.ShowMessageBox("Do you want breakfast?", 
                                   buttons: MessageBoxButton.YesNo, 
                                   buttonLabels: new Dictionary<MessageBoxResult, string>()
        {
            { MessageBoxResult.Yes, "Yes please!" },
        });
 
// Will display a MessageBox with the buttons "Yes please!" and "No, thanks"
    MessageBoxViewModel.ButtonLabels(MessageBoxResult.No) = "No, thanks"
    Me.windowManager.ShowMessageBox("Do you want breakfast?",
                                    buttons:=MessageBoxButton.YesNo,
                                    buttonLabels:=New Dictionary(Of MessageBoxResult, String)() _
                                    From {{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).

Custom FlowDirection and TextAlignment

There are parameters to IWindowManager.ShowMessageBox() allowing you to specify the FlowDirection and TextAlignment. If you do not specify these, then the defaults MessageBoxViewModel.FlowDirection and MessageBoxViewModel.TextAlignment are used. You can change these defaults as well, if you wish.

Clone this wiki locally