Click here to Skip to main content
Click here to Skip to main content

(Extended) Modal Window in Silverlight

, 2 Apr 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
An extension of the code submitted in the article: "Modal Window in Silverlight". This extension wraps the hosted control in a window frame that provides various modal features.


Knowm Ercy's article Modal Window in Silverlight provided a nice way to display a Silverlight UserControl in a way that looks and feels modal. Here at ProModel, Inc. we were interested in this functionality (which is not natively available within Silverlight at the moment) and its use in our Silverlight based applications. Using Knowm's article as a starting point, we put together an extension that "wraps" the hosted UserControl inside a window frame which provides for resizing, moving, maximizing, and many of the other features enjoyed with traditional modal Windows forms.

This code is presented "as is" and we are aware of a number of improvements that can and should be made. However, given our in-house time constraints and the lack of a similar modal solution out there (a free one anyway), we decided to make this source available for improvement by anyone who's up for the challenge.


Although we've made some departures from the original architecture, it is basically as we found it, just extended, so reading Knowm Ercy's article Modal Window in Silverlight should prove helpful in understanding the code.

There are two classes that work to provide the basic modal display:

  • Modal

    A simple class containing the popup control which host the "modal" form and provides basic show/hide functionality.

  • ModalHost

    A class that hosts the UserControl which is to be displayed modally. This class renders a "background canvas" that covers the entire browser window and prevents interaction with anything other than the hosted control, giving the impression that the hosted control is modal. Also, the ModalHost class provides basic mouse drag functionality such that the hosted control can be moved if a mouse drag occurs on its surface.

Each of the two modal display classes contained in our library (ModalControl, WindowedModalControl) contain an instance of each of these class. In the case of ModalControl, the simple base classes are used (as with Knowm's provided project). In the case of WindowedModalControl, each class is derived to provide the extended functionality.

Here is a summary of the functionality provided in the derived classes:

  • WindowedModal (derived from Modal)

    All that is done in this child class is a simple override of a method that sets the ModalHost instance within the Modal class. This allows us to insert our custom ModalHost (WindowedModalHost).

    internal class WindowedModal : Modal
    #region Method Declarations
    protected override void SetHost(IModal ctrl, bool useCanvasPainting)
        _host = new WindowedModalHost(ctrl, useCanvasPainting);
  • WindowsModalHost (derived from ModalHost)

    This class overrides a few basic ModalHost behaviors/adds some simple functionality:

    1. Provides RestoreState property which keeps track of whether or not the WindowedModalControl is maximized.
    2. Overrides the CenterWindow() method so that it takes the RestoreState into account.
    3. Overrides mouse events to prevent the base class from taking any action.
    public override void CentreWindow()
        double dblX = 0.0, dblY = 0.0;
        UserControl modal = _modal as UserControl;
        if (RestoreState == RestoreState.Unmaximized)
            // width
            if (_modal != null && !double.IsNaN
    		(WindowHelpers.GetControlSize(modal).Width) &&
            dblX = ((Application.Current.Host.Content.ActualWidth - 
    			WindowHelpers.GetControlSize(modal).Width) / 2);
            modal.SetValue(Canvas.LeftProperty, dblX);
            // height
            if (_modal != null && !double.IsNaN
    		(WindowHelpers.GetControlSize(modal).Height) &&
            dblY = ((Application.Current.Host.Content.ActualHeight - 
    			WindowHelpers.GetControlSize(modal).Height) / 2);
            modal.SetValue(Canvas.TopProperty, dblY);
    protected override void OnMouseLeftButtonDown
    		(object sender, MouseButtonEventArgs e)
        // prevent the base class from taking action
    protected override void OnMouseMove(object sender, MouseEventArgs e)
        // prevent the base class from taking action

The WindowedModalControl class provides the major functional extensions to Known's original work. This includes:

  1. Managing the placement of the hosted UserControl inside of a window frame
  2. Support for Maximize/Restore
  3. Support for display of window as both resizing and non-resizing
  4. A title bar with image and auto-truncating text caption
  5. Built-in OK, Cancel, Apply button support
  6. Auto-sizing of the hosted UserControl
  7. Usage of custom brushes for form header, background and text

Using the Code

Simply hosting your UserControl within the WindowedModalControl will look like this:

public void ShowWindowedModal(DialogClose callback, Panel panel)
     bool useCanvasPainting = true; 	// whether of not the non-modal space 
				// is darkened partially
     WindowedModalControl wmc = new WindowedModalControl
				(callback, MsgBoxButtons.OKCancelApply);
     TestUserControl tc = new TestUserControl();
     wmc.HostedControl = tc;
     wmc.ShowModal(panel, useCanvasPainting);

This sample makes use of some of the more advanced features:

public void ShowWindowedModal(DialogClose callback, Panel panel)
    bool useCanvasPainting = true; 	// whether of not the non-modal space 
				// is darkened partially
    WindowedModalControl wmc = new WindowedModalControl
				(callback, MsgBoxButtons.OKCancelApply);
    TestUserControl tc = new TestUserControl();
    wmc.TitleBarBrush = Resources["ModalHeaderBrush1"] as Brush;
    wmc.FormBackgroundBrush = Resources["ModalBrush1"] as Brush;
    wmc.TitleImage = _titleImage;
    wmc.HostedControl = tc;
    wmc.ShowModal(panel, useCanvasPainting);
    wmc.AllowResizing = true;
    wmc.AllowMaximize = true;
    wmc.TitleBarText = "It's a Working Title...and it truncates if need be";

The provided source comes with a demo application that has source code samples alongside run-time examples. A compiled help file is also included.

Special Thanks

To Knowm Ercy for the work he put into his article.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Ed Dupas

United States United States
No Biography provided

Comments and Discussions

BugHow can i change the style of ok,cancel or apply button Pinmemberdharmesh02420-Feb-12 14:32 
GeneralModal program flow PinmemberAndrusM7-Apr-09 9:07 
GeneralRe: Modal program flow Pinmemberedupas7-Apr-09 9:40 
GeneralRe: Modal program flow PinmemberAndrusM8-Apr-09 0:00 
How we can add program flow stopping to this code ?
How to suspend main code execution using sleep() and continue its execution after reply in message box?
In this case it can used from DataGrid SelectionChanged event to prompt for row save. If execution is not suspended, SelectionChanged event completes and DataGrid saves row without waiting for user input.
It is not possible to refactor application code to prevent this situation.

GeneralIt would be nice... PinprotectorMarc Clifton2-Apr-09 2:31 
GeneralRe: It would be nice... PinmemberEd Dupas2-Apr-09 6:12 
GeneralRe: It would be nice... PinprotectorMarc Clifton2-Apr-09 6:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150305.1 | Last Updated 2 Apr 2009
Article Copyright 2009 by Ed Dupas
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid