Saturday, June 4, 2011

Closing ChildWindow In MVVM by Using Attached Property

In this post I will show you how to close the ChildWindow of Silverlight using Attached property in MVVM. Let us start with the example code. For this example I have created Silverlight project of template "Silverlight Navigation with Accent Color" application. I have added new ChildWindow in the view folder with the name UserInputForm and then UserInputFormViewModel in the ViewModel folder which is the used to set as the DataContext of the UserInputForm.
I have created one attached property which is used to bind in the ChildWindow as the property of the ChildWindow DialogResult is not dependency property so it can't be bind. So I have created DialogResult property which is bind in ChildWindow which you can see in the Image 1.


List 1

In the code in List 1 you can see that I have set the value of the dialog result in the OnSetDialogResultCallback. In the OnSetDialogResultCallback the dependencyObject is converted to ChildWindow and then check for the ChildWindow for null and if not null then set the value of the ChildWindow DialogResult.

Image 1

In the UserInputFormViewModel I have two commands save and the cancel which are bind to the save and cancel buttons on the UserInputForm. When ever user click either the save or cancel button I have set the value of the ModelDialogResult property true in case of save button and false in case of cancel button. In the Closed event handler of the UserInputForm which I have registered on the Home cs file I have check the DialogResult property. Hope You get idea of how to close the ChildWindow using MVVM.You can download source from here.

All and any comments / bugs / suggestions are welcomed !

7 comments:

Anonymous said...

Hi Asim,
apparently the link to the code sample is broken.
Could you please fix it?
Thanks
Roberto Dalmonte

Asim Sajjad said...

@Anonymous: I have fix the error for source code to download. Thanks for notifying the error.

Anonymous said...

Hi Asim,
great sample.
I suggest to make a subtle change in the code in order to make it full MVVM:
A HomeViewModel class



public class HomeViewModel : INotifyPropertyChanged
{
public HomeViewModel()
{
OpenChildCommand = new DelegateCommand(OpenChildWindow, CanExecute);
}

Anonymous said...

public class HomeViewModel : INotifyPropertyChanged
{
public HomeViewModel()
{
OpenChildCommand = new DelegateCommand(OpenChildWindow, CanExecute);
}
#region " INotifyPropertyChanged Interface "

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
#endregion

private Boolean? resultFromChild;

public Boolean? ResultFromChild
{
get { return resultFromChild; }
set
{
resultFromChild = value;
OnPropertyChanged("ResultFromChild");
}
}
private String resultMessage;

public String ResultMessage
{
get { return resultMessage; }
set
{
resultMessage = value;
OnPropertyChanged("ResultMessage");
}
}


public DelegateCommand OpenChildCommand { get; set; }

public void OpenChildWindow(object sender)
{

UserInputForm userInputForm = new UserInputForm();
userInputForm.Closed += new EventHandler(userInputForm_Closed);
UserInputFormViewModel dataContext = new UserInputFormViewModel();
userInputForm.DataContext = dataContext;
userInputForm.Show();
}

void userInputForm_Closed(object sender, EventArgs e)
{
ChildWindow senderChildWindow = sender as ChildWindow;
Boolean? result = senderChildWindow.DialogResult;
if (result.HasValue)
{
ResultMessage = result.Value ? "User pressed Save" : "User pressed Cancel";
}
else
{
ResultMessage = "The usere dismissed the window without making a choice";
}
}

public Boolean CanExecute(Object param)
{
return true;
}
}

Anonymous said...

in the home.xaml
Command="{Binding OpenChildCommand}
and the TextBlock:
Text="{Binding ResultMessage}

Asim Sajjad said...

@Anonymous: Thanks for your comments and good suggestion.

Anonymous said...

Thanks a lot !!
Very helpfull and easy to understand ;)