控件移動(dòng)的關(guān)鍵點(diǎn)就是需要設(shè)計(jì)一個(gè)獨(dú)立于任何控件的類(UIMoveKnob)來控制控件的移動(dòng)。我這里實(shí)現(xiàn)的方法只針對一個(gè)控件,如果需要同時(shí)選擇多個(gè)控件,然后同時(shí)移動(dòng)的話,你需要修改這個(gè)類,這里是有點(diǎn)難于控制,我使用的方法嚴(yán)重耦合,所以只在這里給出移動(dòng)一個(gè)控件的辦法,具體移動(dòng)過個(gè)控件的方法請各位討論。
要移動(dòng)某個(gè)選定的控件,我們需要實(shí)現(xiàn)控件的:
MouseDown
MouseMove
MouseUp
這3個(gè)事件。
在MouseDown的時(shí)候,記錄鼠標(biāo)點(diǎn)擊的開始位置,并設(shè)置開始移動(dòng)標(biāo)志為True;
在MouseMove的時(shí)候,把控件移動(dòng)相應(yīng)的距離(當(dāng)前鼠標(biāo)位置 – 鼠標(biāo)點(diǎn)擊的開始位置);
在MouseUp的時(shí)候,釋放移動(dòng)標(biāo)志為false。
有了控件移動(dòng)控制類(UIMoveKnob)以后,我們怎么實(shí)現(xiàn)UIMoveKnob和具體控件的關(guān)聯(lián)呢?同樣,我們需要在Form中增加一個(gè)變量private Hashtable _HashUIMoveKnob用于緩存每個(gè)控件對應(yīng)的UIMoveKnob對象。
同時(shí)在Form.ControlAdded事件中,通過this._HashUIMoveKnob.Add(e.Control, new UIMoveKnob(e.Control));設(shè)置其關(guān)聯(lián)性。
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;
/*
* 對于下列控件,是不能拖動(dòng)的,所以這里也不繪制拖動(dòng)邊框
* 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;
//我們將所有的已經(jīng)與具體控件關(guān)聯(lián)了的UISizeKnob緩存在這個(gè)HashTable中
private Hashtable _HashUISizeKnob;
//負(fù)責(zé)控件移動(dòng)的類
private Hashtable _HashUIMoveKnob;
public Form1()
{
InitializeComponent();
this._MouseHook = new MouseHook(this);
this._HashUISizeKnob = new Hashtable();
this._HashUIMoveKnob = new Hashtable();
//為了簡潔明了,我們在ControlAdded中來設(shè)置具體控件和UISizeKnob的關(guān)聯(lián)
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));
//點(diǎn)擊控件的時(shí)候,顯示控件的選擇
e.Control.Click += new EventHandler(Control_Click);
}
}
void Control_Click(object sender, EventArgs e)
{
//壽險(xiǎn)清除已經(jīng)選擇的控件
foreach (UISizeKnob knob in this._HashUISizeKnob.Values)
{
knob.ShowUISizeDots(false);
}
try
{
((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
}
catch { }
}
相對來說實(shí)現(xiàn)單個(gè)控件的拖動(dòng)比較簡單,而實(shí)現(xiàn)多個(gè)控件的拖動(dòng),我們需要首先使用一個(gè)全局的變量來緩存我們所選擇的控件,然后在此類中。拖動(dòng)的時(shí)候,通過遍歷此全局變量,一個(gè)個(gè)改變所選擇控件的位置。
要移動(dòng)某個(gè)選定的控件,我們需要實(shí)現(xiàn)控件的:
MouseDown
MouseMove
MouseUp
這3個(gè)事件。
在MouseDown的時(shí)候,記錄鼠標(biāo)點(diǎn)擊的開始位置,并設(shè)置開始移動(dòng)標(biāo)志為True;
在MouseMove的時(shí)候,把控件移動(dòng)相應(yīng)的距離(當(dāng)前鼠標(biāo)位置 – 鼠標(biāo)點(diǎn)擊的開始位置);
在MouseUp的時(shí)候,釋放移動(dòng)標(biāo)志為false。
有了控件移動(dòng)控制類(UIMoveKnob)以后,我們怎么實(shí)現(xiàn)UIMoveKnob和具體控件的關(guān)聯(lián)呢?同樣,我們需要在Form中增加一個(gè)變量private Hashtable _HashUIMoveKnob用于緩存每個(gè)控件對應(yīng)的UIMoveKnob對象。
同時(shí)在Form.ControlAdded事件中,通過this._HashUIMoveKnob.Add(e.Control, new UIMoveKnob(e.Control));設(shè)置其關(guān)聯(lián)性。
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;
/*
* 對于下列控件,是不能拖動(dòng)的,所以這里也不繪制拖動(dòng)邊框
* 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;
//我們將所有的已經(jīng)與具體控件關(guān)聯(lián)了的UISizeKnob緩存在這個(gè)HashTable中
private Hashtable _HashUISizeKnob;
//負(fù)責(zé)控件移動(dòng)的類
private Hashtable _HashUIMoveKnob;
public Form1()
{
InitializeComponent();
this._MouseHook = new MouseHook(this);
this._HashUISizeKnob = new Hashtable();
this._HashUIMoveKnob = new Hashtable();
//為了簡潔明了,我們在ControlAdded中來設(shè)置具體控件和UISizeKnob的關(guān)聯(lián)
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));
//點(diǎn)擊控件的時(shí)候,顯示控件的選擇
e.Control.Click += new EventHandler(Control_Click);
}
}
void Control_Click(object sender, EventArgs e)
{
//壽險(xiǎn)清除已經(jīng)選擇的控件
foreach (UISizeKnob knob in this._HashUISizeKnob.Values)
{
knob.ShowUISizeDots(false);
}
try
{
((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
}
catch { }
}
相對來說實(shí)現(xiàn)單個(gè)控件的拖動(dòng)比較簡單,而實(shí)現(xiàn)多個(gè)控件的拖動(dòng),我們需要首先使用一個(gè)全局的變量來緩存我們所選擇的控件,然后在此類中。拖動(dòng)的時(shí)候,通過遍歷此全局變量,一個(gè)個(gè)改變所選擇控件的位置。