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

WPF Custom Window W/Full Windows Functionality

By , 18 Jan 2013
 

Introduction

Create a custom WPF window with full Windows functionality, not just partial.

Background

I fought for quite a while to get this working and found many snipe hunt trails along the way, or people that share small samples that work for only partial solutions or only work for the bottom resizing because the solution was not compatible all the way around. This is a full solution that is about 98% complete. I still have not perfected the upper left, upper right, and lower left corners. I will be finishing this up in the near future, but for now here is what I have.

Using the code

This code is used for XAML and WPF solutions with C#. 

The following is the XAML to get you started. Theses are the invisible rectangles that will border your window and monitor mousedowns etc...  I have written a quick project demo for anyone that can't make heads or tails of the poor formatting below. 

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Converters="clr-namespace:StenoViewerAndWriter.Converters" 
        Closed="MainWindowClosed" 
        AllowsTransparency="True"
        WindowStyle="None"
        BorderBrush="DarkGray"
        BorderThickness="2"
        MinHeight="500"
        MinWidth="700"
        SizeChanged="Window_SizeChanged" 
        KeyUp="Window_KeyUp"
        WindowStartupLocation="CenterScreen"
        MouseLeftButtonDown="Window_MouseLeftButtonDown"
        MouseLeftButtonUp="Window_MouseLeftButtonUp"
        MouseDoubleClick="Window_MouseDoubleClicked"
        ResizeMode="CanResizeWithGrip"> 
 <Grid> 
 <StackPanel x:Name="spWindowsButtons" Orientation="Horizontal" 
 VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,5,10,0" >
      
            <Button Background="Transparent" Padding="0" 
            Height="18" Click="btnMinimize_Clicked" BorderBrush="Transparent">
                  <Image x:Name="btnMin" 
                  Source="Images/MinimizeIcon.png" Height="15" Width="15" 
                  VerticalAlignment="Top" HorizontalAlignment="Right" />
            </Button>
            <Button Background="Transparent" Padding="0" 
            Height="18" Margin="10,0,0,0" Click="btnMaxRestore_Clicked" 
            BorderBrush="Transparent">
                <Image x:Name="btnMaxAndRestore" Source="Images/MaximizeIcon.png" 
                Height="15" Width="15" VerticalAlignment="Top" 
                HorizontalAlignment="Right" />
            </Button>
            <Button Background="Transparent" Padding="0" Height="18" 
            Margin="10,0,0,0" Click="btnClose_Clicked" BorderBrush="Transparent">
                <Image x:Name="btnClose" Source="Images/closeIcon.png" 
                Height="15" Width="15" VerticalAlignment="Top" 
                HorizontalAlignment="Right" />
            </Button>
        </StackPanel> 
        <Rectangle x:Name="DragHandleTopLeft" 
        MouseMove="DragHandle_MouseMove" MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter" Cursor="SizeNWSE" 
        Fill="Transparent" Margin="-5,-5,0,0" HorizontalAlignment="Left" 
        VerticalAlignment="Top" Height="15" Width="15" 
        MouseLeftButtonDown="DragHandle_MouseLeftButtonDown"/>
        <Rectangle x:Name="DragHandleTopRight" MouseMove="DragHandle_MouseMove" 
        MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter"   Cursor="SizeNESW" 
        Fill="Transparent" Margin="0,-5,-5,0" 
        HorizontalAlignment="Right" VerticalAlignment="Top" 
        Height="15" Width="15" MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" />
        <Rectangle x:Name="DragHandleBottomLeft" 
        MouseMove="DragHandle_MouseMove" MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter"  Cursor="SizeNESW" 
        Fill="Transparent" Margin="-5,0,0,-5" 
        HorizontalAlignment="Left" VerticalAlignment="Bottom" 
        Height="15" Width="15" 
        MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" />
        <Rectangle x:Name="DragHandleBottomRight" 
        MouseMove="DragHandle_MouseMove" MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter"   Cursor="SizeNWSE" 
        Fill="Transparent" Margin="0,0,-5,-5" 
        HorizontalAlignment="Right" VerticalAlignment="Bottom" 
        Height="15" Width="15" 
        MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" />
        <Rectangle x:Name="DragHandleLeft" 
        MouseMove="DragHandle_MouseMove" MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter"  Cursor="SizeWE" 
        Fill="Transparent" HorizontalAlignment="Left" 
        Margin="-5,10,0,10" Width="10" MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" />
        <Rectangle x:Name="DragHandleRight" 
        MouseMove="DragHandle_MouseMove" MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter"  Cursor="SizeWE" Fill="Transparent" 
        HorizontalAlignment="Right" Margin="0,10,-5,10" Width="10" 
        MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" />
        <Rectangle x:Name="DragHandleTop" MouseMove="DragHandle_MouseMove" 
        MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
        MouseEnter="DragHandle_MouseEnter"  Cursor="SizeNS" 
        Fill="Transparent" VerticalAlignment="Top" Margin="10,-5,10,0" 
        Height="10" MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" />
            <Rectangle x:Name="DragHandleBottom" 
            MouseEnter="DragHandle_MouseEnter" Cursor="SizeNS" 
            Fill="Transparent" VerticalAlignment="Bottom" 
            Margin="10,0,10,-5" Height="10" 
            MouseLeftButtonUp="DragHandle_MouseLeftButtonUp" 
            MouseLeftButtonDown="DragHandle_MouseLeftButtonDown" 
            MouseMove="DragHandle_MouseMove" />

</Grid> 
</Window>
//Here is the C# Code Behind for this stuff 
private bool _isResizing;
private double _initY;
private double _initX;
  
private void btnClose_Clicked(object sender, RoutedEventArgs routedEventArgs)
{
    this.Close();
} 
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (!_isResizing)
        this.DragMove();
}
private void Window_MouseDoubleClicked(object sender, MouseButtonEventArgs e)
{
    ToggleWindowSize();
}
private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    _isResizing = false;
}
//Drag Handlers
private void DragHandle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    _isResizing = false;
    switch (direction)
    {
        case ResizeDirection.Top:
            DragHandleTop.ReleaseMouseCapture();
            break;
        case ResizeDirection.Bottom:
            DragHandleBottom.ReleaseMouseCapture();
            break;
        case ResizeDirection.Left:
            DragHandleLeft.ReleaseMouseCapture();
            break;
        case ResizeDirection.Right:
            DragHandleRight.ReleaseMouseCapture();
            break;
        case ResizeDirection.TopLeft:
            DragHandleTopLeft.ReleaseMouseCapture();
            break;
        case ResizeDirection.BottomRight:
            DragHandleBottomRight.ReleaseMouseCapture();
            break;
        case ResizeDirection.TopRight:
            DragHandleTopRight.ReleaseMouseCapture();
            break;
        case ResizeDirection.BottomLeft:
            DragHandleBottomLeft.ReleaseMouseCapture();
            break;
        default:
            this.Cursor = Cursors.Arrow;
            break;
    }
}
private void DragHandle_MouseEnter(object sender, MouseEventArgs e)
{
    if (e.LeftButton != MouseButtonState.Pressed)
        _isResizing = false;
}
private void DragHandle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    _initY = this.PointToScreen(e.GetPosition(this)).Y;
    _initX = this.PointToScreen(e.GetPosition(this)).X;
    _isResizing = true;
}
private void DragHandle_MouseMove(object sender, MouseEventArgs e)
{
    if (!_isResizing)
        return;

    FrameworkElement element = sender as FrameworkElement;
    string enumName = element.Name.Replace("DragHandle", "");
    direction = (ResizeDirection)Enum.Parse(typeof(ResizeDirection), enumName);

    double newY = this.PointToScreen(e.GetPosition(this)).Y;
    double newX = this.PointToScreen(e.GetPosition(this)).X;
    double diff;
    double newHeight;
    double newWidth;

    switch (direction)
    {
        case ResizeDirection.Top:
            {
                diff = _initY - newY;
                newHeight = this.Height + diff;

                //ShowTestData = "Old Height=" + this.Height + "New Height=" + 
                //  newHeight.ToString() + " and Diff" + diff;
                if (newHeight >

Points of Interest

This is a huge pain in the butt and requires a little math and some patience. However this should be copy and pasteable code to help you get started.

History

Version 1: I have not made a demo project as this is in a corporate project that I cannot share, so all I can share is the code, but it does fully function. Hopefully I included everything you will need in the above.

License

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

About the Author

Programmer35
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionSourcememberKonstantin Glushakov27 Jan '13 - 8:35 
Where I can download source code?
AnswerRe: Sourcememberjiju chovva10 Feb '13 - 14:48 
QuestionIncomplete!memberFatCatProgrammer6 Nov '12 - 9:12 
QuestionThe code is truncated...membergabbby694 Nov '12 - 7:05 
AnswerRe: The code is truncated...memberMember 80668645 Nov '12 - 8:02 

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 18 Jan 2013
Article Copyright 2012 by Programmer35
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid