Silverlight 3 introduced a very useful control called a ChildWindow. This is a "modal" dialog box that can contain whatever content you give it and it floats above the rest of the application inside a Popup control. I say "modal" because unlike ShowDialog in WPF or Windows Forms, showing a ChildWindow via the Show method returns immediately, but it does disable the application’s RootVisual which prevents the user from interacting with the rest of the application while the window is showing.
As cool as this control is, I have always been pretty disappointed in the default behavior and look and feel of the ChildWindow class. For example, the animation as it opens and closes is very unnatural and distracting. The overlay that "dims" the rest of the application successfully indicates the modal nature of the control, but it’s too strong I think. In fact I’m fine with just the normal "grey out" that happens when the RootVisual is disabled.

A while back I had created a pretty lame ChildWindow template that kinda sorta looked like a Windows 7 Aero window. It was a half-hearted attempt but it looked a lot better than the above. But then I saw a question on StackOverflow asking about creating an Aero glass style window and I decided to revisit the problem and try to come up with something decent.
The first thing to note when trying to customize the ChildWindow template is that you probably ought to start from scratch. The default template is like an onion of nested grids and borders and panels, none of which have any particular significance to the control other than the border named Chrome. This is what ChildWindow uses to handle dragging. Although as I’ll discuss shortly, I think there’s some bugs there.

My ChildWindow template looks like the one in the above screen shot. I tried very hard to make the template "cooperate" with the style. That is whenever possible, I use values from the style or directly applied to the control instead of hard coding colors, paddings, etc in the template which are hard to tweak.
For example, if you want to create more glass area around the white content area, just increase the Padding of the ChildWindow. Padding, of course, does not have to be uniform. You could give it a larger padding on the bottom to make room for Windows Media Player-style controls.
There’s a couple of caveats though…
- There is no blur! I originally wanted to blur the elements underneath the "glass" areas but I found this to be a lot more difficult than I thought. A blur effect only applies the blur to its associated element and visual children. Since the stuff I want it to blur is only showing through as a result of opacity, the blur has no effect. I suspect there’s a way to do this using a WritableBitmap but I haven’t gone down that rabbit hole just yet.
- It doesn’t have any open/close transition animations. I took those out on purpose but now I think a very subtle transition is needed to look more natural than the jarring animation from the default style.
- It doesn’t currently have any visual states defined on the close button which I took out for the sake of keeping the XAML clean for the example. But you can pretty much drop in the transitions from the default template to get that back.
- Dragging the ChildWindow appears to be jerky for some reason. I think this is a bug in the way ChildWindow handles dragging because Jeff Wilcox’s customized template has the same problem when one of his readers enabled dragging on his Zune style template.
Finally, there are a number of blog posts out there about how to hack the ChildWindow to be non-modal. Tim Huer has an excellent post about this. I have not tried but I don’t see any reason why my template could not also be applied in conjunction with those methods.
To grab the ResourceDictionary that contains the template, click the Show Source link below.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<Style x:Key="AeroWindowCloseButton" TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFEEB3AC" Offset="0.009"/>
<GradientStop Color="#FFDA8578" Offset="0.402"/>
<GradientStop Color="#FFC64D38" Offset="0.459"/>
<GradientStop Color="#FFC84934" Offset="0.598"/>
<GradientStop Color="#FFD48671" Offset="0.885"/>
<GradientStop Color="#FFE8BBAE" Offset="0.943"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="#FF5E5E5E"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="Width" Value="45"/>
<Setter Property="Height" Value="20"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="0,0,3,3">
<Path
Fill="{TemplateBinding Foreground}"
Width="11"
Height="10"
Stretch="Fill"
Data="F1 M 6.742,3.852 L 9.110,1.559 L 8.910,0.500 L 6.838,0.500 L 4.902,2.435 L 2.967,0.500 L 0.895,0.500 L 0.694,1.559 L 3.062,3.852 L 0.527,6.351 L 0.689,7.600 L 2.967,7.600 L 4.897,5.575 L 6.854,7.600 L 9.115,7.600 L 9.277,6.351 L 6.742,3.852 Z">
<Path.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF313131" Offset="1"/>
<GradientStop Color="#FF8E9092" Offset="0"/>
</LinearGradientBrush>
</Path.Stroke>
</Path>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AeroWindow" TargetType="s:ChildWindow">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="#FF5E5E5E"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="OverlayBrush" Value="Transparent"/>
<Setter Property="OverlayOpacity" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="TabNavigation" Value="Cycle"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="s:ChildWindow">
<Grid x:Name="Root">
<!-- OVERLAY BEHIND CHILDWINDOW -->
<Grid
x:Name="Overlay"
Background="{TemplateBinding OverlayBrush}"
Opacity="{TemplateBinding OverlayOpacity}"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"/>
<!-- WINDOW CONTAINER -->
<Grid x:Name="ContentRoot" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<!-- GLASS BACKGROUND AND BORDER -->
<!--
NOTE: This border should not physically contain the rest of the
window contents because it has an opacity setting that would
affect all of its children. Instead, a second border is directly
above it in the z-order and contains the child elements.
-->
<Border
x:Name="Chrome"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4"
Opacity="0.9">
<Border.Background>
<LinearGradientBrush MappingMode="Absolute" StartPoint="0,0" EndPoint="1920,0">
<GradientStop Color="#FFADC9E5" Offset="0.010"/>
<GradientStop Color="#FFA7C2DC" Offset="0.069"/>
<GradientStop Color="#FFB7D2EC" Offset="0.084"/>
<GradientStop Color="#FFB7D2EC" Offset="0.146"/>
<GradientStop Color="#FFA8C4DE" Offset="0.168"/>
<GradientStop Color="#FFB8D3ED" Offset="0.455"/>
<GradientStop Color="#FFA6C1DB" Offset="0.518"/>
<GradientStop Color="#FFB6D1EB" Offset="0.543"/>
<GradientStop Color="#FFA7C2DC" Offset="0.604"/>
<GradientStop Color="#FFB7D2EC" Offset="0.618"/>
<GradientStop Color="#FFB7D2EC" Offset="0.700"/>
<GradientStop Color="#FFABC6E1" Offset="0.722"/>
<GradientStop Color="#FFB1CEEA" Offset="0.778"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<!-- WINDOW CONTENTS -->
<!--
NOTE: This element will not have a visible border. The Chrome element
provides the visible border but this element needs to have a matching
thickness and corner radius so that the contents of the window are
"pushed in" by the same amount.
-->
<Border BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentControl
Content="{TemplateBinding Title}"
Foreground="#FF393939"
FontWeight="Bold"
VerticalAlignment="Center"
Margin="6,0,6,0"
Grid.Row="0"
Grid.Column="0"/>
<Button
x:Name="CloseButton"
Style="{StaticResource AeroWindowCloseButton}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1,0,1,1"
VerticalAlignment="Top"
Margin="0,0,5,0"
Grid.Row="0"
Grid.Column="1"/>
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Margin="{TemplateBinding Padding}"
Grid.Row="1"
Grid.ColumnSpan="2">
<ContentPresenter
x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</Border>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>