WPF窗口设置NoResize属性后自定义窗口拖动缩放

在xmal中添加如下控件,分别标记左、右、上、下各条边以及左上、右上、左下、右下四个角,当鼠标移入、移出、鼠标点击时分别触发设置鼠标图标、重置图标、触发resize等操作

c 复制代码
<Path x:Name="ResizeNW" VerticalAlignment="Top" HorizontalAlignment="Left"
      Stroke="Green" StrokeThickness="4" Margin="0" MouseEnter="DisplayResizeCursor"
           MouseLeave="ResetCursor" PreviewMouseLeftButtonDown="Resize">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigureCollection>
                    <PathFigure StartPoint="0,10">
                        <PathFigure.Segments>
                            <PathSegmentCollection>
                                <QuadraticBezierSegment Point1="0,0" Point2="10,0" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
<Path x:Name="ResizeNE" VerticalAlignment="Top" HorizontalAlignment="Right"
      Stroke="Green" 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>
                                <QuadraticBezierSegment Point1="10,0" Point2="10,10" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
<Path x:Name="ResizeSE" VerticalAlignment="Bottom" HorizontalAlignment="Right"
      Stroke="Green" 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>
                                <QuadraticBezierSegment Point1="10,10" Point2="0,10" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>
<Path x:Name="ResizeSW" VerticalAlignment="Bottom" HorizontalAlignment="Left"
      Stroke="Green" 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>
                                <QuadraticBezierSegment Point1="0,10" Point2="10,10" />
                            </PathSegmentCollection>
                        </PathFigure.Segments>
                    </PathFigure>
                </PathFigureCollection>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>

自定义窗口的实现代码如下:

c 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace ResizableWindow
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private const int WM_SYSCOMMAND = 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 Window1()
        {
            SourceInitialized += Window1_SourceInitialized;

            InitializeComponent();
        }

        private void Window1_SourceInitialized( object sender, EventArgs e )
        {
            hwndSource = PresentationSource.FromVisual( (Visual)sender ) as HwndSource;
        }

        private void ResizeWindow( ResizeDirection direction )
        {
            SendMessage( hwndSource.Handle, WM_SYSCOMMAND, (IntPtr)direction, IntPtr.Zero );
        }

        protected void ResetCursor( object sender, MouseEventArgs e )
        {
            if( Mouse.LeftButton != MouseButtonState.Pressed )
            {
                this.Cursor = Cursors.Arrow;
            }
        }

        protected void Resize( object sender, MouseButtonEventArgs e )
        {
            var clickedShape = sender as Shape;

            switch( clickedShape.Name )
            {
                case "ResizeN":
                    this.Cursor = Cursors.SizeNS;
                    ResizeWindow( ResizeDirection.Top );
                    break;
                case "ResizeE":
                    this.Cursor = Cursors.SizeWE;
                    ResizeWindow( ResizeDirection.Right );
                    break;
                case "ResizeS":
                    this.Cursor = Cursors.SizeNS;
                    ResizeWindow( ResizeDirection.Bottom );
                    break;
                case "ResizeW":
                    this.Cursor = Cursors.SizeWE;
                    ResizeWindow( ResizeDirection.Left );
                    break;
                case "ResizeNW":
                    this.Cursor = Cursors.SizeNWSE;
                    ResizeWindow( ResizeDirection.TopLeft );
                    break;
                case "ResizeNE":
                    this.Cursor = Cursors.SizeNESW;
                    ResizeWindow( ResizeDirection.TopRight );
                    break;
                case "ResizeSE":
                    this.Cursor = Cursors.SizeNWSE;
                    ResizeWindow( ResizeDirection.BottomRight );
                    break;
                case "ResizeSW":
                    this.Cursor = Cursors.SizeNESW;
                    ResizeWindow( ResizeDirection.BottomLeft );
                    break;
                default:
                    break;
            }
        }

        protected void DisplayResizeCursor( object sender, MouseEventArgs e )
        {
            var clickedShape = sender as Shape;

            switch( clickedShape.Name )
            {
                case "ResizeN":
                case "ResizeS":
                    this.Cursor = Cursors.SizeNS;
                    break;
                case "ResizeE":
                case "ResizeW":
                    this.Cursor = Cursors.SizeWE;
                    break;
                case "ResizeNW":
                case "ResizeSE":
                    this.Cursor = Cursors.SizeNWSE;
                    break;
                case "ResizeNE":
                case "ResizeSW":
                    this.Cursor = Cursors.SizeNESW;
                    break;
                default:
                    break;
            }
        }

        protected void DragWindow( object sender, MouseButtonEventArgs e )
        {
            DragMove();
        }
    }
}
相关推荐
FuckPatience19 小时前
WPF DataGrid 行根据某个属性循环变色动画
wpf
一条闲鱼_mytube3 天前
高并发短链接系统设计
wpf
一个天蝎座 白勺 程序猿4 天前
IoTDB集群扩容:从慌乱到从容的经验分享
数据库·wpf·时序数据库·iotdb
samble5 天前
从零搭建灌装监控系统(十三):报警系统设计,生命周期与通知
c#·wpf·mvvm·modbus·工业控制
samble5 天前
从零搭建灌装监控系统(十二):配置系统,原子写入与容错
c#·wpf·mvvm·modbus·工业控制
蜗牛互联网8 天前
OLMo-core 3的token gerrymandering提醒:MoE路由要按时间窗验收
java·人工智能·wpf
LateFrames8 天前
WPF 升级选型:用 .NET 8 还是 .NET 10
.net·wpf·.net8·.net10
samble8 天前
从零搭建灌装监控系统(十):生产追溯,条码触发自动记录
c#·wpf·mvvm·modbus·工业控制
SamChan9011 天前
PDF页面旋转与CropBox陷阱:译文回填位置总是错位的根因实测
python·ai·pdf·wpf
SamChan9012 天前
PDF翻译时页眉页脚总在捣乱?跨页重复文本块的检测与过滤实测
人工智能·python·ai·pdf·wpf