[C#] 拖拉 Windows Form 的 Component
最近有需要想將 Windows Form 上的元件(例如 Label、Button)隨使用者自由拖拉,雖然事件都有 Drag 相關的可以使用,但查了一下似乎不是我想要的,這些 DragDrop()、DrapOver() 事件還有 AllowDrop 屬性好像是拖拉資料,並不是拖拉元件,只好手動用 MouseDown()、MouseMove()、MouseUp() 事件來組合。首先如下兩圖,先設置了一個 Label 叫 label1,有設定背景色和 AutoSize = false,左圖是本來的位置,右圖是用滑鼠左鍵拖拉後的結果:
這些滑鼠事件的參數 MouseEventArgs e 有 X 和 Y 兩個屬性,是滑鼠相對於元件的坐標,不是相對整個表單,也不是相對整個螢幕,例如:
其實相對於什麼倒也不是這麼重要,只要得到位移向量,就能找出後來元件新的位置為何,如下圖,首先要兩個點:P 為最開始點擊 MouseDown() 事件時的定點,而 Q 為 MouseMove() 過程任何時候的動點,然後用PQ連出的向量 t,加上原來物件相對於整個表單的坐標向量 u,就得到物件新的位置的坐標向量 v:
P 點就是 MouseMove() 事件中要先取到的 clickPoint,而 Q 點是 MouseMove() 事件中不停變動的 ( e.X , e.Y ),向量 t 為 ( e.X - clickPoint.X , e.Y - clickPoint.Y ),這個向量 t 再加上之前物件 Location 就得新的 Location ,也就是 ( Location.X + e.X - clickPoint.X , Location.Y + e.Y - clickPoint.Y ),參考程式碼如下:
namespace DragComponentDemo { public partial class Form1 : Form { bool isDraging = false; Point clickPoint; public Form1() { InitializeComponent(); } private void label1_MouseDown(object sender, MouseEventArgs e) { isDraging = true; // 當按下滑鼠按鍵(左右鍵皆可),開始拖拉模式 clickPoint = new Point(e.X, e.Y); // 記下最初按鍵點選的坐標 } private void label1_MouseMove(object sender, MouseEventArgs e) { if (isDraging) { Label obj = (Label)sender; obj.Location = new Point( obj.Location.X + e.X - clickPoint.X, //將此物件(Label)的坐標重設 obj.Location.Y + e.Y - clickPoint.Y); } } private void label1_MouseUp(object sender, MouseEventArgs e) { isDraging = false; // 放開滑鼠按鍵則離開拖拉模式 } } }
留言
張貼留言