Created
May 27, 2014 10:55
-
-
Save danvacam/937e58347a4a264994d6 to your computer and use it in GitHub Desktop.
Making borderless resizable window in WPF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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