My blog about application development on the .NET platform and Windows®.

How to create a custom window in WPF

This introductory post will provide a walkthrough on how to create your own custom looking window control with resize, drag, minimize, restore and close functionality and how to use it in your WPF applications.

The solution includes two Visual Studio projects, the first one a class library where the control itself is implemented and the second one a sample WPF application which will have a reference to the class library and use the custom window control as its main window.

Get started

Start by creating a new C# class library in Visual Studio (File->New Project) and give it a suitable name like Mm.Wpf.Controls.
Create project

Add references

After removing the automatically generated Class1.cs from the project the first thing to do is to add some references. We will need a reference to the PresentationFramework.dll where the out-of-the-box System.Windows.Window class, which our custom window class will inherit from, is implemented. We also need to add a reference to PresentationCore.dll where the RoutedEventArgs class lives, System.Xaml.dll and WindowsBase.dll. You add a reference in Visual Studio by choosing “Add reference” from the Project menu or by right-clicking the project in the solution explorer and the required DLLs should be found under the .NET tab.
addreference

Implement the control

The next step is to add a new class called CustomWindow.cs to the project by right-clicking the project name in the solution explorer and choose Add->Class. The class will be public and inherit from the default WPF window class (Sytem.Windows.Window). By extending the default Window class we can use its built-in functionality for minimizing, restoring and closing the window. We add the three click event handlers shown below to take care of this.

using System.Windows;

namespace Mm.Wpf.Controls
{
    public class CustomWindow : Window
    {
        #region Click events
        protected void MinimizeClick(object sender, RoutedEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        protected void RestoreClick(object sender, RoutedEventArgs e)
        {
            WindowState = (WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
        }

        protected void CloseClick(object sender, RoutedEventArgs e)
        {
            Close();
        }
        #endregion
    }
}

When you create a custom control in WPF you define a template for it in XAML. The default style must be located in a folder called “Themes” at the root of the class library project and for our custom window control to be able to find its default style we add a static constructor where the default value of the DefaultStyleKey property is set to the type object of our class.

static CustomWindow()
{    
    DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWindow),
        new FrameworkPropertyMetadata(typeof(CustomWindow)));
}

To define the style for the window we then add a “Themes” folder to the project. Inside this folder you can add different templates for each Windows theme but since theming is out of the scope of this article we will only add a so called fallback style. This style must be located in (or defined in a file referenced from) a file called “Generic.xaml” in the “Themes” folder.

Since the project template is a generic class library you probably won’t find the option to add a WPF Resource dictionary when right-clicking the newly created folder and choosing Add. Instead, choose to add a simple text file, name it “Generic.xaml” and give it the below content.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:Mm.Wpf.Controls">
    <!--  Button style -->
    <Style TargetType="{x:Type Button}" x:Key="WindowButtonStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ButtonBase}">
                    <Border
                            x:Name="Chrome"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Margin="0"
                            Background="{TemplateBinding Background}"
                            SnapsToDevicePixels="True">
                        <ContentPresenter
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                Content="{TemplateBinding Content}"
                                ContentStringFormat="{TemplateBinding ContentStringFormat}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                Margin="{TemplateBinding Padding}"
                                RecognizesAccessKey="True"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="FontFamily" Value="Webdings"/>
        <Setter Property="FontSize" Value="13.333" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="Margin" Value="0,2,3,0"/>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Foreground" Value="Gray" />
            </Trigger>
        </Style.Triggers>
    </Style>
    
    <!-- Window style -->
    <Style TargetType="{x:Type local:CustomWindow}">
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="ResizeMode" Value="NoResize"/>
        <Setter Property="Background" Value="White"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="BorderBrush" Value="Silver"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:CustomWindow}">
                    <Border BorderThickness="{TemplateBinding BorderThickness}" 
                            BorderBrush="{TemplateBinding BorderBrush}">
                        <Grid>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition />
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <Rectangle x:Name="moveRectangle" Fill="Transparent"
                                           Grid.Row="0" Grid.Column="0"/>
                                <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
                                    <Button x:Name="minimizeButton" Style="{StaticResource WindowButtonStyle}"
                                            Content="0" />
                                    <Button x:Name="restoreButton" Style="{StaticResource WindowButtonStyle}"
                                            Content="1" />
                                    <Button x:Name="closeButton" Style="{StaticResource WindowButtonStyle}"
                                            Content="r" />
                                </StackPanel>
                                <Grid Background="{TemplateBinding Background}"
                                           Grid.Row="1" Grid.ColumnSpan="2" Margin="5,5,5,5">
                                    <AdornerDecorator>
                                        <ContentPresenter/>
                                    </AdornerDecorator>
                                </Grid>
                            </Grid>
		        <! -- Resize grid to be inserted here -->
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Note that the buttons for minimizing, restoring and closing the window have their own template defined above the actual custom window template. Also these buttons have been assigned a name by the x:Name attribute for us to be able to find them in code and hook up their click event handlers. This is done by overriding the OnApplyTemplate in our CustomWindow class.

public override void OnApplyTemplate()
{
    Button minimizeButton = GetTemplateChild("minimizeButton") as Button;
    if (minimizeButton != null)
    	minimizeButton.Click += MinimizeClick;

    Button restoreButton = GetTemplateChild("restoreButton") as Button;
    if (restoreButton != null)
    	restoreButton.Click += RestoreClick;

    Button closeButton = GetTemplateChild("closeButton") as Button;
    if (closeButton != null)
    	closeButton.Click += CloseClick;

    base.OnApplyTemplate();
}

Make it draggable

At this stage our custom window is almost (the ThemeAttribute is missing) ready to be used in a WPF application but it cannot yet be dragged around on the screen nor resized. You may have noticed that the template above contains a rectangle named “moveRectangle” and this one will serve as a ‘handle’ to drag our window. We add a PreviewMouseDown event handler for the Rectangle in the OnApplyTemplate method and implement it as below.

private void moveRectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
   if (Mouse.LeftButton == MouseButtonState.Pressed)
      DragMove();
}

Make it resizable

To make the window resizable requires a bit more effort. We start by adding a bunch of invisible (Fill=”Transparent”) rectangles, one for each side of the window and another one for each corner of the window, to our XAML defined template. These rectangles will serve as the window’s edges and we will show the resizing cursors when the mouse moves over these. It is accomplished by implementing the MouseMove event for each of the rectangles. Note that the rectangle’s name decides which type of cursor to display.

<Grid x:Name="resizeGrid">
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            VerticalAlignment="Top"
            Height="5"
            x:Name="top"
            Margin="5,0,5,0" />
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            x:Name="bottom"
            Height="5"
            VerticalAlignment="Bottom"
            Margin="5,0,5,0" />
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            HorizontalAlignment="Left"
            Margin="0,5,0,5"
            Width="5"
            x:Name="left"/>
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            Margin="0,5,0,5"
            Width="5"
            HorizontalAlignment="Right"
            x:Name="right" />
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            HorizontalAlignment="Left"
            VerticalAlignment="Bottom"
            Width="5"
            Height="5"
            x:Name="bottomLeft" />
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            VerticalAlignment="Bottom"
            Height="5"
            Width="5"
            HorizontalAlignment="Right"
            x:Name="bottomRight" />
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            HorizontalAlignment="Right"
            Width="5"
            Height="5"
            VerticalAlignment="Top"
            x:Name="topRight" />
        <Rectangle
            Stroke="{x:Null}"
            Fill="Transparent"
            HorizontalAlignment="Left"
            Width="6"
            VerticalAlignment="Top"
            Height="5"
            x:Name="topLeft" />
    </Grid>
public override void OnApplyTemplate()
{
      /* omitted */

      Grid resizeGrid = GetTemplateChild("resizeGrid") as Grid;
      if (resizeGrid != null)
      {
           foreach (UIElement element in resizeGrid.Children)
           {
                 Rectangle resizeRectangle = element as Rectangle;
                 if (resizeRectangle != null)
                 {
                      resizeRectangle.PreviewMouseDown += ResizeRectangle_PreviewMouseDown;
                      resizeRectangle.MouseMove += ResizeRectangle_MouseMove;
                 }
           }
       }

       base.OnApplyTemplate();
}

protected void ResizeRectangle_MouseMove(Object sender, MouseEventArgs e)
{
    Rectangle rectangle = sender as Rectangle;
    switch (rectangle.Name)
    {
        case "top":
            Cursor = Cursors.SizeNS;
            break;
        case "bottom":
            Cursor = Cursors.SizeNS;
            break;
        case "left":
            Cursor = Cursors.SizeWE;
            break;
        case "right":
            Cursor = Cursors.SizeWE;
            break;
        case "topLeft":
            Cursor = Cursors.SizeNWSE;
            break;
        case "topRight":
            Cursor = Cursors.SizeNESW;
            break;
        case "bottomLeft":
            Cursor = Cursors.SizeNESW;
            break;
        case "bottomRight":
            Cursor = Cursors.SizeNWSE;
            break;
        default:
            break;
        }
}

We also need to remember to reset the cursor to its default state when the mouse moves from one of the edges into the content area and for this we add a constructor to our custom window class and an event handler to the Window’s PreviewMouseMove event.

public CustomWindow()
    : base()
{
    PreviewMouseMove += OnPreviewMouseMove;
}

protected void OnPreviewMouseMove(object sender, MouseEventArgs e)
{
    if (Mouse.LeftButton != MouseButtonState.Pressed)
        Cursor = Cursors.Arrow;
}

To implement the actual resizing behavior in the PreviewMouseDown event handler for each of the edge rectangles we then make use of the platform invocation services (PInvoke) to call the unmanaged Windows API SendMessage method.

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);

protected void ResizeRectangle_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    Rectangle rectangle = sender as Rectangle;
    switch (rectangle.Name)
    {
        case "top":
            Cursor = Cursors.SizeNS;
            ResizeWindow(ResizeDirection.Top);
            break;
        case "bottom":
            Cursor = Cursors.SizeNS;
            ResizeWindow(ResizeDirection.Bottom);
            break;
        case "left":
            Cursor = Cursors.SizeWE;
            ResizeWindow(ResizeDirection.Left);
            break;
        case "right":
            Cursor = Cursors.SizeWE;
            ResizeWindow(ResizeDirection.Right);
            break;
        case "topLeft":
            Cursor = Cursors.SizeNWSE;
            ResizeWindow(ResizeDirection.TopLeft);
            break;
        case "topRight":
            Cursor = Cursors.SizeNESW;
            ResizeWindow(ResizeDirection.TopRight);
            break;
        case "bottomLeft":
            Cursor = Cursors.SizeNESW;
            ResizeWindow(ResizeDirection.BottomLeft);
            break;
        case "bottomRight":
            Cursor = Cursors.SizeNWSE;
            ResizeWindow(ResizeDirection.BottomRight);
            break;
        default:
            break;
     }
}

private void ResizeWindow(ResizeDirection direction)
{
    SendMessage(_hwndSource.Handle, 0x112, (IntPtr)(61440 + direction), IntPtr.Zero);
}

private enum ResizeDirection
{
    Left = 1,
    Right = 2,
    Top = 3,
    TopLeft = 4,
    TopRight = 5,
    Bottom = 6,
    BottomLeft = 7,
    BottomRight = 8,
}

For the above ResizeWindow wrapper method to compile we need to add a member variable of type HwndSource to represent our window and provide access to its window handle. The variable is initialized in the Window.SourceInitialized event.

private HwndSource _hwndSource;

protected override void OnInitialized(EventArgs e)
{
    SourceInitialized += OnSourceInitialized;
    base.OnInitialized(e);
}

private void OnSourceInitialized(object sender, EventArgs e)
{
    _hwndSource = (HwndSource)PresentationSource.FromVisual(this);
} 

At this point the class library should compile just fine if you have included the following required using statements at the top of the CustomWindow.cs file.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Shapes;
using System;
using System.Windows.Interop;
using System.Runtime.InteropServices;

The last thing to do is to add a ThemeInfo attribute to our assembly to specify where WPF should look for the possible theme dictionaries and the generic dictionary. As we don’t have any specific theme styles and our Generic.xaml is located in the current assembly we add the following to the automatically generated AssemblyInfo.cs located under the Properties folder at the root of the project.

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

Use the control in a WPF application

The CustomWindow control is now ready be used. We add a new WPF application to our solution by choosing File->Add->New project on the menu bar.

We then set the newly added project to the startup project by right-clicking on it in the solution explorer and choosing “Set as StartUp project”. If you run the solution at this point you should see an ordinary empty window popup on your screen.
default
To be able to replace this window with our custom style window, we first add a reference to the Mm.Wpf.Controls class library by right-clicking the WPF application project and choosing “Add reference” and the “Projects” tab.

Then we simply edit the MainWindow class, both the code-behind C# and the XAML, to inherit from our custom CustomWindow class instead of the default Window class as shown below.

namespace WpfApplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : CustomWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}
<control:CustomWindow x:Class="WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:control="clr-namespace:Mm.Wpf.Controls;assembly=Mm.Wpf.Controls"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock Text="Here goes the content!"/>
    </Grid>
</control:CustomWindow>

The application’s main window should now show up with our custom style and you should be able to drag it around on the screen, resize it, minimize it, restore it and close it just like you would with the default window.
Custom window


88 Comments on “How to create a custom window in WPF”

  1. ebia says:

    hi
    where to implement this xaml?
    in Mm.Wpf.Controls project or in secend project: WPF application?

    …..
    ……
    ….
    .

    please send to me source code of this project

    thank you

  2. Hi ebia,

    Only the very last XAML markup snippet, where you define the appearance for the instance of the custom window class defined in the class library, resides in the WPF application.

  3. najah1968 says:

    hi
    I’m a newbie in Visual Studio and I’m getting this error “The type ‘Mm.Wpf.Controls.CustomWindow’ already contains a definition for ‘ResizeRectangle_PreviewMouseDown'”

    can you tell me how to fix it?. . .thanks in advance.

  4. najah1968 says:

    hi again, can you tell me where is this problem coming from?

    Ambiguity between ‘Mm.Wpf.Controls.CustomWindow.ResizeRectangle_PreviewMouseDown’ and ‘Mm.Wpf.Controls.CustomWindow.ResizeRectangle_PreviewMouseDown(object, System.Windows.Input.MouseButtonEventArgs)’

  5. najah1968 says:

    please send to me the source code of this project also. . .tnx a lot!

  6. Hi najah1968,

    The CustomWindow class should only have a single method named ResizeRectangle_PreviewMouseDown.

  7. Buddy says:

    It works.
    Greate job. Thanks a lot.

  8. Mogi says:

    Nice work.
    But this work has few conflict when you are working in Visual Studio 2012 and .NET 4.5.

  9. Mogi says:

    Hi, some questions here.
    I added Mm.Wpf.Controls class library as Reference to my new Proejct.
    But now it shows below errors.
    1 The tag ‘CustomWindow’ does not exist in XML namespace ‘clr-namespace:Mm.Wpf.Controls;assembly=Mm.Wpf.Controls’. Line 1 Position 23.
    2 Project file must include the .NET Framework assembly ‘WindowsBase’ in the reference list. Mm.Wpf.Controls
    3 The type ‘control:CustomWindow’ was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.

    Any suggestion?

  10. Hi Mogi,

    Add a reference to WindowsBase.dll to the Mm.Wpf.Controls class library and recompile the solution.

  11. Darren says:

    I have it working and its awesome. Thanks you saved me loads of time. Any idea on how to get it working with Aero snap?

  12. Adam says:

    Magnus – I am having the same problem others are having. I think it’s a designer bug in VS 2012. I have all the references added, and I’m getting errors that CustomWindow does not exist in the namespace.. yet I’m not getting any squiggly lines under the code indicating there is a problem.

    I had another issue with this part:
    xmlns:local=”clr-namespace:Mm.Wpf.Controls”

    It says:
    Undefined CLR namespace. The ‘clr-namespace’ URI refers to a namespace ‘Mm.Wpf.Controls’ that could not be found.

    Yet if I just edit the text a little bit, like delete the ‘s’ from ‘Controls’ and retype it exactly how it was, the error goes away. But I still get errors about CustomWindow not existing in Mm.Wpf.Controls ..even though I have all the code you told us to add, copied and pasted verbatim.

    Something’s acting wonky here.

  13. Adam says:

    Yeah I am absolutely stumped. Been trying to figure this error out for hours now. There are a ton of people asking how to fix this and I’ve tried every suggestion I could find with no success. Any chance you could post the compiled control?

  14. Hi Adam,

    In which project does the error regarding the undefined namespace occur? If you have defined the custom window in the class library, you need add a reference to this project from the WPF application and include the name of the assembly when you import the namespace in the MainWindow.xaml file:

    xmlns:control=”clr-namespace:Mm.Wpf.Controls;assembly=Mm.Wpf.Controls”

    If you get the error when compiling the class library, make sure that the CustomWindow class is defined in the Mm.Wpf.Controls namespace.

  15. vishnu says:

    Thanks a lot,

  16. Dingdong says:

    Hi
    I used VS 2008 and followed your tutorial step by step but got a base window in WpfApplication.
    The Generic.xaml file doesn’t apply to the window that inherits from CustomWindow.
    Could you please kindly advise?

  17. Dingdong says:

    I did add the constructor

    static CustomWindow()
    {
    DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWindow),
    new FrameworkPropertyMetadata(typeof(CustomWindow)));
    }

    and also the ThemeInfo attribute in the AssemblyInfo.cs (the last line).

  18. Dingdong says:

    I’ve tried another way: Adding a WPF custom control to the project instead of refering this custom control from a class library. It does pick up the Generic.xaml file but not the dragable feature.. Still searching for the reason..

  19. Dingdong says:

    Eventually I got the dragable feature as well. But still dont understand why the Generic.xaml doesnt apply when the custom control is called from a class library…

  20. Hi Dingdong,

    The generic resource dictionary should be located in the Themes folder of the class library where the custom window control is defined and not in the WPF application.

  21. dirt says:

    Not working vs2012 .NET 4.5. Intellisense autocompletes the views:CustomWindow so I know it is in the right namespace…

    Failed to create a ‘TargetType’ from the text ‘views:CustomWindow’

  22. itay says:

    hi great article, i have scceed to load the window but i am getting the regular Windows window with black background
    i am working on VS 2012 and with windows 8
    do u know what seems to be the problem?

  23. itay says:

    is it possible to get the source code i’m realy need this window 10x.

  24. Peter says:

    Thanks for the great article!
    I was following along, but how can I add controls from the Toolbox to it? When I open the Design mode I can’t see any of the panels with child controls I added to that Window (via XAML), even though I see them when I start the application. Is there a solution to this?
    How can I see the content of the custom Window in design mode and add controls to it?

  25. Dusty Roberts says:

    to get the dragging work, just add the following to the “OnApplyTemplate”:

    Rectangle moveRectangle = GetTemplateChild(“moveRectangle”) as Rectangle;
    moveRectangle.MouseDown += moveRectangle_PreviewMouseDown;

  26. laymensterm says:

    To get rid of the black border: update the border backround as seen below:

  27. mo says:

    I am using Visual studio 2010, but when I add the Generic.xaml, all my tags are highlighted (e.g. “ResourceDictionary” cannot be found, same with Style, Setter, Rectangle….). They should be normal xaml tags… Why does VS find them as a warning? How can I fix it?

  28. Hi! Thank you for this post.

    I have an error: In MainWindow class, on InitializeComponent();

    “Error 1 The name ‘InitializeComponent’ does not exist in the current context”

    I’m using VS2013, any ideas whats wrong?

  29. Hi, I don’t understand the onapplytemplate function. It’s described twice here, should I add the second one’s content to the first one, but then the base.onapplytemplate appears twice?

  30. Dror D says:

    Hello
    I did everything and window shows, can be moved but resize don’t work
    help please
    thank you.

  31. Joe says:

    Hello,
    I think i did everything correctly, i dont have any compilation error, my designer works fine but when i launch my mainpage i have the original window template with a total black content.. can you tell me what could be the cause of that?
    Thank you.

  32. Tosca says:

    Hi,

    I am having the same problem as Joe and Itay. My window has the original window template with black content… Is the cause or solution known?

    Thanks a lot!

  33. Joe says:

    I’ve found that the black window is due to the class library project, i put everything in a WPF custom control project and it worked.

  34. Diego says:

    Wonderful tutorial, I use it and I made some update but there’s a thing I cannot solve.
    When I maximize window it hide the taskbar going at full screen, I can we avoid it? I triend some trick with System.Windows.SystemParameters.WorkArea but it doesn’t work with multiple monitors.

  35. Joe says:

    Hi Diego, i had the same problems and i put this in the RestoreClick method and it works:

    switch (WindowState)
    {
    case WindowState.Normal:
    MaxHeight = Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Height;
    ResizeMode = ResizeMode.NoResize;
    WindowState = WindowState.Maximized;
    _restoreButton.Content = 2;
    break;
    case WindowState.Maximized:
    ResizeMode = ResizeMode.CanResize;
    WindowState = WindowState.Normal;
    _restoreButton.Content = 1;
    break;
    }

  36. Elvis Hsu says:

    Thanks for this great article. I think many people and I have same issue, “Black background”. I noticed that the OnApplyTemplate is not getting called. I have checked everything such as:

    1. Themes/Generic.xaml at the root of the project
    2. adding a static method by calling DefaultStyleKeyProperty.OverrideMetadata
    3. Added mentioned line in AssemblyInfo.cs

    But the OnApplyTemplate method is still not getting called. Any suggestion?

  37. Elvis Hsu says:

    I found the answer. Set the build action of Generic.xaml to Page.

  38. Jakob Anton Mayrhofer says:

    I don`t know if the problem with that black Window is alredy solved, but here is some solution

    you have to name your xml File “generic.xaml” and it has to be in a folder called “themes”

    in your folder Properties open AssemblyInfo.cs
    and add

    using System.Windows;


    [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

  39. Hasan says:

    Wow Great Job, thansks.

  40. mts says:

    Hi,
    I know it’s a quite old thread, but is it possible to get the complete sourcecode?

  41. mts says:

    Is there any way to see the window style at design time?
    I have the problem, that I am using a dark background and bright foreground.
    In design time I cant see any text, as the default background is white.

  42. Mikael says:

    Hello, I guess I’m late but I have been trying for hours now to get rid of the black borders (Its black where it is blue on a normal Window) I Just can’t get it to work. From what I can see is that the error lies between line 6 – 27 in the xaml file. Please help, this Article is gold Worth.

  43. Mikael says:

    Hello again, I Found the solution, I was abit tired when looking last time. My problem with black borders was the Resize grid. The Transparent color made them black.! Thanks alot for this Guide!

  44. Sachin C R says:

    Hi all, I just fallow the custom window instructions. All will work as window changes other than window re-size and drag the corners.
    I have placed “resizeGrid” rectangles inside a custom window style is it fine or please suggest me if its wrong.
    Can you please help me any one.
    Is it possible share source code

  45. ph.E says:

    Hello,

    Please make the source code of the article for download somewhere.
    Will help a lot to find our mistakes.

    Nice article.
    Congratulations.

  46. nevermind10844 says:

    Hey Guys!

    I hat the same problem with InitializeComponent not known in this context.
    It was caused by not having set the namespace-attributes matching for both, the code-behind and the xaml file.
    For me it need to be like “namespace MyWPFTestApplication” in cs-File and like “<control:JKWindow x:Class="MyWPFTestApplication.MainWindow"" in xaml-File.

  47. nevermind10844 says:

    Hey Guys!
    Is the black-context and default window-style problem solved?
    I would like to run it from the class-library.

  48. nevermind10844 says:

    Hey, I just realized there allready was a solution.
    Adding these two lines:
    using System.Windows;


    [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
    to the AssemblyInfo.cs of the ClassLibrary did the trick.

    Thank you Jakob Anton Mayrhofer

  49. Carte says:

    Had the same “black background problem”. Modfied the line (line 50) in Generic.xaml from:

    …to also include…
    Background=”{TemplateBinding Background}”

    Then its working.

  50. Swarnava says:

    can the same be done using visual basic??..can anyone plz post the code for that??…


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s