如何使用装饰器从各个方向实现 window 调整大小?
How to implement window resizing from all sides using an adorner?
我有一个无边界透明 wpf window (WindowStyle=None),我希望能够从各个方向调整大小。如果我设置 ResizeMode=CanResizeWithGrip,目前调整大小仅适用于上述设置。这对于视觉提示来说很好,但不是很好,因为您只能从一个角调整大小。
我想用装饰器来做这个,所以当 window 处于调整大小模式(可以打开和关闭)时,我也可以给出视觉提示。这可能吗?如果是这样,我该怎么做?
这个问题已经在 Whosebug 上的某个地方得到了回答。我现在真的找不到了,但我是这样做的。
主窗口:
<Window x:Class="Solution.Views.Main.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" MinWidth="1000" MinHeight="500" WindowStyle="None" AllowsTransparency="False" BorderThickness="0" ResizeMode="NoResize">
<Window.TaskbarItemInfo>
<TaskbarItemInfo />
</Window.TaskbarItemInfo>
<Grid>
<Border MouseLeftButtonDown="WindowResizeEast" MouseEnter="BorderVertical_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="1" Background="Black"/>
<Border MouseLeftButtonDown="WindowResizeWest" MouseEnter="BorderVertical_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="1" Background="Black"/>
<Border MouseLeftButtonDown="WindowResizeNorth" MouseEnter="BorderHorizontal_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="1" Background="Black"/>
<Border MouseLeftButtonDown="WindowResizeSouth" MouseEnter="BorderHorizontal_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="1" Background="Black"/>
<Border VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="20" Height="20" MouseEnter="BorderSouthEast_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown">
<Grid>
<Path Stroke="Gray" StrokeThickness="1" Data=" M 5 20 L 20 5 M 10 20 L 20 10 M 15 20 L 20 15"/>
</Grid>
</Border>
</Grid>
</Window>
主窗口代码:
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using PrmWpf.Services;
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
private void WindowResizeNorth(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Top, IntPtr.Zero);
}
private void WindowResizeSouth(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Bottom, IntPtr.Zero);
}
private void WindowResizeWest(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Left, IntPtr.Zero);
}
private void WindowResizeEast(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Right, IntPtr.Zero);
}
private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, Bottom = 61446, BottomRight = 61448, }
private void BorderVertical_OnMouseEnter(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.SizeWE;
}
private void BorderHorizontal_OnMouseEnter(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.SizeNS;
}
private void BorderAll_OnMouseLeave(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.Arrow;
}
private void BorderSouthEast_OnMouseEnter(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.SizeNWSE;
}
private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.BottomRight, IntPtr.Zero);
}
}
我有一个无边界透明 wpf window (WindowStyle=None),我希望能够从各个方向调整大小。如果我设置 ResizeMode=CanResizeWithGrip,目前调整大小仅适用于上述设置。这对于视觉提示来说很好,但不是很好,因为您只能从一个角调整大小。
我想用装饰器来做这个,所以当 window 处于调整大小模式(可以打开和关闭)时,我也可以给出视觉提示。这可能吗?如果是这样,我该怎么做?
这个问题已经在 Whosebug 上的某个地方得到了回答。我现在真的找不到了,但我是这样做的。
主窗口:
<Window x:Class="Solution.Views.Main.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" MinWidth="1000" MinHeight="500" WindowStyle="None" AllowsTransparency="False" BorderThickness="0" ResizeMode="NoResize">
<Window.TaskbarItemInfo>
<TaskbarItemInfo />
</Window.TaskbarItemInfo>
<Grid>
<Border MouseLeftButtonDown="WindowResizeEast" MouseEnter="BorderVertical_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="1" Background="Black"/>
<Border MouseLeftButtonDown="WindowResizeWest" MouseEnter="BorderVertical_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="1" Background="Black"/>
<Border MouseLeftButtonDown="WindowResizeNorth" MouseEnter="BorderHorizontal_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="1" Background="Black"/>
<Border MouseLeftButtonDown="WindowResizeSouth" MouseEnter="BorderHorizontal_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="1" Background="Black"/>
<Border VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="20" Height="20" MouseEnter="BorderSouthEast_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown">
<Grid>
<Path Stroke="Gray" StrokeThickness="1" Data=" M 5 20 L 20 5 M 10 20 L 20 10 M 15 20 L 20 15"/>
</Grid>
</Border>
</Grid>
</Window>
主窗口代码:
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using PrmWpf.Services;
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
private void WindowResizeNorth(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Top, IntPtr.Zero);
}
private void WindowResizeSouth(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Bottom, IntPtr.Zero);
}
private void WindowResizeWest(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Left, IntPtr.Zero);
}
private void WindowResizeEast(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Right, IntPtr.Zero);
}
private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, Bottom = 61446, BottomRight = 61448, }
private void BorderVertical_OnMouseEnter(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.SizeWE;
}
private void BorderHorizontal_OnMouseEnter(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.SizeNS;
}
private void BorderAll_OnMouseLeave(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.Arrow;
}
private void BorderSouthEast_OnMouseEnter(object sender, MouseEventArgs e)
{
Mouse.OverrideCursor = Cursors.SizeNWSE;
}
private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.BottomRight, IntPtr.Zero);
}
}