Behaviors seems like the killer feature for every possible problem we used to have with MVVM. Thank god for WPF4 
Showing a Message Box is one of those navigational problems that comes with MVVM. It’s something that we want the ViewModel to control, but yet we don’t want the ViewModel to contain any hard reference to the View.
My solution uses the Messenger class from MVVMLight toolkit, but can easily be adjusted to use Prism’s EventAggregator.
Lauren Bugnion suggested a solution a while ago which is to send a message to the view’s CodeBehind, and from there to open a message box like so:
1: public MainPage() //Yuck code behind.
2: {
3: InitializeComponent();
4:
5: Messenger.Default.Register<DialogMessage>(
6: this,
7: msg =>
8: {
9: var result = MessageBox.Show(
10: msg.Content,
11: msg.Caption,
12: msg.Button);
13:
14: // Send callback
15: msg.ProcessCallback(result);
16: });
17: }
It’s important to say that the solution is basically good, and that the separation of layers is kept.
It is, however, far from elegant. It uses code behind, and it is not very reusable. That’s where behaviors come into play – The perfect solutions to such problems. What we have to do is create a Custom MessageBox Behavior that could address that.
The Custom Behavior
Behaviors are really easy to implement, all you have to do is to implement Behavior<T>, and override the OnAttached and OnDetached:
1: class DialogBehavior : Behavior<FrameworkElement>
2: {
3: Messenger messenger = Messenger.Default;
4:
5: protected override void OnAttached()
6: {
7: base.OnAttached();
8:
9: messenger.Register<GalaSoft.MvvmLight.Messaging.DialogMessage>(this, Identifier, ShowDialog);
10: }
11:
12: public string Identifier { get; set; }
13: public string Caption { get; set; }
14: public string Text { get; set; }
15: public MessageBoxButton Buttons { get; set; }
16:
17: private void ShowDialog(GalaSoft.MvvmLight.Messaging.DialogMessage dm)
18: {
19: var result = MessageBox.Show(Text, Caption, Buttons);
20:
21: dm.Callback(result);
22: }
23:
24: }
In order to use it we have to put it anywhere in the view, but putting it in the top makes more sense:
1: <i:Interaction.Behaviors>
2: <local:DialogBehavior Caption="MyCap" Text="MyText" Buttons="YesNoCancel" Identifier="mb1" />
3: <local:DialogBehavior Caption="MyCap2" Text="MyText2" Buttons="YesNo" Identifier="mb2" />
4: </i:Interaction.Behaviors>
Now comes the cool part. The usage from the ViewModel is as simple as it gets:
1: Messenger mes = Messenger.Default;
2:
3: mes.Send(new GalaSoft.MvvmLight.Messaging.DialogMessage("Hey", res =>
4: {
5: Debug.WriteLine(res.ToString());
6: }), "mb1");
7: mes.Send(new GalaSoft.MvvmLight.Messaging.DialogMessage("Hey", res =>
8: {
9: Debug.WriteLine(res.ToString());
10: }), "mb2");
Using the messenger we send a weak message. The DialogBehavior shows a Dialog based on the how we set it in the view, and the response comes back to the ViewModel. Elegant, isn’t it?
The full code can be found here