控件移動的關鍵點就是需要設計一個獨立于任何控件的類(UIMoveKnob)來控制控件的移動。我這里實現的方法只針對一個控件,如果需要同時選擇多個控件,然后同時移動的話,你需要修改這個類,這里是有點難于控制,我使用的方法嚴重耦合,所以只在這里給出移動一個控件的辦法,具體移動過個控件的方法請各位討論。
要移動某個選定的控件,我們需要實現控件的:
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 { }
}
相對來說實現單個控件的拖動比較簡單,而實現多個控件的拖動,我們需要首先使用一個全局的變量來緩存我們所選擇的控件,然后在此類中。拖動的時候,通過遍歷此全局變量,一個個改變所選擇控件的位置。