Skip to content

Instantly share code, notes, and snippets.

@danvacam
Created May 27, 2014 10:55
Show Gist options
  • Save danvacam/937e58347a4a264994d6 to your computer and use it in GitHub Desktop.
Save danvacam/937e58347a4a264994d6 to your computer and use it in GitHub Desktop.
Making borderless resizable window in WPF
<Window x:Class="Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowStyle="None" AllowsTransparency="True" Background="Transparent" >
<Grid x:Name="LayoutRoot"
Background="White" Margin="4">
<Grid.Effect>
<DropShadowEffect BlurRadius="15" Direction="-90" RenderingBias="Quality" ShadowDepth="2"/>
</Grid.Effect>
<Grid>
<Rectangle x:Name="ResizeN" Fill="White" VerticalAlignment="Top"
Height="4" Margin="9,-2,9,0" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
<Rectangle x:Name="ResizeE" Fill="White" HorizontalAlignment="Right"
Width="4" Margin="0,9,-2,9" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
<Rectangle x:Name="ResizeS" Fill="White" VerticalAlignment="Bottom"
Height="4" Margin="9,0,9,-2" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
<Rectangle x:Name="ResizeW" Fill="White" HorizontalAlignment="Left"
Width="4" Margin="-2,9,0,9" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize" />
</Grid>
<Path x:Name="ResizeNW" VerticalAlignment="Top" HorizontalAlignment="Left"
Stroke="White" StrokeThickness="4" Margin="0" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="0,10">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="0,0" />
<LineSegment Point="10,0"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Path x:Name="ResizeNE" VerticalAlignment="Top" HorizontalAlignment="Right"
Stroke="White" StrokeThickness="4" Margin="0,0,-2,0" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="0,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="10,0" />
<LineSegment Point="10,10"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Path x:Name="ResizeSE" VerticalAlignment="Bottom" HorizontalAlignment="Right"
Stroke="White" StrokeThickness="4" Margin="0,0,-2,-2" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="10,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="10,10" />
<LineSegment Point="0,10"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<Path x:Name="ResizeSW" VerticalAlignment="Bottom" HorizontalAlignment="Left"
Stroke="White" StrokeThickness="4" Margin="0,0,0,-2" MouseEnter="DisplayResizeCursor"
MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="0,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="0,10" />
<LineSegment Point="10,10"/>
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
<!-- HEADER -->
<Grid x:Name="HeaderGrid"
Height="50"
VerticalAlignment="Top">
<Grid
x:Name="DragableArea"
Background="White"
MouseDown="Window_OnMouseDown"/>
<StackPanel Orientation="Horizontal" Margin="0,5,5,0" HorizontalAlignment="Right" VerticalAlignment="Top" Background="White">
<TextBlock x:Name="SettingsButton" ToolTip="Impostazioni"
Text="@" FontFamily="Webdings" FontSize="16"
Padding="5" Margin="5,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Top"
MouseLeftButtonUp="SettingsButton_Click">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock x:Name="MinimizeButton" ToolTip="Rimpicciolisci"
Text="0" FontFamily="Webdings" FontSize="16"
Padding="5" Margin="5,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Top"
MouseLeftButtonUp="MinimizeButton_Click">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock x:Name="MaximizeButton" ToolTip="Ingrandisci"
Text="1" FontFamily="Webdings" FontSize="16"
Padding="5" Margin="5,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Top"
MouseLeftButtonUp="MaximizeButton_Click">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock x:Name="CloseButton" ToolTip="Chiudi"
Text="r" FontFamily="Webdings" FontSize="16"
Padding="5" Margin="5,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Top"
MouseLeftButtonUp="CloseButton_Click">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Gray" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Grid>
<!-- CONTENT -->
<Grid Margin="0,30,0,30" Background="White" VerticalAlignment="Top">
<Grid Background="White" MouseDown="Window_OnMouseDown" MinHeight="770">
</Grid>
</Grid>
<!-- FOOTER -->
<Grid Background="White" VerticalAlignment="Bottom">
<Grid Background="White" MouseDown="Window_OnMouseDown" Height="30">
</Grid>
</Grid>
</Grid>
</Window>
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Wpf
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
private const int WmSyscommand = 0x112;
private HwndSource _hwndSource;
private enum ResizeDirection
{
Left = 61441,
Right = 61442,
Top = 61443,
TopLeft = 61444,
TopRight = 61445,
Bottom = 61446,
BottomLeft = 61447,
BottomRight = 61448,
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
public MainWindow()
{
SourceInitialized += Window1_SourceInitialized;
InitializeComponent();
}
private void SettingsButton_Click(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
//SettingsGrid.Visibility = SettingsGrid.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
}
/// <summary>
/// Window_OnMouseDown
/// </summary>
private void Window_OnMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
Application.Current.MainWindow.DragMove();
}
/// <summary>
/// CloseButton_Clicked
/// </summary>
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
/// <summary>
/// MaximizedButton_Clicked
/// </summary>
private void MaximizeButton_Click(object sender, RoutedEventArgs e)
{
AdjustWindowSize();
}
/// <summary>
/// Minimized Button_Clicked
/// </summary>
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.WindowState = WindowState.Minimized;
}
/// <summary>
/// Adjusts the WindowSize to correct parameters when Maximize button is clicked
/// </summary>
private static void AdjustWindowSize()
{
Application.Current.MainWindow.WindowState = Application.Current.MainWindow.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
private void Window1_SourceInitialized(object sender, EventArgs e)
{
_hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
}
private void ResizeWindow(ResizeDirection direction)
{
SendMessage(_hwndSource.Handle, WmSyscommand, (IntPtr)direction, IntPtr.Zero);
}
protected void ResetCursor(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton != MouseButtonState.Pressed)
{
Cursor = Cursors.Arrow;
}
}
protected void Resize(object sender, MouseButtonEventArgs e)
{
var clickedShape = sender as Shape;
if (clickedShape == null) return;
switch (clickedShape.Name)
{
case "ResizeN":
Cursor = Cursors.SizeNS;
ResizeWindow(ResizeDirection.Top);
break;
case "ResizeE":
Cursor = Cursors.SizeWE;
ResizeWindow(ResizeDirection.Right);
break;
case "ResizeS":
Cursor = Cursors.SizeNS;
ResizeWindow(ResizeDirection.Bottom);
break;
case "ResizeW":
Cursor = Cursors.SizeWE;
ResizeWindow(ResizeDirection.Left);
break;
case "ResizeNW":
Cursor = Cursors.SizeNWSE;
ResizeWindow(ResizeDirection.TopLeft);
break;
case "ResizeNE":
Cursor = Cursors.SizeNESW;
ResizeWindow(ResizeDirection.TopRight);
break;
case "ResizeSE":
Cursor = Cursors.SizeNWSE;
ResizeWindow(ResizeDirection.BottomRight);
break;
case "ResizeSW":
Cursor = Cursors.SizeNESW;
ResizeWindow(ResizeDirection.BottomLeft);
break;
}
}
protected void DisplayResizeCursor(object sender, MouseEventArgs e)
{
var clickedShape = sender as Shape;
if (clickedShape == null) return;
switch (clickedShape.Name)
{
case "ResizeN":
case "ResizeS":
Cursor = Cursors.SizeNS;
break;
case "ResizeE":
case "ResizeW":
Cursor = Cursors.SizeWE;
break;
case "ResizeNW":
case "ResizeSE":
Cursor = Cursors.SizeNWSE;
break;
case "ResizeNE":
case "ResizeSW":
Cursor = Cursors.SizeNESW;
break;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment