Wintellect Blogs

Silverlight 3’s New Child Windows

29 Apr , 2009  

If you’ve worked with Silverlight 3, you may have noticed that Visual Studio’s Add New Item dialog includes an option for adding a “Silverlight Child Window” to your Silverlight project:

Silverlight Child Window

The new child window feature makes it easy to add modal dialogs to Silverlight applications. A child window derives from the new ChildWindow class, and its content is defined in XAML (of course!). So you can now embellish an application with modal popups containing rich content.

To see this feature in action, create a new Silverlight project and add a Silverlight child window to it. Replace “ChildWindow1.xaml” in the Name box with “ErrorDialog.xaml” and click OK. Visual Studio responds by adding two new files to your project: ErrorDialog.xaml, which contains the child window’s UI, and ErrorDialog.xaml.cs, which contains the child window’s code-behind class. You can display your new child window with two simple lines of code:

ErrorDialog dlg = new ErrorDialog();

dlg.Show();

When you do, an empty dialog appears with OK and Cancel buttons at the bottom. The content behind the dialog grays out and the user has to dismiss the dialog before doing anything else in the application.

You can add content to the dialog by declaring the content in ErrorDialog.xaml. You can also remove the OK and Cancel buttons by deleting the Button declarations. Here’s some content you can plug into ErrorDialog.xaml to customize the dialog’s appearance:

<StackPanel Orientation=”Vertical”>

  <Image Source=”Images/UnhappyFace.png” Stretch=”None” Margin=”8″ />

  <TextBlock Text=”An unforeseen error has occurred. Please contact a system administrator or, better yet, use our competitor’s Web site until we get the problem resolved.” TextWrapping=”Wrap” />

</StackPanel>

<Button x:Name=”CloseButton” Content=”Close” Click=”CloseButton_Click”

  Width=”75″ Height=”23″ HorizontalAlignment=”Center” Margin=”16″

  Grid.Row=”1″ />

Add the following line of code to ErrorDialog’s constructor to customize the title bar:

this.Title = “Error”;

And add the following method to the ErrorDialog class to handle clicks of the Close button:

private void CloseButton_Click(object sender, RoutedEventArgs e)

{

    this.DialogResult = false;

}

When you display the dialog, here’s what you get:

Child Window 

It’s not earth-shaking, but it’s certainly nice to have the ability to dress up your apps with genuine modal dialogs.

This is all rather straightforward, but certain aspects of a child window’s operation merit further explanation. For example, the ChildWindow class has a Close() method that you can call to close a dialog, but my CloseButton_Click handler, which is patterned after the click handlers provided by Visual Studio, doesn’t call it. DialogResult’s setter calls Close for you, so simply assigning a value to the DialogResult property is sufficient to close the dialog.

Another aspect of child windows that may not be obvious is that Show() is an asynchronous call. That is, it doesn’t wait for the dialog to be dismissed; it returns immediately. That’s why Show() returns void rather than a DialogResult. If you want to know how the dialog was dismissed (that is, what the DialogResult value is once the dialog is closed), you handle the dialog’s Closed event and check DialogResult there:

ErrorDialog dlg = new ErrorDialog ();

dlg.Closed += new EventHandler(OnErrorDialogClosed);

dlg.Show();

 

private void OnErrorDialogClosed(object sender, EventArgs e)

{

    ErrorDialog dlg = (ErrorDialog)sender;

    bool? result = dlg.DialogResult;

}

Note that DialogResult is a nullable bool, so it isn’t necessarily set to true or false.

One last item to consider is how to retrieve input from a child window that allows the user to input data. Generally you build public properties into the dialog class and transfer values from the dialog’s input controls into these properties in the OK button’s click handler. After the dialog is dismissed, you then retrieve the user input from the dialog properties. For example, suppose a child-window class named InputDialog contains a TextBox named “InputBox” so the user can enter text. You could do this in the dialog class:

public string Input { get; set; }

 

private void OKButton_Click(object sender, RoutedEventArgs e)

{

    this.Input = InputBox.Text;

    this.DialogResult = true;

}

And after the dialog is dismissed, you could do this to find out what the user typed into the TextBox:

private void OnInputDialogClosed(object sender, EventArgs e)

{

    InputDialog dlg = (InputDialog)sender;

    bool? result = dlg.DialogResult;

 

    if (result.HasValue && result.Value)

    {

        string input = dlg.Input;

    }

}

This is how we used to retrieve input from dialog boxes in MFC. And now, 15 years later, it comes in handy again. I guess useful patterns never die!


  • http://blog.inphonite.com Anonymous

    I had to write a very similar function for SL2 – can’t wait to kick SL3’s wheels. Can the window leave the scope of the browser (or application in the case of an out-of-browser scenario?) Or will it still be confined to the primary grid/canvas? Thanks!

  • jprosise

    It’s still confined. Sigh.

  • Anonymous

    I really hope that its not confined by the time its released – it makes it worthless I will have to continue with my hack using the bridge to javascript.

    Also it would be good to have other window modes – e.g. always on top, modeless.

  • Anonymous

    Is it possible to change the behavior of the ChildWindow the way it opens and closes? It kind of jumps out at you and disappears just as dramatically. I don’t think this effect is appropriate in the business application when you open hundreds of windows a day.

  • http://www.christianwirth.de Anonymous

    Nice! That was overdue!

  • Anonymous

    Thanks!! Very Usefull

  • Anonymous

    Very Good Article!

  • http://www.dotnetkicks.com/silverlight/Silverlight_3_s_New_Child_Windows Anonymous

    You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  • Anonymous

    Is there a way to get a ChildWindow and/or its buttons to respond to an Escape keypress (for a Cancel button) and to respond to an Enter keypress (for an OK button)?

    Thank you in advance, and thanks for writing the article.

  • Anonymous

    John, You can always refactor the control itself..
    Take a look at tims page:
    http://timheuer.com/blog/archive/2009/05/10/silverlight-childwindow-non-modal-refactor.aspx

    /Roy

  • Anonymous

    Hi I want to open a PDF document in the child window, can this be done?? I mean the child window when popped up will have only the PDF document that can be scrolled vertically.

  • Anonymous

    Hi!
    Great Article!

    I was wondering how one can access resource files in the child window class?

    Im able to access it normally through a page in the xaml by using the tag but it doesnt work in a child window and I need it for localization.

    Thanks!

  • Anonymous

    excellent article, exactly what i was looking for. thx!

  • Anonymous

    thank so much! very helpful article!

  • Anonymous

    Very useful article!
    Thanks

  • Anonymous

    Excellent shortest trick. Bundle of thanks…

  • Anonymous

    I gotta do this in Silverlight XAML VB! How do i open the child window in VB?

  • Anonymous

    Thx! Really helpfull post!
    “One last item to consider is how to retrieve input from a child window that allows the user to input data.”
    private void OnInputDialogClosed(object sender, EventArgs e)
    {
    InputDialog dlg = (InputDialog)sender;
    bool? result = dlg.DialogResult;
    if (result.HasValue && result.Value)
    {
    string input = dlg.InputBox.Text; //it’s work too
    }
    }

  • http://www.78thplace.com/blog/post/Silverlight-ChildWindow-Modal-Dialog-101.aspx Anonymous

    Silverlight ChildWindow / Modal Dialog 101

  • Anonymous

    is there a busyIndicator for childwindows to use?

  • http://www.isozworld.com Anonymous

    Thank you very much for your great post Jeff.

  • Anonymous

    Thanks a lot.
    i was stuck for hours till trying to figure out whats wrong with my code, until i read here that Show() is an asynchronous call.

  • Anonymous

    Hi, is there a way to call the child window in synchronous way?

    Regards

  • Anonymous

    http://www.wintellect.com/CS/bhttp://www.wintellect.com/CS/blogs/JpegImage.aspxlhttp://www.wintellect.com/CS/blogs/JpegImage.aspxogs/JpegIhttp://www.wintellect.com/CS/blogs/JpegImage.aspxmaghttp://http://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspxwwhttp://www.winthttp://www.wintellect.com/CS/blogs/JpegImage.aspxellect.com/http://www.wintellect.com/http://www.wintellect.com/CS/blogs/JpegImage.aspxCS/blogs/JpegImage.aspxCS/blogs/Jphttp://www.wintellect.com/CS/blogs/JpegImage.http://www.wintellect.com/CS/blogs/JpegImage.aspxaspxegImage.aspxhthttp://www.wintellect.com/CS/blogs/JpegImage.aspxtp://www.htthttp://www.wintellect.com/CS/blogs/JpegImage.aspxp://www.wintellect.com/CS/blogs/JpegImage.aspxwintellect.com/CS/blogs/JpegImhttp://www.wintellect.com/CS/blogs/JpegImage.aspxage.aspxw.http://www.wintellect.com/CS/blogs/JpegImage.aspxwintellhttp://www.wintellect.com/CS/blogs/JpegImage.ahttp://www.wintellect.com/CS/blhttp://www.wintellect.com/CS/blogs/JpegImage.aspxogs/JpegImage.aspxspxecthttp://www.winhttp://www.wintellect.com/CS/blogs/JpegImage.aspxtellect.com/CS/blogs/JpegIhttp://www.wintellect.com/CS/blogs/JpegImage.ahttp://www.wintellect.com/CS/blogs/JpegImage.aspxspxmaghttp://www.wintellect.com/CS/blogs/JpegImage.aspxe.aspx.com/CS/http://www.wintellect.com/CS/blogs/JpegImage.aspxblogs/Jpeghttp://www.wintellect.com/CS/blogs/JpegImage.aspxImage.ashttp://http://www.wintellect.com/CS/blogs/JpegImage.aspxwhttp://www.wintellect.com/CS/blogs/JpegImage.aspxww.wintellect.com/CS/blogs/JpegImage.aspxphttp://wwhttp://wwhttp://www.wintellect.cohttp://www.wintellect.com/CS/blogs/JpegImage.aspxm/CS/blogs/JpegImage.ahttp://www.wintellect.com/CS/blogs/JpegImage.aspxspxw.wintellect.com/CS/blogs/JpegImage.aspxw.wintellect.com/CS/bloghttp://www.wintellect.com/CS/blogs/JpegImage.aspxs/JpegImage.aspxxe.aspxhttp://wwhttp://www.wihttp://www.wintellechttp://wwwhttp://www.wintellehttp://www.wintellect.com/CS/blogs/JpegImage.aspxct.com/CS/blogs/JpegImage.aspx.wintellect.com/CS/blogs/JpegImage.aspxt.com/CS/blogs/JpegImage.aspxnhttp://whttp://www.wintellect.http://www.wintellect.com/CS/blogs/JpegImage.aspxcom/CS/blogs/JpegImage.aspxww.wintellect.com/CS/blogs/JpegImage.aspxtehttp://www.wintellect.com/CS/blogs/JpegImage.aspxllect.com/CS/blogs/http://www.wintellect.com/CS/blhttphttp://www.winthttp://www.wintellect.com/CS/blogs/JpegImage.aspxellect.com/CS/blogs/JpegImage.aspx://www.wintellect.com/CS/blogs/JpegImage.aspxogs/JpegImage.aspxJphttp://www.wintellect.com/CS/blogs/JpegImage.aspxegImage.aspxw.wintellect.com/http://www.wintellect.cohttp://whttp://www.wintellect.com/CS/blogs/JpegImage.aspxwhttp://www.wintellect.com/CS/blogs/JpegImage.aspxw.wintellect.com/CS/blogs/JpegImage.aspxm/CS/blogs/JpegImage.aspxCS/blogs/JpegImahttp://www.winhttp://www.wintehttp://www.wintellect.com/CS/blogs/JpegImage.aspxllect.com/CS/blogs/JpegImage.aspxtellect.cohttp://www.wintellect.com/CS/blogs/JpegImage.aspxm/CS/blogs/JpegImage.aspxge.aspxhttp://wwwhttp://www.wintellect.com/CS/blogs/JpegImage.aspx.wintellect.com/CS/blogs/JpegImage.aspxhhttp://www.wintellect.com/CS/blogs/JpegImage.aspxttp://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImaghttp://www.wintellect.com/CS/blogs/JpegImage.aspxe.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintelhttp://www.wintellect.com/CS/blogs/JpegImage.aspxlect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspxhttp://www.wintehttp://www.wintellect.com/CS/blogs/JpegImage.aspxllect.com/CS/blogs/JpegImage.aspxhttp://www.wintellect.com/CS/blogs/JpegImage.aspx

  • http://ilegales14 Anonymous

    nada q quiero misica para virtual dj