12

Say I want to display some validation error to the user. In the MVVM pattern, I could have a label that is bound to some property on my viewmodel. But what if I wanted to show a message box while strictly adhering to the MVVM pattern. What would my viewmodel bind to, and how would it trigger a message box to be created/displayed?

Tilak
  • 30,108
  • 19
  • 83
  • 131
ConditionRacer
  • 4,418
  • 6
  • 45
  • 67
  • 1
    Your question is similar to this one http://stackoverflow.com/questions/1098023/how-have-you-successfully-implemented-messagebox-show-functionality-in-mvvm – Zack Jan 12 '13 at 19:56

2 Answers2

28

Have an interface IMessageBoxService as:

interface IMessageBoxService
{
    bool ShowMessage(string text, string caption, MessageType messageType);
}

Create a WPFMessageBoxService class:

using System.Windows;

class WPFMessageBoxService : IMessageBoxService
{
    bool ShowMessage(string text, string caption, MessageType messageType)
    {
        // TODO: Choose MessageBoxButton and MessageBoxImage based on MessageType received
        MessageBox.Show(text, caption, MessageBoxButton.OK, MessageBoxImage.Information);
    }
}

In your ViewModel accept IMessageBoxService as a constructor parameter and inject WPFMessageBoxService using DI/IoC.

In the ViewModel, use IMessageBoxService.ShowMessage to show the MessageBox.

ShowMessageCommand = new DelegateCommand (
    () => messageBoxService.ShowMessage(message, header, MessageType.Information)
);

Customize IMessageBoxService interface to your needs, and pick up a better name.

Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
Tilak
  • 30,108
  • 19
  • 83
  • 131
  • Interesting and simple solution! How do you center the MessageBox in the middle of your Window / Control ? It is not really usual in WPF to notify the View over a callback interface. Usually, the View get notified over binding. But the solution has the great advantage to be simple and straightforward! – jeromerg Apr 17 '15 at 11:51
  • @Tilak @Nautious and @Cameron MacFarland ., can you please help me out of this Error which says `Delegate 'System.Predicate' does not take 0 arguments` at `() => messageBoxService.ShowMessage(message, header, MessageType.Information);` – Mohammed Abrar Ahmed Aug 25 '16 at 11:12
  • change it to (s) => messageBoxService.ShowMessage(message, header, MessageType.Information) – Tilak Aug 25 '16 at 18:04
  • @Tilak When you pass IMessageBoxService as a parameter to view model contructor, you mean, for example create an instance of WPFMessageBoxService and pass this instance to the view model constructor? – Willy Jan 07 '19 at 17:27
  • @Tilak what is MessageType? Is it from System.Messaging assembly? – Willy Jan 07 '19 at 17:49
  • @Tilak Could you explain me or update your post to indicate what is DelegateCommand please? I have created a delegate and I am trying to call showMessage within my view model but without success.Also why are you using a lambda to call showMessage? Is not enough by doing messageBoxService.ShowMessage(...);? – Willy Jan 07 '19 at 18:47
  • Can somebody explain step where you need to inject "**WPFMessageBoxService using DI/IoC.**". What is this and how to do it - maybe some links ? – Lucy82 Jun 29 '20 at 11:29
  • Just curious - why interface? Wouldn't It be easier to just pass WPFMessageBoxService as parameter to Viewmodel constructor? Viewmodel still wouldn't know anything about the View + less code. – LuckyLuke82 Jul 14 '20 at 19:01
  • The correct MVVM solution would be to let the view observe the view model and then generate the messages. The message service should be a pure view object. The view model should never care about UI messages. MVVM is more than just avoiding UI controls in your view model. It's primarily about responsibilities. And it's not the responsibility of the view model to communicate with the user. Let the view model publish events that the view can convert into messages. – BionicCode Apr 10 '22 at 09:48
2

You could bind your messagebox control's visibility to the validation.

You will need a Bool To Visibility converter for this.

See here for using the built in converter: Binding a Button's visibility to a bool value in ViewModel

Community
  • 1
  • 1
zombiehugs
  • 717
  • 3
  • 10