我正在使用 MouseMove、MouseUp、MouseDown 事件來移動無邊框表單(如在此處找到的示例)。
它作業得很好,但對于 ListViews,它只有在我單擊串列中的一個專案(其文本)時才有效。如果我單擊不包含任何專案的 ListView 的空間,它將不起作用。
有沒有辦法解決這個問題?
private bool mouseDown;
private Point lastLocation;
private void ListView1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
lastLocation = e.Location;
}
private void ListView1_MouseMove(object sender, MouseEventArgs e)
{
if(mouseDown)
{
this.Location = new Point(
(this.Location.X - lastLocation.X) e.X, (this.Location.Y - lastLocation.Y) e.Y);
this.Update();
}
}
private void ListView1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
uj5u.com熱心網友回復:
要移動表單,單擊并拖動任何控制元件,您可以實作IMessageFilter 介面。您將在將訊息發送到目標 Control 之前收到訊息(可以選擇抑制它們,回傳true)。
該實作要求您實作PreFilterMessage。
當訊息為 時存盤當前滑鼠位置WM_LBUTTONDOWN并在它為時移動表單WM_MOUSEMOVE,如果左按鈕仍被按下(當前按下的按鈕在 中指定WParam,請參閱有關此的檔案)。
使用Application.AddMessageFilter注冊實作介面的類(在本例中為 Form 本身)。在這里,它被稱為OnHandleCreated.
呼叫Application.RemoveMessageFilter以洗掉過濾器。在這里,叫進來OnHandleDestroyed。
請注意,我在 中使用Capture = true;過WM_MOUSEMOVE,因此按下滑鼠左鍵并拖動(例如,按鈕控制元件)不會導致(在這種情況下)發生 Click 事件。
不喜歡就修改。
注意:正如 Reza Aghaei 所建議的,如果將 ListView 設定為MultiSelect = false,則可以單擊其上的任意位置以拖動表單。
public partial class SomeForm : Form, IMessageFilter
{
private const int WM_MOUSEMOVE = 0x0200;
private const int WM_LBUTTONDOWN = 0x0201;
Point mouseDownPos = Point.Empty;
public bool PreFilterMessage(ref Message m) {
switch (m.Msg) {
case WM_LBUTTONDOWN:
mouseDownPos = PointToClient(MousePosition);
break;
case WM_MOUSEMOVE:
if ((m.WParam.ToInt32() & 1) != 1) break;
Capture = true;
var p = PointToClient(MousePosition);
Location = new Point(Left p.X - mouseDownPos.X, Top p.Y - mouseDownPos.Y);
break;
}
return false;
}
protected override void OnHandleCreated(EventArgs e) {
base.OnHandleCreated(e);
if (!DesignMode) Application.AddMessageFilter(this);
}
protected override void OnHandleDestroyed(EventArgs e) {
if (!DesignMode) Application.RemoveMessageFilter(this);
base.OnHandleDestroyed(e);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/429708.html
