控件移動的關鍵點就是需要設計一個獨立於任何控件的類(UIMoveKnob)來控制控件的移動。我這裏實現的方法只針對一個控件,如果需要同時選擇多個控件,然後同時移動的話,你需要修改這個類,這裏是有點難於控制,我使用的方法嚴重耦合,所以只在這裏給出移動一個控件的辦法,具體移動過個控件的方法請各位討論。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
要移動某個選定的控件,我們需要實現控件的:
MouseDown
MouseMove
MouseUp
這3個事件。
在MouseDown的時候,記錄鼠標點擊的開始位置,並設置開始移動標誌爲True;
在MouseMove的時候,把控件移動相應的距離(當前鼠標位置 – 鼠標點擊的開始位置);
在MouseUp的時候,釋放移動標誌爲false。
有了控件移動控制類(UIMoveKnob)以後,我們怎麼實現UIMoveKnob和具體控件的關聯呢?同樣,我們需要在Form中增加一個變量private Hashtable _HashUIMoveKnob用於緩存每個控件對應的UIMoveKnob對象。
同時在Form.ControlAdded事件中,通過this._HashUIMoveKnob.Add(e.Control, new UIMoveKnob(e.Control));設置其關聯性。
UIMoveKnob的代碼如下:
- public class UIMoveKnob
- {
- private System.Windows.Forms.Control _Owner;
- private int _MouseClickAtX;
- private int _MouseClickAtY;
- private bool _BeginDrag;
- public UIMoveKnob(System.Windows.Forms.Control Owner)
- {
- this._Owner = Owner;
- this._Owner.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Owner_MouseDown);
- this._Owner.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Owner_MouseMove);
- this._Owner.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Owner_MouseUp);
- }
- void Owner_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- this._Owner.Cursor = System.Windows.Forms.Cursors.Default;
- this._MouseClickAtX = e.X;
- this._MouseClickAtY = e.Y;
- this._BeginDrag = true;
- }
- void Owner_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- try
- {
- if (this._BeginDrag)
- {
- Rectangle rect;
- /*
- * 對於下列控件,是不能拖動的,所以這裏也不繪製拖動邊框
- * TabPage,
- */
- if (this._Owner is System.Windows.Forms.TabPage)
- {
- //
- }
- else
- {
- this._Owner.Location = new Point(this._Owner.Left + e.X - this._MouseClickAtX, this._Owner.Top + e.Y - this._MouseClickAtY);
- }
- }
- }
- catch { }
- }
- void Owner_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
- {
- this._BeginDrag = false;
- this._Owner.Parent.Refresh();
- }
- }
修改後的Form代碼前半部分如下:
- private MouseHook _MouseHook;
- //我們將所有的已經與具體控件關聯了的UISizeKnob緩存在這個HashTable中
- private Hashtable _HashUISizeKnob;
- //負責控件移動的類
- private Hashtable _HashUIMoveKnob;
- public Form1()
- {
- InitializeComponent();
- this._MouseHook = new MouseHook(this);
- this._HashUISizeKnob = new Hashtable();
- this._HashUIMoveKnob = new Hashtable();
- //爲了簡潔明瞭,我們在ControlAdded中來設置具體控件和UISizeKnob的關聯
- this.ControlAdded += new ControlEventHandler(Form1_ControlAdded);
- }
- void Form1_ControlAdded(object sender, ControlEventArgs e)
- {
- if (!(e.Control is UISizeDot))
- {
- this._HashUISizeKnob.Add(e.Control, new UISizeKnob(e.Control));
- this._HashUIMoveKnob.Add(e.Control, new UIMoveKnob(e.Control));
- //點擊控件的時候,顯示控件的選擇
- e.Control.Click += new EventHandler(Control_Click);
- }
- }
- void Control_Click(object sender, EventArgs e)
- {
- //壽險清除已經選擇的控件
- foreach (UISizeKnob knob in this._HashUISizeKnob.Values)
- {
- knob.ShowUISizeDots(false);
- }
- try
- {
- ((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
- }
- catch { }
- }
相對來說實現單個控件的拖動比較簡單,而實現多個控件的拖動,我們需要首先使用一個全局的變量來緩存我們所選擇的控件,然後在此類中。拖動的時候,通過遍歷此全局變量,一個個改變所選擇控件的位置。