DCSIMG
MVVM: How to show a dialog box from the ViewModel using Behaviors - אלעד כץ | Elad Katz
Sign in | Join | Help

אלעד כץ | Elad Katz

לגו של גדולים

MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Feb 06 2011, 07:19 PM על ידי eladkatz | ישנם 19 תגובות

Behaviors seems like the killer feature for every possible problem we used to have with MVVM. Thank god for WPF4 Smile

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

רשימת תגובות

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Monday, February 07, 2011 5:43 PM על ידי Mark  

The download link is broken.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Saturday, February 12, 2011 3:42 AM על ידי eladkatz  

@Mark

The link seems to be working as far as I can see.. What message are you getting?

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Sunday, February 20, 2011 2:01 AM על ידי Rupert  

I too am having issues downloading the code, in Internet Explorer just get a blank page, and in Chrome a 'broken link' message.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Friday, February 25, 2011 4:42 PM על ידי eladkatz  

You're both correct... I fixed the link.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Thursday, March 03, 2011 11:37 PM על ידי PWoodall  

I have tried to replicate your solution and ran into a lifecycle issue.  Whenever the view constructor is called, the OnAttached() method of the DialogBehavior is executed.  This registers the message type.

Where is the unregister?  If I navigate away and come back, the OnAttached() is executed and the message type is registered again.  This causes a message sent to execute the callback multiple times (similar to adding delegates to an event).

Is there a way to guarentee that the message type is only registered once?

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Tuesday, May 10, 2011 3:35 PM על ידי Leny  

Good idea, Will this work in Windows Phone project?

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Friday, May 20, 2011 11:19 PM על ידי Gary  

What about the case where the View(s) will be allocated dynamically?  For example, the application has 200 very sophisticated views that are each represented by a "Dialog" window (not necessarily a MessageBox).  The ViewModel would want to invoke 1 of the 200 Views at any given time.  If the ViewModel was aware of the View, it could simple create a new instance of the view (i.e., new MyView1()).  I'm looking for a more elegant way of the ViewModel to invoke/create views, where the views are allocated dynamically at runtime, but the ViewModel doesn't really know about the view.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Thursday, June 02, 2011 4:42 AM על ידי eladkatz  

@PWoodall - Sure, you just have to subscribe to the event Unloaded in the behavior and unregister all you messages. It's pretty straight forward from there.

@Gary - The solution i purposed is mainly targeted toward MessageBoxes and not Views. The more general View navigation is a different problem. The best solution for it that I know is the View-Switching technique you can find in Prism, which is loosely based on what i show here (it's based on Attached Properties. I might show that in a future post).

However, I strongly feel that creating more than 5-10 Windows in an application is a big mistake UX-wise. if all you need is View-Switching, however, then the prism's technique is best.

@Leny - no reason it shouldn't, though i didn't check it there.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Tuesday, August 09, 2011 1:08 PM על ידי Yasir  

this site is very nice.

# MVVM and Dialogs | DaedTech

פורסם בתאריך Wednesday, August 10, 2011 3:05 AM על ידי MVVM and Dialogs | DaedTech  

Pingback from  MVVM and Dialogs | DaedTech

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Sunday, October 30, 2011 7:36 PM על ידי Leon  

This is great!!! Just applied this to my project. Fantasic work.

THANKS!!!!

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Tuesday, November 15, 2011 1:19 AM על ידי David  

Looks like the link is still broken. I'd like to get a look at the whole solution.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Sunday, February 26, 2012 11:19 AM על ידי kytoni  

The download link is broken :( annoying

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Sunday, February 26, 2012 9:48 PM על ידי eladkatz  

@kitony

i fixed the download link.. thanks!

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Sunday, March 25, 2012 12:27 PM על ידי gintarassvalbonas@yahoo.com  

My way

           _mes.Send(new DialogMessage("Do you want to leave this channel?", res =>

           {

               if (res != MessageBoxResult.OK) return;

               Messenger.Default.Send("GoBackRequest");

               App.IrcClientInstance.RfcPart(Channel.Name);

           }) { Button = MessageBoxButton.OKCancel,Caption = ""}, "mb1");

       private void ShowDialog(DialogMessage dm)

       {

           var result = MessageBox.Show(dm.Content, dm.Caption, dm.Button);

           dm.Callback(result);

       }

       <i:Interaction.Behaviors>

           <Extra:DialogBehavior Identifier="mb1"  />

       </i:Interaction.Behaviors>

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Friday, November 16, 2012 12:16 AM על ידי Drardiawn  

hello

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Monday, April 08, 2013 9:29 PM על ידי Ingebynenty  

Hello. And Bye.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Tuesday, April 09, 2013 2:54 AM על ידי Eteddelocon  

Hello. And Bye.

# re: MVVM: How to show a dialog box from the ViewModel using Behaviors

פורסם בתאריך Sunday, April 21, 2013 9:13 PM על ידי ViekSeeds  

Nike Unencumbered TR Change 2 Shield broke of textile materials in strip with seasonal requirements, enhances the warmth and durability, and contemplative constituents, in <a href=www.nikeskorrea.se/>air max rea</a>

barren visibility when reflection and DWR (fast tone down stubborn) coating to achieve breathability while, contract out feet wilt in wet weather. Shoe upper welt on the by nature of the salaam suds enhances foot take up the cudgels for and stability.

Aspect ratio of the Nike Uninhabited shoe Trough conceive provides ductile like bare feet feel and sturdiness of multi-direction action while <a href=www.nikeskoroutlet.se/.../>air max 90 billigt</a>

retaining grip and shockproof column engrained in training shoes. Lightweight Phylite midsole can bring and masses of durability, which increments the expediency exponentially outsole, which significantly reduces the bulk of the shoe.

Tail and foot rubber grooves made of environmentally friendly materials, stop to lift its <a href=www.airmaxdam.se/>nike air max dam</a>

multi-directional feel on all kinds of track surfaces.

שלח תגובה

(שדה חובה) 
(שדה חובה) 
(אופציונלי)
(שדה חובה) 

Enter the numbers above: