C#表单控件移动

反正有控制你可以移动表格的地方吗?

因此,如果我移动一个表格,它只能在垂直轴上移动,当我尝试水平移动时,没有任何反应。

我不想要像changechanged或move事件那样的bug实现并将其弹回内联。 我没有办法使用类似WndProc覆盖的东西,但在搜索了一段时间后,我找不到任何东西。 请帮忙

您很可能希望覆盖WndProc并处理WM_MOVING消息。 根据MSDN :

WM_MOVING消息被发送到用户正在移动的窗口。 通过处理此消息,应用程序可以监视拖动矩形的位置,并在需要时更改其位置。

这是一种方法,但是,您显然需要根据自己的需要进行调整:

using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows.Forms; namespace VerticalMovingForm { public partial class Form1 : Form { private const int WM_MOVING = 0x0216; private readonly int positionX; private readonly int positionR; public Form1() { Left = 400; Width = 500; positionX = Left; positionR = Left + Width; } protected override void WndProc(ref Message m) { if (m.Msg == WM_MOVING) { var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT)); r.Left = positionX; r.Right = positionR; Marshal.StructureToPtr(r, m.LParam, false); } base.WndProc(ref m); } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } } } 

例如:

 using System.Runtime.InteropServices; protected override void WndProc(ref Message m) { if (m.Msg == 0x216) // WM_MOVING = 0x216 { Rectangle rect = (Rectangle) Marshal.PtrToStructure(m.LParam, typeof (Rectangle)); if (rect.Left < 100) { // compensates for right side drift rect.Width = rect.Width + (100 - rect.Left); // force left side to 100 rect.X = 100; Marshal.StructureToPtr(rect, m.LParam, true); } } base.WndProc(ref m); } 

上面的代码设置最小左手位置为100。

没有必要重新创建RECT结构,就像driis那样,.NET原生Rectangle工作得很好。 但是,您必须通过X属性设置位置,因为Left是Get only属性。

VB.NET版本:

 Protected Overloads Overrides Sub WndProc(ByRef m As Message) If m.Msg = &H216 Then ' WM_MOVING = 0x216 Dim rect As Rectangle = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(Rectangle)), Rectangle) If rect.Left < 100 Then ' compensates for right side drift rect.Width = rect.Width + (100 - rect.Left) ' force left side to 100 rect.X = 100 Marshal.StructureToPtr(rect, m.LParam, True) End If End If MyBase.WndProc(m) End Sub