700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > WPF 无边框拖动

WPF 无边框拖动

时间:2019-11-07 00:00:34

相关推荐

WPF 无边框拖动

无边框之后的拖动方法有三种。

我个人是喜欢第一和第三的方法,看个人去需求。

第三种代码比较仓促,有需要者可以立马用,或者稍作整理修改。

对于WIN10 .NET 4.5以上的框架可以使用

WIndowChrome

<WindowChrome.WindowChrome><WindowChrome CaptionHeight="50" /></WindowChrome.WindowChrome>

其次是

通过DragMove方法来控制移动 此方法需要写在事件内,比如鼠标事件等

private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){(sender as Window).DragMove();}

不过这个方法有些缺陷。

例如全屏之后无法通过鼠标移动恢复

再者就是WIn32API

先给出两份参考:

/xuchonglei/archive//04/12/913.html

/dlangu0393/article/details/12548731

我这里直接给出带代码

我是用behavior来配合的

public class WinMove : Behavior<Grid>{protected override void OnAttached(){base.OnAttached();AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;var b = new WindowBehaviorHelper(AssociatedObject.GetParentObject<Window>(null));b.RepairBehavior();}private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){if (e.OriginalSource is Grid || e.OriginalSource is Border || e.OriginalSource is Window){WindowInteropHelper wih = new WindowInteropHelper(AssociatedObject.GetParentObject<Window>(null));//我附加在grid上 用来寻找窗口的WindowBehaviorHelper.SendMessage(wih.Handle, 0x00A1, (IntPtr)WindowBehaviorHelper.HitTest.HTCAPTION, IntPtr.Zero);return;}}protected override void OnDetaching(){base.OnDetaching();AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;}}public class WindowBehaviorHelper{private const int WM_NCHITTEST = 0x0084; //测试消息private const int WM_GETMINMAXINFO = 0x0024;//大小变化private Window WindowTarget;//目标窗口private int WidthCorner = 4;//拐角宽度private int ThicknessTransparentBorder = 5; //透明宽度private int ThicknessBorder = 4; //边框宽度private Point PointMouse = new Point();//鼠标坐标public enum HitTest : int //测试句柄 {#region 测试句柄HTERROR = -2,HTTRANSPARENT = -1,HTNOWHERE = 0,HTCLIENT = 1,HTCAPTION = 2,HTSYSMENU = 3,HTGROWBOX = 4,HTSIZE = HTGROWBOX,HTMENU = 5,HTHSCROLL = 6,HTVSCROLL = 7,HTMINBUTTON = 8,HTMAXBUTTON = 9,HTLEFT = 10,HTRIGHT = 11,HTTOP = 12,HTTOPLEFT = 13,HTTOPRIGHT = 14,HTBOTTOM = 15,HTBOTTOMLEFT = 16,HTBOTTOMRIGHT = 17,HTBORDER = 18,HTREDUCE = HTMINBUTTON,HTZOOM = HTMAXBUTTON,HTSIZEFIRST = HTLEFT,HTSIZELAST = HTBOTTOMRIGHT,HTOBJECT = 19,HTCLOSE = 20,HTHELP = 21#endregion}//构造函数public WindowBehaviorHelper(Window window){this.WindowTarget = window;}public IntPtr handle;//修复行为public void RepairBehavior(){if (WindowTarget == null)return;this.WindowTarget.SourceInitialized += delegate{handle = (new WindowInteropHelper(WindowTarget)).Handle;HwndSource hwndSource = HwndSource.FromHwnd(handle);if (hwndSource != null){hwndSource.AddHook(WindowProc);}};}//消息循环private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){switch (msg){case WM_NCHITTEST:if (WindowTarget.WindowState != WindowState.Normal){break;}this.PointMouse.X = (lParam.ToInt32() & 0xFFFF);this.PointMouse.Y = (lParam.ToInt32() >> 16);//窗口左上角if (this.PointMouse.X > this.WindowTarget.Left + this.ThicknessTransparentBorder&& this.PointMouse.X <= this.WindowTarget.Left + this.ThicknessTransparentBorder + this.WidthCorner&& this.PointMouse.Y > this.WindowTarget.Top + this.ThicknessTransparentBorder&& this.PointMouse.Y <= this.WindowTarget.Top + this.ThicknessTransparentBorder + this.WidthCorner){handled = true;return new IntPtr((int)HitTest.HTTOPLEFT);}//窗口左下角else if (this.PointMouse.X > this.WindowTarget.Left + this.ThicknessTransparentBorder&& this.PointMouse.X <= this.WindowTarget.Left + this.ThicknessTransparentBorder + this.WidthCorner&& this.PointMouse.Y < this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder&& this.PointMouse.Y >= this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder - this.WidthCorner){handled = true;return new IntPtr((int)HitTest.HTBOTTOMLEFT);}//窗口右上角else if (this.PointMouse.X < this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder&& this.PointMouse.X >= this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder - this.WidthCorner&& this.PointMouse.Y > this.WindowTarget.Top + this.ThicknessTransparentBorder&& this.PointMouse.Y <= this.WindowTarget.Top + this.ThicknessTransparentBorder + this.WidthCorner){handled = true;return new IntPtr((int)HitTest.HTTOPRIGHT);}//窗口右下角else if (this.PointMouse.X < this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder&& this.PointMouse.X >= this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder - this.WidthCorner&& this.PointMouse.Y < this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder&& this.PointMouse.Y >= this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder - this.WidthCorner){handled = true;return new IntPtr((int)HitTest.HTBOTTOMRIGHT);}//窗口左侧else if (this.PointMouse.X > this.WindowTarget.Left + this.ThicknessTransparentBorder&& this.PointMouse.X <= this.WindowTarget.Left + this.ThicknessTransparentBorder + this.ThicknessBorder&& this.PointMouse.Y > this.WindowTarget.Top + this.ThicknessTransparentBorder&& this.PointMouse.Y < this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder){handled = true;return new IntPtr((int)HitTest.HTLEFT);}//窗口右侧else if (this.PointMouse.X < this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder&& this.PointMouse.X >= this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder - this.ThicknessBorder&& this.PointMouse.Y > this.WindowTarget.Top + this.ThicknessTransparentBorder&& this.PointMouse.Y < this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder){handled = true;return new IntPtr((int)HitTest.HTRIGHT);}//窗口上方else if (this.PointMouse.X > this.WindowTarget.Left + this.ThicknessTransparentBorder&& this.PointMouse.X < this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder&& this.PointMouse.Y > this.WindowTarget.Top + this.ThicknessTransparentBorder&& this.PointMouse.Y <= this.WindowTarget.Top + this.ThicknessTransparentBorder + this.ThicknessBorder){handled = true;return new IntPtr((int)HitTest.HTTOP);}//窗口下方else if (this.PointMouse.X > this.WindowTarget.Left + this.ThicknessTransparentBorder&& this.PointMouse.X < this.WindowTarget.Left + this.WindowTarget.ActualWidth - this.ThicknessTransparentBorder&& this.PointMouse.Y < this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder&& this.PointMouse.Y >= this.WindowTarget.Top + this.WindowTarget.ActualHeight - this.ThicknessTransparentBorder - this.ThicknessBorder){handled = true;return new IntPtr((int)HitTest.HTBOTTOM);}//其他消息else{SendMessage(handle, (int)0x00A1, (IntPtr)HitTest.HTCAPTION, IntPtr.Zero);break;}case WM_GETMINMAXINFO:WmGetMinMaxInfo(hwnd, lParam);handled = true;break;default:break;}return IntPtr.Zero;}//更改最小化最大化时窗口位置大小private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam){MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));int MONITOR_DEFAULTTONEAREST = 0x00000002;IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);if (monitor != IntPtr.Zero){MONITORINFO monitorInfo = new MONITORINFO();GetMonitorInfo(monitor, monitorInfo);RECT rcWorkArea = monitorInfo.rcWork;RECT rcMonitorArea = monitorInfo.rcMonitor;mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left) - 3;mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top) - 3;mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left) + 6;mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top) + 6;mmi.ptMinTrackSize.x = (int)this.WindowTarget.MinWidth;mmi.ptMinTrackSize.y = (int)this.WindowTarget.MinHeight;}Marshal.StructureToPtr(mmi, lParam, true);}[DllImport("user32")]internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);[DllImport("User32")]internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);[DllImport("user32.dll")]public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);#region Nested type: MINMAXINFO[StructLayout(LayoutKind.Sequential)]internal struct MINMAXINFO{public POINT ptReserved;public POINT ptMaxSize;public POINT ptMaxPosition;public POINT ptMinTrackSize;public POINT ptMaxTrackSize;}#endregion#region Nested type: MONITORINFO[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]internal class MONITORINFO{public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));public RECT rcMonitor;public RECT rcWork;public int dwFlags;}#endregion#region Nested type: POINT[StructLayout(LayoutKind.Sequential)]internal struct POINT{public int x;public int y;public POINT(int x, int y){this.x = x;this.y = y;}}#endregion#region Nested type: RECT[StructLayout(LayoutKind.Sequential, Pack = 0)]internal struct RECT{public int left;public int top;public int right;public int bottom;public static readonly RECT Empty;public int Width{get { return Math.Abs(right - left); }}public int Height{get { return bottom - top; }}public RECT(int left, int top, int right, int bottom){this.left = left;this.top = top;this.right = right;this.bottom = bottom;}public RECT(RECT rcSrc){left = rcSrc.left;top = rcSrc.top;right = rcSrc.right;bottom = rcSrc.bottom;}public bool IsEmpty{get{return left >= right || top >= bottom;}}public override string ToString(){if (this == Empty){return "RECT {Empty}";}return "RECT { left : " + left + " / top : " + top + " / right : " + right + " / bottom : " + bottom + " }";}public override bool Equals(object obj){if (!(obj is Rect)){return false;}return (this == (RECT)obj);}public override int GetHashCode(){return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode();}public static bool operator ==(RECT rect1, RECT rect2){return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom);}public static bool operator !=(RECT rect1, RECT rect2){return !(rect1 == rect2);}}#endregion}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。