I like modal web dialogs, especially when they dim the background. Here is an example:
The background is dimmed, not clickable, and the dialog box is in the foreground. The work area is visible at first site, you must focus on the current content.
I wanted something similar in WPF. Here is my example application:
How it works?
There are two parts of the window. There is a DataGrid in the left pane and a ListBox in the right pane. The same data is loaded into both controls. When you select an item in the grid, the popup will appear over the grid, displaying the selected name. Clicking on the popup will close that. You can’t click through the popup. The right pane demonstrates that you can do anything with other controls. The popup resizes itself (drag the grid splitter to test it).
The key component to the popup control is the adorner class of WPF. The definition of adorners from MSDN:
An Adorner is a custom FrameworkElement that is bound to a UIElement. Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements. Rendering of an adorner is independent from rendering of the UIElement that the adorner is bound to. An adorner is typically positioned relative to the element to which it is bound, using the standard 2-D coordinate origin located at the upper-left of the adorned element.
There are three types of adorners:
Adorner: An abstract base class from which all concrete adorner implementations inherit.
AdornerLayer: A class representing a rendering layer for the adorner(s) of one or more adorned elements.
AdornerDecorator: A class that enables an adorner layer to be associated with a collection of elements.
The code of the popup adorner is the following:
You can set a content for the popup adorner, and that is all what I want. The VisualCollection is responsible for rendering the content on screen, and the ContentPresenter is responsible for storing the popup’s content.
There is a BackgroundShade user control to represent the dimmed background. The code is very short and simple:
I set the background to black at line 3 and I set the opacity of the control to 70% at line 4.
The Main window layout:
The Main window code:
The implementation details are in the comments. One interesting thing: I couldn’t simply bind the AdornedElement’s RenderSize to the shade’s width property, so it seems simpler to convert the AdornedElement to FrameworkElement and attach an event handler to the SizeChanged event.
You can download the source and the binaries from Google code, or you can simply browse source at the same place. Links are below.