Click here to Skip to main content
11,707,254 members (54,986 online)
Click here to Skip to main content

Create Custom Windows in WPF with Ease

, 27 Dec 2010 CPOL 71K 369 48
Rate this:
Please Sign up or sign in to vote.
Declaratively and visually create custom windows in WPF


One of the features I wanted to add to Synergy toolkit was the ability to quickly create custom theme windows with all the features of standard windows. In this article, I am demonstrating how to create a custom window theme visually using declarative XAML and apply it to windows in your applications.

You can download Synergy SDK with the full source code here. You may also want to see my window docking solution in Synergy here. I will be posting updates on Synergy SDK on my twitter account: MixModes.

The sample application Synergy uses main window as the custom window whose theme is defined within Windows.xaml resource dictionary within MixModes.Synergy.Themes project.

Declarative is the Key

As we all know, XAML is declarative and simple and so there is no reason why traditional approach of writing code for windows and controls should apply. One must be able to simply create a visual and stick it in a control template to get things working. That was exactly my motivation when I started out developing look-less window functionality in Synergy.

Declare a Template

The first thing you may want to do in creating a custom window is to actually create a visual template. The easiest way to create this template is to create a user control in Microsoft Blend and then define extension points in XAML that look-less control will liven up once the template is applied. Once the visual is ready, all that needs to be done is a style creation for CustomWindow where the template can be pasted and then the temporary user control can be discarded.

The following extension points are supported for current implementation:

  • PART_TITLEBAR (UIElement) - For displaying window title, dragging and maximize / restore operations
  • PART_MINIMIZE (Button) – Window minimize button
  • PART_MAXIMIZE_RESTORE (Button) – Maximize restore button
  • PART_CLOSE (Button) – Close button
  • PART_LEFT_BORDER (UIElement) – Left resizable border
  • PART_RIGHT_BORDER (UIElement) – Right resizable border
  • PART_TOP_BORDER (UIElement) – Top resizable border
  • PART_BOTTOM_BORDER (UIElement) – Bottom resizable border

One more thing to note is that while defining the window template, you must declare the ContentPresenter (which ultimately contains window content) within AdornerDecorator tag (which is the adorner layer for the window) as this is a WPF requirement.

Here is the template I have created within Windows.xaml resource dictionary within MixModes.Synergy.Themes project:

<ResourceDictionary xmlns="" 
    <Style x:Key="MainWindow" 
           TargetType="{x:Type Window}"> 
        <Setter Property="Foreground" 
                Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" /> 
        <Setter Property="Template"> 
                <ControlTemplate TargetType="{x:Type Window}"> 
                        <Border x:Name="MainBorder" 
                                BorderBrush="{DynamicResource MainWindowBorderBrush}" 
                                Background="{DynamicResource MainWindowBackgroundBrush}"> 
                            <DockPanel LastChildFill="True"> 
                                <Rectangle x:Name="PART_LEFT_BORDER" 
                                        <SolidColorBrush Color="Transparent" /> 
                                <Rectangle x:Name="PART_RIGHT_BORDER" 
                                        <SolidColorBrush Color="Transparent" /> 
                                <Rectangle x:Name="PART_TOP_BORDER" 
                                        <SolidColorBrush Color="Transparent" /> 
                                <Rectangle x:Name="PART_BOTTOM_BORDER" 
                                        <SolidColorBrush Color="Transparent" /> 
                                <Border x:Name="PART_TITLEBAR" 
                                    <DockPanel LastChildFill="False"> 
                                        <TextBlock Margin="8,0,0,4" 
                                                   Text="{TemplateBinding Title}" 
                                                   FontSize="16" /> 
                                        <Button x:Name="PART_CLOSE" 
                                                Style="{DynamicResource FlatButton}" 
                                            <Image Source="/MixModes.Synergy.Resources;
                                                   Margin="4" /> 
                                        <Button x:Name="PART_MAXIMIZE_RESTORE" 
                                                Style="{DynamicResource FlatButton}"> 
                                            <Image x:Name="MaximizeRestoreImage" 
                                                   Margin="4" /> 
                                        <Button x:Name="PART_MINIMIZE" 
                                                Style="{DynamicResource FlatButton}" 
                                            <Image Margin="4" 
                                                   Stretch="None" /> 

                                <!-- Title bar separator--> 
                                <Border Height="1" 
					MainWindowTitleBarSeparator}" />

                                <!-- Actual Window Content --> 
                                <AdornerDecorator DockPanel.Dock="Bottom"> 
                                    <ContentPresenter /> 
                        <DataTrigger Binding="{Binding RelativeSource=
				{RelativeSource Self}, Path=Maximized}" 
                            <Setter TargetName="MaximizeRestoreImage" 
				component/Resources/Maximize.png" /> 

This is a pretty simple theme which creates a rounded rectangle window with 2 pixel wide resizers and custom window minimize, maximize and restore buttons. It also contains a template trigger that changes the image of maximize restore button if window is not maximized.

The window created using this theme looks like the following:


Inherit from CustomWindow Class

The final step is to inherit from CustomWindow class (which in turn inherits from Window class) instead of directly inheriting from Window class and refer to the style created in the previous step. This is again very simple:

  • Import visual framework namespace:
  • Inherit from CustomWindow class:
    use “visualFx:CustomWindow” as your window tag in XAML
  • Refer to the style created in previous step in your visualFx:CustomWindow tag:
    Style="{DynamicResource MainWindow}"

That’s all you have to do to get your custom window working !

How Does It Work?

If you crack open the CustomWindow class, you will see that bulk of the work happens in the AttachToVisualTree method which is called from OnApplyTemplate (which in turn is called anytime template is applied to our custom window).

AttachToVisualTree in turn calls AttachCloseButton, AttachMaximizeButton, AttachMaximizeRestoreButton, AttachTitleBar and AttachBorders methods, each of which queries for visual parts (the PART_… named parts we defined in the template) and attaches functionality via events.

So that’s it ! Creating custom windows using Synergy is really that simple!


  • 27th December, 2010: Initial post


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


About the Author

Ashish Kaila
Software Developer (Senior) MixModes Inc. | Research In Motion
Canada Canada
Ashish worked for Microsoft for a number of years in Microsoft Visual Studio (Architect edition) and Windows Live division as a developer. Before that he was a developer consultant mainly involved in distributed service development / architecture. His main interests are distributed software architecture, patterns and practices and mobile device development.

Currently Ashish serves as a Technical Lead at RIM leading next generation BlackBerry media experience and also runs his own company MixModes Inc. specializing in .NET / WPF / Silverlight technologies. You can visit MixModes at or follow it on Twitter @MixModes

In his free time he is an avid painter, hockey player and enjoys travelling. His blog is at:

You may also be interested in...

Comments and Discussions

QuestionBlack stripes when restore minimized CustomWindow in the downloaded project. Pin
amalraj198814-Oct-14 2:47
memberamalraj198814-Oct-14 2:47 
Questionkind of new in wpf Pin
Member 1045550624-Dec-13 22:07
memberMember 1045550624-Dec-13 22:07 
QuestionRe: kind of new in wpf Pin
Claude He21-Jul-14 17:26
memberClaude He21-Jul-14 17:26 
AnswerRe: kind of new in wpf Pin
Claude He21-Jul-14 17:35
memberClaude He21-Jul-14 17:35 
QuestionProject Pin
Member 984209614-Apr-13 1:28
memberMember 984209614-Apr-13 1:28 
AnswerRe: Project Pin
Ashish Kaila14-Apr-13 11:41
memberAshish Kaila14-Apr-13 11:41 
GeneralRe: Project Pin
LiquidHolic11-Jun-13 16:27
memberLiquidHolic11-Jun-13 16:27 
GeneralRe: Project Pin
Ashish Kaila12-Jun-13 7:05
memberAshish Kaila12-Jun-13 7:05 
Generalcustomwindow class Pin
disposable6-Jun-11 8:07
memberdisposable6-Jun-11 8:07 
GeneralRe: customwindow class Pin
Ashish Kaila6-Jun-11 8:08
memberAshish Kaila6-Jun-11 8:08 

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
Web02 | 2.8.150819.1 | Last Updated 27 Dec 2010
Article Copyright 2010 by Ashish Kaila
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid