我的天堂」想你的代碼,但我所看到的只是部分正確:-)
您保存初始座標,這是相對於點擊左上角的控件,但您需要保存屏幕座標。
然後,鼠標移動,並再次得到相對於該角落的一個點。你錯過了一些相關的事情:
- 你需要計算基礎上,屏幕座標的兩個點之間的增量,下方的光標爲您提供了錯誤的值,否則移動窗口。
- 您需要此增量添加到窗體的當前位置
- 您需要保存新的鼠標位置來計算正確
基於屏幕座標當前鼠標的位置可以得到下一個增量通過Cursor.Position
。
所以,你的代碼應該閱讀:
private void lblHeader_MouseDown(object sender, MouseEventArgs e)
{
isDragging = true; // _dragging is your variable flag
startPoint = Cursor.Position;
}
private void lblHeader_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void lblHeader_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Point p = Cursor.Position;
int deltaX = p.X - startPoint.X;
int deltaY = p.Y - startPoint.Y;
startPoint = p;
this.Left += deltaX;
this.Top += deltaY;
}
}
我剛纔放置在窗體上面板和implented以上,其工作。當他說,這種做法其實是不太好,因爲它沒有考慮到的Windows實際上可以處理這一切都爲您
@IInspector是正確的。
的另一種方法(和最好的一個)我會帶是:
- 覆蓋所述
WndProc
方法如下所示
- 完成。沒有更多的鼠標處理
以下是你如何能重寫的WndProc做你所需要的一個例子:
protected override void WndProc(ref Message m)
{
const UInt32 WM_NCHITTEST = 0x0084;
const UInt32 HTCAPTION = 0x2;
bool handled = false;
if (m.Msg == WM_NCHITTEST)
{
if (<cursor is within the caption area>)
{
m.Result = (IntPtr)HTCAPTION;
handled = true;
}
}
if (!handled)
base.WndProc(ref m);
}
要限制該窗口可以移動到的區域,你可以使用以下內容。當然,@IInspectable會不同意,但你去這條道路:-)
private void lblHeader_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
Point p = Cursor.Position;
int deltaX = p.X - startPoint.X;
int deltaY = p.Y - startPoint.Y;
startPoint = p;
int fX = this.Left + deltaX;
int fY = this.Top + deltaY;
if (fX >= 0 && fX + this.Width < Area.Width) this.Left = fX;
if (fY >= 0 && f> + this.Height < Area.Height) this.Top = fY;
}
}
是你要移動頭部或形式..爲「this.location」移動形式...... – BugFinder
你真的認爲這樣使用自定義鑲邊是個好主意?將窗口保持原樣並讓*用戶選擇它將如何顯示會出現什麼問題?如果你堅持,看看非客戶區在Windows中是如何工作的 - 很容易以任何你想要的方式重新繪製非客戶區,擴展它,或者甚至假裝窗口客戶區的一部分實際上是一個與客戶端對應的非客戶端區域(並讓Windows爲您做出拖動)。 – Luaan
如果鼠標移過標籤並點擊。表單的位置發生了變化。 – user2115618