開發自己的窗體設計器

 

控件移動的關鍵點就是需要設計一個獨立於任何控件的類(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的代碼如下:

  1. public class UIMoveKnob
  2. {
  3.     private System.Windows.Forms.Control _Owner;
  4.     private int _MouseClickAtX;
  5.     private int _MouseClickAtY;
  6.     private bool _BeginDrag;
  7.     public UIMoveKnob(System.Windows.Forms.Control Owner)
  8.     {
  9.         this._Owner = Owner;
  10.         this._Owner.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Owner_MouseDown);
  11.         this._Owner.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Owner_MouseMove);
  12.         this._Owner.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Owner_MouseUp);
  13.     }
  14.     void Owner_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
  15.     {
  16.         this._Owner.Cursor = System.Windows.Forms.Cursors.Default;
  17.         this._MouseClickAtX = e.X;
  18.         this._MouseClickAtY = e.Y;
  19.         this._BeginDrag = true;
  20.     }
  21.     void Owner_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
  22.     {
  23.         try
  24.         {
  25.             if (this._BeginDrag)
  26.             {
  27.                 Rectangle rect;
  28.                 /*
  29.                  * 對於下列控件,是不能拖動的,所以這裏也不繪製拖動邊框
  30.                  * TabPage,
  31.                  */
  32.                 if (this._Owner is System.Windows.Forms.TabPage)
  33.                 {
  34.                     //
  35.                 }
  36.                 else
  37.                 {
  38.                     this._Owner.Location = new Point(this._Owner.Left + e.X - this._MouseClickAtX, this._Owner.Top + e.Y - this._MouseClickAtY);
  39.                 }
  40.             }
  41.         }
  42.         catch { }
  43.     }
  44.     void Owner_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
  45.     {
  46.         this._BeginDrag = false;
  47.         this._Owner.Parent.Refresh();
  48.     }
  49. }

修改後的Form代碼前半部分如下:

  1. private MouseHook _MouseHook;
  2. //我們將所有的已經與具體控件關聯了的UISizeKnob緩存在這個HashTable中
  3. private Hashtable _HashUISizeKnob;
  4. //負責控件移動的類
  5. private Hashtable _HashUIMoveKnob;
  6. public Form1()
  7. {
  8.     InitializeComponent();
  9.     this._MouseHook = new MouseHook(this);
  10.     this._HashUISizeKnob = new Hashtable();
  11.     this._HashUIMoveKnob = new Hashtable();
  12.     //爲了簡潔明瞭,我們在ControlAdded中來設置具體控件和UISizeKnob的關聯
  13.     this.ControlAdded += new ControlEventHandler(Form1_ControlAdded);
  14. }
  15. void Form1_ControlAdded(object sender, ControlEventArgs e)
  16. {
  17.     if (!(e.Control is UISizeDot))
  18.     {
  19.         this._HashUISizeKnob.Add(e.Control, new UISizeKnob(e.Control));
  20.         this._HashUIMoveKnob.Add(e.Control, new UIMoveKnob(e.Control));
  21.         
  22.         //點擊控件的時候,顯示控件的選擇
  23.         e.Control.Click += new EventHandler(Control_Click);
  24.     }
  25. }
  26. void Control_Click(object sender, EventArgs e)
  27. {
  28.     //壽險清除已經選擇的控件
  29.     foreach (UISizeKnob knob in this._HashUISizeKnob.Values)
  30.     {
  31.         knob.ShowUISizeDots(false);
  32.     }
  33.     try 
  34.     {
  35.         ((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
  36.     }
  37.     catch { }
  38. }

相對來說實現單個控件的拖動比較簡單,而實現多個控件的拖動,我們需要首先使用一個全局的變量來緩存我們所選擇的控件,然後在此類中。拖動的時候,通過遍歷此全局變量,一個個改變所選擇控件的位置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章