Silverlight Behavior : HisowaModPopUpBehavior
Aug
30
Written by:
8/30/2010 9:40 PM
This is a different variation of my previous PopUp Behavior. If you are unfamiliar with my previous one visit the link, this is built on it and assumes you get the general idea.
This one will allow you to make you own View and View Model and inject it into my generated pop up. Note this one will create the OK/Cancel button like the previous one.
Sample
Sample App, The second section.
Sample project
Code only.
Notes
- This variation will allow you to use your own View and View Model
- This behavior will create its own Yes / No button (more on reasoning later)
- Like the previous it will return the Result container class, HisowaModPopUpResult
- HisowaModPopUpResult will pass a DataContext, which is the DataContext of your View Model.
- I will explain you the the parts of the code that have changed so you will be able to customize it / fix it.
In Action

Like the last one, it is attached to the button. The behavior will open the Pop up on button click event, no code behind.

The Calender control values will be passed to Main View Model by the DataContext in HisowaModPopUpResult.
How do I use this one?
1) Add a reference to System.Windows.Interactivity, and System.Windows.Controls. System.Windows.Interactivty is in Blend SDK.
2) Add my HisowaModPopUpBehavior.cs to your project.
3) Create a View + View Model
3a) Open your project in Blend.
3b) Right click your project, Select Add New Item…

3c) Select UserControl with ViewModel call it View1.xaml

3d) Make a View Without the OK / Cancel. (here’s mine)
Its default canvas, and size to auto. Be sure to set a actual pixel if you are using canvas. The way canvas lays out control is by Margin of the closest X / Y border, which will lead to weird UI. (specifically it will try to fit it in as small of space as possible as long as it meets the Margin, for mine the margin for the left calendar is left and top, right calendar has it for right and bottom. This results in overlapping controls.)
3e) Build >> go back to Visual studio and make your ViewModel. here’s mine.
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4: using System.Windows.Data;
5: using System.ComponentModel;
6:
7: namespace SimplePopUpBehaviorSample
8: {
9: public class View1Model : INotifyPropertyChanged
10: {
11: public View1Model()
12: {
13:
14: }
15:
16: #region DateStartValueProperty
17:
18: private DateTime _DateStartValueProperty;
19: public DateTime DateStartValueProperty
20: {
21: get
22: {
23: return this._DateStartValueProperty;
24: }
25: set
26: {
27: this._DateStartValueProperty = value;
28: this.NotifyPropertyChanged("DateStartValueProperty");
29: }
30: }
31: #endregion
32:
33: #region DateEndValueProperty
34: private DateTime _DateEndValueProperty;
35: public DateTime DateEndValueProperty
36: {
37: get
38: {
39: return this._DateEndValueProperty;
40: }
41: set
42: {
43: this._DateEndValueProperty = value;
44: this.NotifyPropertyChanged("DateEndValueProperty");
45: }
46: }
47: #endregion
48:
49: #region INotifyPropertyChanged
50: public event PropertyChangedEventHandler PropertyChanged;
51:
52: private void NotifyPropertyChanged(String info)
53: {
54: if (PropertyChanged != null)
55: {
56: PropertyChanged(this, new PropertyChangedEventArgs(info));
57: }
58: }
59: #endregion
60: }
61: }
Only properties to store dates
3f) build
4) Go back to Blend and Bind your Calendar selected date to the View Model Property, (Two-way).

5) Go Back to Visual Studio and Add ICommand to run when the PopUp is Closed on the Main View Model.
1: #region PopupModResultCommand
2: public ICommand PopupModResultCommand { get; set; }
3: public void PopupModResult(object param)
4: {
5: //cast to my DataContainer
6: HisowaModPopUpBehaviorResult _result = (HisowaModPopUpBehaviorResult)param;
7:
8: //get the dialogResult
9: View1Model vm = (View1Model)_result.DataContext;
10:
11: //get the input if exists
12: if (vm != null)
13: {
14: DateStart = vm.DateStartValueProperty;
15: DateEnd = vm.DateEndValueProperty;
16: }
17: }
18:
19: private bool CanPopupModResult(object param)
20: {
21: return true;
22: }
23: #endregion
24:
25:
Notice it returns HisowaModPopUpResult and I get the datacontext from it. Its cast to View1Model and I get the dates from it.
6) Add the Properties to store dates
1: #region DateStart
2: private DateTime _DateStart;
3: public DateTime DateStart
4: {
5: get { return _DateStart; }
6: private set
7: {
8: if (DateStart == value)
9: {
10: return;
11: }
12: _DateStart = value;
13: this.NotifyPropertyChanged("DateStart");
14: }
15: }
16: #endregion
17:
18: #region DateEnd
19: private DateTime _DateEnd;
20: public DateTime DateEnd
21: {
22: get { return _DateEnd; }
23: private set
24: {
25: if (DateEnd == value)
26: {
27: return;
28: }
29: _DateEnd = value;
30: NotifyPropertyChanged("DateEnd");
31: }
32: }
33: #endregion
7) Go back to your Main View, and Drag my Behavior on a Control.
8) Set your CustomUI to the View you have created

9) Databind the ReturnICommand to the ICommand we created.

10) Make a UI that can use the Properties that got updated by ICommand. (mine is the 2 dates). And Databind.

11) Build, Run, Test.
Behavior Code Explained.
1: using System;
2: using System.Windows;
3: using System.Windows.Controls;
4: using System.Windows.Input;
5: using System.Windows.Interactivity;
6: using System.ComponentModel;
7: using System.Reflection;
8:
9: namespace HisowaPopUpBehaviors
10: {
11: [System.ComponentModel.Description("Launches a Popup with custom UI on Event Trigger")]
12: public class HisowaModPopUpBehavior : TargetedTriggerAction, INotifyPropertyChanged
13: {
14: private ChildWindow PopUp;
15: Grid _grid = new Grid();
16:
17: private StackPanel PopUpContent;
18:
19: //constructor
20: public HisowaModPopUpBehavior()
21: { }
22:
Pretty standard stuff, except it has a ChildWindow, Grid, and StackPanel as class variables.
1: #region CustomUI
2: public static readonly DependencyProperty CustomUIProperty = DependencyProperty.Register("CustomUI", typeof(UserControl), typeof(HisowaModPopUpBehavior), null);
3:
4: public UserControl CustomUI
5: {
6: get
7: {
8: return (UserControl)base.GetValue(CustomUIProperty);
9: }
10: set
11: {
12: base.SetValue(CustomUIProperty, value);
13: }
14: }
15: #endregion
16:
Dependency property to set your User Control to the Behavior.
1: protected override void OnAttached()
2: {
3: base.OnAttached();
4:
5: StackPanel stpnl = new StackPanel();
6: stpnl.Children.Add(CustomUI);
7:
8: stpnl.SetValue(Grid.RowProperty, 0);
9: stpnl.SetValue(Grid.RowSpanProperty, 2);
10: stpnl.SetValue(Grid.ColumnProperty, 0);
11: stpnl.SetValue(Grid.ColumnSpanProperty, 3);
12:
13: PopUpContent = stpnl;
14: }
This is where your usercontrol is set into the Behavior, on attached it will jam you usercontrol into a stackpanel, which sits in a Grid (that holds the whole window). This is where you can tweak it to your needs for the layout.
1:
2: #region ChildwindowClosing
3:
4: //Runs an Icommand when the Popup is closing
5: //you can change what it passes to Icommand to whatever you like
6: //be sure that your method can consume them
7:
8:
9: void PopUp_Closing(object sender, CancelEventArgs e)
10: {
11: PopUp.Closing -= new EventHandler(PopUp_Closing);
12:
13: ReturnDialogResultCommand = PopUp.DialogResult;
14:
15: if (ReturnICommand != null)
16: {
17: HisowaModPopUpBehaviorResult _result = new HisowaModPopUpBehaviorResult();
18: _result.DialogResult = PopUp.DialogResult;
19: _result.DataContext = ((FrameworkElement)CustomUI.Content).DataContext;
20: _result.InputParameter = CustomParameter;
21:
22: ReturnICommand.Execute(_result);
23: }
24:
25: PopUp.Content = null;
26: }
27:
28: #endregion
This is the code it runs when the childwindow is closing. Sets the dialog result property on the Behavior, creates a the Container HisowaModPopUpBehaviorResult to store the result, the data context of the UI you injected, and the input parameters. Pretty much the same as the “simple” except the datacontext is actually being used to pass in your UI’s datacontext.
1: public class HisowaSimplePopUpBehaviorResult
2: {
3: public bool? DialogResult { get; set; }
4: public object DataContext { get; set; }
5: public object InputParameter { get; set; }
6: }
The dataContainer that gets passed.
Why does it make the Yes, No button for me.
The simple explanation for this is by doing it this way I don’t make your View model have a reference to the Childwindow to set dialog result to close it or make you write code behind. This idea behind this popUp behavior was so A) you do not have to make crazy code with services, messaging or B) allow you to have popUp without your code behind or View Model have a reference to your childwindow.
1 comment(s) so far...
Re: Silverlight Behavior : HisowaModPopUpBehavior
Great! All my Popup worries are over :) I pointed my Popup article on CodeProject to this one.
By ADefWebserver on
9/1/2010 7:54 PM
|