A Behavior created by Haruhiro Isowa with assistance from Michael Washington.
Introduction
This article will show you how to use my PopUp Behavior that will launch a simple Yes/No Popup and explain how it works so you will be able to tune it to your needs. This PopUp should make creating PopUps in MVVM / VM style easier by generating the PopUp for you which will save you the time of creating a View and View Model for a Popup, remove the need for complexity shown by other solutions that uses messaging / services and so forth. This also allows designers to have some control to create PopUps without waiting for the programmers to make a View and VM for them.
What HisowaSimplePopUpBehavior Do
This is the PopUp that it generates, but you can customize by modding the code or by properties on behavior.

These are the Properties. (All properties under Miscellaneous are bindable).

Brushes are to set your background of the Buttons and PopUp Window, gradients, images, etc. are ok.
CustomParameter: object, you pass to the behavior and when the PopUp closes it will return that to you. You can pass selected object or ID, etc.
PopUpMessage: string, set the message for the PopUp
PopUpNoMessage: string, set the text on the No button
PopUpYesMessage: string, set the text on the Yes button
ReturnDialogResult: bool?, exposes the result of the PopUp (You can use two-way binding to pass back results. I used it to set IsChecked on a checkbox.
ReturnICommand: ICommand, The command to run when PopUp closes. It will pass in a dataholder class HisowaSimplePopUpBehaviorResult which will contain the DialogResult (bool?), DataContext of the Popup (Probably will not be used for this Popup Behavior ver), and InputParameter which is your CustomParameter you have set above.
By the properties of the behavior, you probably can guess what is going to happen. This Behavior will generate a simple Popup that you can set text, background values; pass in a parameter (probably useful to put the object in question); allow you to bind the DialogResult of the PopUp; and Most importantly run an ICommand when the PopUp Closes and passes you the DialogResult, DataContext, and the parameter you have passed so your ICommand can consume it.
Using my HisowaSimplePopUpBehavior
Start by opening a new Silverlight Application. Name it SimplePopUpBehaviorSample. Add my HisowaSimplePopUpBehavior class to your solution. Add a reference to System.Windows.Interactivity, and System.Windows.Controls. System.Windows.Interactivty is in Blend SDK. Build your project and open your MainPage.xaml in Expression Blend.
Before we can get started, we will need to have a View and ViewModel. Delete the MainPage.xaml in Blend. Add a new Item to the project by Right Clicking on the Project, select Add New Item. On the dialog, set User Control with ViewModel, name the file MainPage.xaml.

Open the MainPage.xaml.
Drag a button on the page. Then look for my behavior HisowaSimplePopUpBehavior and drag it on the Button.
.
Now Build and run it from Blend. You should now have a simple Popup. At this point, it's not doing anything cool.
ViewModel Code
We need to setup some code in the ViewModel. But before we get started, we will use John Papa's DelegateCommand.cs file. Get it from Delegate Command From John Papa.
Replace MainPageModel.cs code with this:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Data;
using System.ComponentModel;
using System.Windows.Input;
using HisowaPopUpBehaviors;
namespace SimplePopUpBehaviorSample
{
public class MainPageModel : INotifyPropertyChanged
{
public MainPageModel()
{
PopupSimpleResultCommand = new DelegateCommand
(PopupSimpleResult, CanPopupSimpleResult);
}
#region PopupSimpleResultCommand
public ICommand PopupSimpleResultCommand { get; set; }
public void PopupSimpleResult(object param)
{
HisowaSimplePopUpBehaviorResult _result =
(HisowaSimplePopUpBehaviorResult)param;
PopUpResult = _result.DialogResult;
if (_result.InputParameter != null)
{
Message = _result.InputParameter.ToString();
}
}
private bool CanPopupSimpleResult(object param)
{
return true;
}
#endregion
#region PopUpResult
private bool? _PopUpResult;
public bool? PopUpResult
{
get
{
return _PopUpResult;
}
set
{
_PopUpResult = value;
this.NotifyPropertyChanged("PopUpResult");
}
}
#endregion
#region Message
private string _Message;
public string Message
{
get { return _Message; }
private set
{
if (Message == value)
{
return;
}
_Message = value;
this.NotifyPropertyChanged("Message");
}
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
This is just a simple VM that has single ICommand that sets the Popup result to the properties (string Message, bool? PopupResult). It also implements INotifyPropertyChanged.
*Note: You might need to fix namespaces if you didn't use the same name for the project.
Now Build and let's get back to Blend.
Using the Behavior part2, with Properties
Now that we got all the groundwork done, we can start using the HisowaSimplePopUpBehavior to its full potential.
First, we will need to make a UI similar to this for this demo.

Bind these Text Values with Element Property Binding.
PopUpMessage: Your message Textbox's Text property
PopUpYes/NoMessage: Your Textbox's Text property
CustomParameter: Your Input Textbox's Text property (this allows object, it can be anything)

Bind ReturnDialogResult to Checkbox's IsChecked Property, two-way binding.

Build and Run. Now you should be able to change the text on your TextBox to what you typed in the textbox. The CheckBox should be checked if the popup was closed by the yes button.

Should look like this.
Now we would like to set ReturnICommand the most important part of the Behavior. To do this, Databind the ReturnIcommand to the PopUpSimpleResultCommand and Build.

To check that it's working, go back to Visual Studio and put a breakpoint somewhere in the ICommand you binded. Then Debug in Visual Studio.

Notice that Icommand is getting HisowaPopUpBehaviors class which holds the DialogResult, InputParameter(CustomParameter) and DataContext. You should be able to do a lot with these in your ICommand.
My Behavior Explained
In this section, I will explain the code of the Behavior. Most of them are dependency properties that allow the databindings, so I will skip over those.
This is the Invoke method, this gets called when the trigger is fired.
#region Invoke
protected override void Invoke(object parameter)
{
ChildWindow _childWindow = new ChildWindow();
_grid = new Grid();
_grid.Width = 300;
_grid.Height = 100;
_grid.ColumnDefinitions.Add(new ColumnDefinition()
{ Width = new GridLength(1, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition()
{ Width = new GridLength(1, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition()
{ Width = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition()
{ Height = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition());
_grid.RowDefinitions.Add(new RowDefinition());
TextBlock tbkMessage = new TextBlock();
tbkMessage.Text = PopUpMessage;
tbkMessage.SetValue(Grid.RowProperty, 0);
tbkMessage.SetValue(Grid.ColumnProperty, 0);
tbkMessage.SetValue(Grid.ColumnSpanProperty, 3);
_grid.Children.Add(tbkMessage);
Button btnYes = new Button();
btnYes.Content = PopUpYesMessage;
btnYes.SetValue(Grid.ColumnProperty, 0);
btnYes.SetValue(Grid.RowProperty, 1);
btnYes.Name = "btnYes";
btnYes.Click += new RoutedEventHandler(btnYes_Click);
_grid.Children.Add(btnYes);
Button btnNo = new Button();
btnNo.Content = PopUpNoMessage;
btnNo.SetValue(Grid.ColumnProperty, 2);
btnNo.SetValue(Grid.RowProperty, 1);
btnNo.Name = "btnNo";
btnNo.Click += new RoutedEventHandler(btnNo_Click);
_grid.Children.Add(btnNo);
_grid.Background = BackGroundColorParameter;
btnYes.Background = YesColorParameter;
btnNo.Background = NoColorParameter;
_childWindow.Content = _grid;
PopUp = _childWindow;
PopUp.Closing += new EventHandler<canceleventargs />(PopUp_Closing);
PopUp.Show();
}
#endregion
Basically it creates the UI, sets the event handlers and assigns the properties from the behavior such as background and message. This is where you will tweak to change the UI.
Now the event handling code for the Yes/No buttons.
#region BtnClicks
void btnNo_Click(object sender, RoutedEventArgs e)
{
RemoveButtonHandlers();
PopUp.DialogResult = false;
}
void btnYes_Click(object sender, RoutedEventArgs e)
{
RemoveButtonHandlers();
PopUp.DialogResult = true;
}
private void RemoveButtonHandlers()
{
Button btnYes = (Button)_grid.FindName("btnYes");
btnYes.Click -= new RoutedEventHandler(btnYes_Click);
Button btnNo = (Button)_grid.FindName("btnNo");
btnNo.Click -= new RoutedEventHandler(btnNo_Click);
}
#endregion
This sets the DialogResults which also closes the PopUp, and removes the event handlers.
Now the code for PopUpClosing event:
#region ChildwindowClosing
void PopUp_Closing(object sender, CancelEventArgs e)
{
PopUp.Closing -= new EventHandler<canceleventargs />(PopUp_Closing);
ReturnDialogResultCommand = PopUp.DialogResult;
if (ReturnICommand != null)
{
HisowaSimplePopUpBehaviorResult _result =
new HisowaSimplePopUpBehaviorResult();
_result.DialogResult = PopUp.DialogResult;
_result.DataContext = PopUp.DataContext;
_result.InputParameter = CustomParameter;
ReturnICommand.Execute(_result);
}
}
#endregion
All this does is remove the handler, get the Icommand from the dependency property, create my datacontainer HisowaSimplePopUpBehaviorResult, and run the Icommand passing the HisowaSimplePopUpBehaviorResult.
Lastly, the DataContainer HisowaSimplePopUpBehaviorResult class which is in the same file.
public class HisowaSimplePopUpBehaviorResult
{
public bool? DialogResult { get; set; }
public object DataContext { get; set; }
public object InputParameter { get; set; }
}
This is just a simple data holder.
Full Code
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.ComponentModel;
using System.Reflection;
namespace HisowaPopUpBehaviors
{
[System.ComponentModel.Description("Launches a Simple Popup on Event Trigger")]
public class HisowaSimplePopUpBehavior : TargetedTriggerAction<frameworkelement />,
INotifyPropertyChanged
{
private ChildWindow PopUp;
Grid _grid = new Grid();
public HisowaSimplePopUpBehavior()
{ }
#region CustomParameterProperty
public static readonly DependencyProperty CustomParameterProperty =
DependencyProperty.Register("CustomParameter", typeof(object),
typeof(HisowaSimplePopUpBehavior), null);
public object CustomParameter
{
get
{
return base.GetValue(CustomParameterProperty);
}
set
{
base.SetValue(CustomParameterProperty, value);
}
}
#endregion
#region ReturnDialogResultCommandProperty
public static readonly DependencyProperty ReturnDialogResultCommandProperty =
DependencyProperty.Register("ReturnDialogResultCommand", typeof(bool?),
typeof(HisowaSimplePopUpBehavior), null);
public bool? ReturnDialogResultCommand
{
get
{
return (bool?)base.GetValue(ReturnDialogResultCommandProperty);
}
set
{
base.SetValue(ReturnDialogResultCommandProperty, value);
this.NotifyPropertyChanged("ReturnDialogResultCommand");
}
}
#endregion
#region ReturnICommandProperty
public static readonly DependencyProperty ReturnICommandProperty =
DependencyProperty.Register("ReturnICommand", typeof(ICommand),
typeof(HisowaSimplePopUpBehavior), null);
public ICommand ReturnICommand
{
get
{
return (ICommand)base.GetValue(ReturnICommandProperty);
}
set
{
base.SetValue(ReturnICommandProperty, value);
}
}
#endregion
#region PopUpMessageProperty
public static readonly DependencyProperty PopUpMessageProperty =
DependencyProperty.Register("PopUpMessage", typeof(string),
typeof(HisowaSimplePopUpBehavior), null);
public string PopUpMessage
{
get
{
if (base.GetValue(PopUpMessageProperty) == null)
{
return "Are you sure?";
}
else
{
return (string)base.GetValue(PopUpMessageProperty);
}
}
set
{
base.SetValue(PopUpMessageProperty, value);
}
}
#endregion
#region PopUpYesMessageProperty
public static readonly DependencyProperty PopUpYesMessageProperty =
DependencyProperty.Register("PopUpYesMessage", typeof(string),
typeof(HisowaSimplePopUpBehavior), null);
public string PopUpYesMessage
{
get
{
if (base.GetValue(PopUpYesMessageProperty) == null)
{
return "Yes";
}
else
{
return (string)base.GetValue(PopUpYesMessageProperty);
}
}
set
{
base.SetValue(PopUpYesMessageProperty, value);
}
}
#endregion
#region PopUpNoMessageProperty
public static readonly DependencyProperty PopUpNoMessageProperty =
DependencyProperty.Register("PopUpNoMessage", typeof(string),
typeof(HisowaSimplePopUpBehavior), null);
public string PopUpNoMessage
{
get
{
if (base.GetValue(PopUpNoMessageProperty) == null)
{
return "No";
}
else
{
return (string)base.GetValue(PopUpNoMessageProperty);
}
}
set
{
base.SetValue(PopUpNoMessageProperty, value);
}
}
#endregion
#region BackgroundColor
public static readonly DependencyProperty BackGroundColorParameterProperty =
DependencyProperty.Register("BackGroundColorParameter",
typeof(System.Windows.Media.Brush), typeof(HisowaSimplePopUpBehavior), null);
public System.Windows.Media.Brush BackGroundColorParameter
{
get
{
return (System.Windows.Media.Brush)base.GetValue
(BackGroundColorParameterProperty);
}
set
{
base.SetValue(BackGroundColorParameterProperty, value);
}
}
#endregion
#region YesColor
public static readonly DependencyProperty YesColorParameterProperty =
DependencyProperty.Register("YesColorParameter",
typeof(System.Windows.Media.Brush), typeof(HisowaSimplePopUpBehavior), null);
public System.Windows.Media.Brush YesColorParameter
{
get
{
return (System.Windows.Media.Brush)base.GetValue
(YesColorParameterProperty);
}
set
{
base.SetValue(YesColorParameterProperty, value);
}
}
#endregion
#region NoColor
public static readonly DependencyProperty NoColorParameterProperty =
DependencyProperty.Register("NoColorParameter",
typeof(System.Windows.Media.Brush), typeof(HisowaSimplePopUpBehavior), null);
public System.Windows.Media.Brush NoColorParameter
{
get
{
return
(System.Windows.Media.Brush)base.GetValue(NoColorParameterProperty);
}
set
{
base.SetValue(NoColorParameterProperty, value);
}
}
#endregion
#region Invoke
protected override void Invoke(object parameter)
{
ChildWindow _childWindow = new ChildWindow();
_grid = new Grid();
_grid.Width = 300;
_grid.Height = 100;
_grid.ColumnDefinitions.Add(new ColumnDefinition()
{ Width = new GridLength(1, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition()
{ Width = new GridLength(1, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition()
{ Width = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition()
{ Height = new GridLength(1, GridUnitType.Star) });
_grid.RowDefinitions.Add(new RowDefinition());
_grid.RowDefinitions.Add(new RowDefinition());
TextBlock tbkMessage = new TextBlock();
tbkMessage.Text = PopUpMessage;
tbkMessage.SetValue(Grid.RowProperty, 0);
tbkMessage.SetValue(Grid.ColumnProperty, 0);
tbkMessage.SetValue(Grid.ColumnSpanProperty, 3);
_grid.Children.Add(tbkMessage);
Button btnYes = new Button();
btnYes.Content = PopUpYesMessage;
btnYes.SetValue(Grid.ColumnProperty, 0);
btnYes.SetValue(Grid.RowProperty, 1);
btnYes.Name = "btnYes";
btnYes.Click += new RoutedEventHandler(btnYes_Click);
_grid.Children.Add(btnYes);
Button btnNo = new Button();
btnNo.Content = PopUpNoMessage;
btnNo.SetValue(Grid.ColumnProperty, 2);
btnNo.SetValue(Grid.RowProperty, 1);
btnNo.Name = "btnNo";
btnNo.Click += new RoutedEventHandler(btnNo_Click);
_grid.Children.Add(btnNo);
_grid.Background = BackGroundColorParameter;
btnYes.Background = YesColorParameter;
btnNo.Background = NoColorParameter;
_childWindow.Content = _grid;
PopUp = _childWindow;
PopUp.Closing += new EventHandler<canceleventargs />(PopUp_Closing);
PopUp.Show();
}
#endregion
#region BtnClicks
void btnNo_Click(object sender, RoutedEventArgs e)
{
RemoveButtonHandlers();
PopUp.DialogResult = false;
}
void btnYes_Click(object sender, RoutedEventArgs e)
{
RemoveButtonHandlers();
PopUp.DialogResult = true;
}
private void RemoveButtonHandlers()
{
Button btnYes = (Button)_grid.FindName("btnYes");
btnYes.Click -= new RoutedEventHandler(btnYes_Click);
Button btnNo = (Button)_grid.FindName("btnNo");
btnNo.Click -= new RoutedEventHandler(btnNo_Click);
}
#endregion
#region ChildwindowClosing
void PopUp_Closing(object sender, CancelEventArgs e)
{
PopUp.Closing -= new EventHandler<canceleventargs />(PopUp_Closing);
ReturnDialogResultCommand = PopUp.DialogResult;
if (ReturnICommand != null)
{
HisowaSimplePopUpBehaviorResult _result =
new HisowaSimplePopUpBehaviorResult();
_result.DialogResult = PopUp.DialogResult;
_result.DataContext = PopUp.DataContext;
_result.InputParameter = CustomParameter;
ReturnICommand.Execute(_result);
}
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
public class HisowaSimplePopUpBehaviorResult
{
public bool? DialogResult { get; set; }
public object DataContext { get; set; }
public object InputParameter { get; set; }
}
}
Also see: HisowaModPopUpBehavior
This variation will allow you to use your own View and View Model and inject it into the popup.