WPF 无边框拖动
无边框之后的拖动方法有三种。
我个人是喜欢第一和第三的方法,看个人去需求。
第三种代码比较仓促,有需要者可以立马用,或者稍作整理修改。
对于WIN10 .NET 4.5以上的框架可以使用
WIndowChrome
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="" />
</WindowChrome.WindowChrome>
其次是
通过DragMove方法来控制移动 此方法需要写在事件内,比如鼠标事件等
private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
(sender as Window).DragMove();
}
不过这个方法有些缺陷。
例如全屏之后无法通过鼠标移动恢复
再者就是WIn32API
先给出两份参考:
http://www.cnblogs.com/xuchonglei/archive/2011/04/12/2013913.html
https://blog.csdn.net/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 = ; //拐角宽度
private int ThicknessTransparentBorder = ; //透明宽度
private int ThicknessBorder = ; //边框宽度
private Point PointMouse = new Point(); //鼠标坐标
public enum HitTest : int //测试句柄
{
#region 测试句柄 HTERROR = -,
HTTRANSPARENT = -,
HTNOWHERE = ,
HTCLIENT = ,
HTCAPTION = ,
HTSYSMENU = ,
HTGROWBOX = ,
HTSIZE = HTGROWBOX,
HTMENU = ,
HTHSCROLL = ,
HTVSCROLL = ,
HTMINBUTTON = ,
HTMAXBUTTON = ,
HTLEFT = ,
HTRIGHT = ,
HTTOP = ,
HTTOPLEFT = ,
HTTOPRIGHT = ,
HTBOTTOM = ,
HTBOTTOMLEFT = ,
HTBOTTOMRIGHT = ,
HTBORDER = ,
HTREDUCE = HTMINBUTTON,
HTZOOM = HTMAXBUTTON,
HTSIZEFIRST = HTLEFT,
HTSIZELAST = HTBOTTOMRIGHT,
HTOBJECT = ,
HTCLOSE = ,
HTHELP = #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() >> ); //窗口左上角
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) - ;
mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top) - ;
mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left) + ;
mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top) + ;
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 = )]
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
}
WPF 无边框拖动的更多相关文章
- WPF无边框拖动、全屏、缩放
原文:WPF无边框拖动.全屏.缩放 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/lwwl12/article/details/78059361 先看效果 ...
- C# .net WPF无边框移动窗体
转自 http://download.csdn.net/detail/xiang348352/3095084 WPF无边框移动窗体,先在<Window>里添加 MouseLeftButto ...
- wpf无边框窗体移动和大小调整
原文:wpf无边框窗体移动和大小调整 using System; using System.Windows; using System.Windows.Interop; namespace Wpf ...
- WPF无边框捕获消息改变窗口大小
原文:WPF无边框捕获消息改变窗口大小 文章大部分转载自http://blog.csdn.net/fwj380891124,如有问题,请联系删除 最近一直在学习 WPF,看着别人做的WPF程序那么漂 ...
- WPF无边框移动窗体
WPF无边框移动窗体,先在<Window>里添加 MouseLeftButtonDown=”Window_MouseLeftButtonDown” 然后导航到事件,在事件里添加 if (e ...
- winform学习(9)无边框拖动窗体
去除边框 选中窗体,在属性中找到FormBorderStyle,设置为None 实现无边框拖动 [DllImport("user32.dll")] public st ...
- WPF无边框可拖动窗体
下面主要记录下创建无边框窗体,并且可以拖动.这种窗体主要用于弹出小窗体时. <Window x:Class="WpfApplication1.MainWindow" xmln ...
- 【转载】 wpf无边框的方法以及拖拽的问题
今天在做wpf程序的时候遇到了一个制作无边框的窗体并且有透明圆角的问题,我把解决的过程写下来,和大家学习 正常窗体必须把WindowStyle="None"这个属性加上去,但是加上 ...
- WPFの无边框窗体以及控件的移动
对于WPF,一旦隐藏了标题栏,就无法移动,这时候需要重写移动方法,下面列举常见的三种方式方式. 方式一:重写OnMouseLeftButtonDown protected override void ...
随机推荐
- Python处理文本换行符
源文件每行后面都有回车,所以用下面输出时,中间会多了一行 try: with open("F:\\hjt.txt" ) as f : for line in f: print(li ...
- ELK Stack 5.2.2 安装文档
简介: ELK Stack 安装文档,这次都使用最新版本(5.2.2).RPM 包的方式搭建 ELK Stack. 下载地址: https://artifacts.elastic.co/downloa ...
- Jboss:The LogManager was not properly installed (you must set the "java.util.logging.manager" system prop
可能是jboss的服务器版本选择不对 ,比如我本地的Jboss服务器版本是 jboss-as-web-7.0.2.Final,选择的服务器版本是JBOOS V7.1 Runtime ,就会报上面 ...
- Defer 声明的设计理念
[Defer 声明的设计理念] A defer statement pushes a function call onto a list. The list of saved calls is exe ...
- 2015年传智播客JavaEE 第168期就业班视频教程14-登录功能需求分析+模块结构命名规范
得先造一个模块,来封装我们的员工模型.登录的就是我们的员工嘛.员工模块属于权限校验系列的,校验叫做auth.进销存模块叫做cn.itcast.erp.invoice.权限模块叫做cn.itcast.e ...
- 利用 Chrome 原生工具进行网页长截图
转自https://sspai.com/post/42193 要想使用截图功能,你需要首先确保 Chrome 已升级至 59 或更高版本.在想要截图的网页中,首先按下 ⌘Command + ⌥Opti ...
- UNITY中有Timer
using UnityEngine; using System.Collections; using System.Timers; public class NewBehaviourScript : ...
- 286被围绕的区域 · Surrounded Regions
[抄题]: 给一个二维的矩阵,包含 'X' 和 'O', 找到所有被 'X' 围绕的区域,并用 'X' 填充满. 样例 给出二维矩阵: X X X X X O O X X X O X X O X X ...
- QByteArray to QString
QByteArray => QString void BarEngine::ByteArrayToString(QByteArray &ba, QString &str) { i ...
- ibatis 常用标签
prepend:自动在前面加上:自动新手:自动预:自动前置 property:属性 compareValue:指定的常数,值 //判断不相等: <isNotEqual prepend=" ...