MessageBox - canton7/Stylet GitHub Wiki
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).
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.
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:
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" |
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.
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.
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).
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.