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

WPF Custom Window W/Full Windows Functionality

, 18 Jan 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
WPF Custom Window W/Full Windows Functionality.

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)

Share

About the Author

Programmer35

United States United States
No Biography provided

Comments and Discussions

 
QuestionSource PinmemberKonstantin Glushakov27-Jan-13 9:35 
AnswerRe: Source Pinmemberjiju chovva10-Feb-13 15:48 

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.1411023.1 | Last Updated 18 Jan 2013
Article Copyright 2012 by Programmer35
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid