`
saybody
  • 浏览: 863900 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

C#基础系列:开发自己的窗体设计器(实现控件的拖动)

阅读更多

控件移动的关键点就是需要设计一个独立于任何控件的类(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. publicclassUIMoveKnob
  2. {
  3. privateSystem.Windows.Forms.Control_Owner;
  4. privateint_MouseClickAtX;
  5. privateint_MouseClickAtY;
  6. privatebool_BeginDrag;
  7. publicUIMoveKnob(System.Windows.Forms.ControlOwner)
  8. {
  9. this._Owner=Owner;
  10. this._Owner.MouseDown+=newSystem.Windows.Forms.MouseEventHandler(this.Owner_MouseDown);
  11. this._Owner.MouseMove+=newSystem.Windows.Forms.MouseEventHandler(this.Owner_MouseMove);
  12. this._Owner.MouseUp+=newSystem.Windows.Forms.MouseEventHandler(this.Owner_MouseUp);
  13. }
  14. voidOwner_MouseDown(objectsender,System.Windows.Forms.MouseEventArgse)
  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. voidOwner_MouseMove(objectsender,System.Windows.Forms.MouseEventArgse)
  22. {
  23. try
  24. {
  25. if(this._BeginDrag)
  26. {
  27. Rectanglerect;
  28. /*
  29. *对于下列控件,是不能拖动的,所以这里也不绘制拖动边框
  30. *TabPage,
  31. */
  32. if(this._OwnerisSystem.Windows.Forms.TabPage)
  33. {
  34. //
  35. }
  36. else
  37. {
  38. this._Owner.Location=newPoint(this._Owner.Left+e.X-this._MouseClickAtX,this._Owner.Top+e.Y-this._MouseClickAtY);
  39. }
  40. }
  41. }
  42. catch{}
  43. }
  44. voidOwner_MouseUp(objectsender,System.Windows.Forms.MouseEventArgse)
  45. {
  46. this._BeginDrag=false;
  47. this._Owner.Parent.Refresh();
  48. }
  49. }

修改后的Form代码前半部分如下:

  1. privateMouseHook_MouseHook;
  2. //我们将所有的已经与具体控件关联了的UISizeKnob缓存在这个HashTable中
  3. privateHashtable_HashUISizeKnob;
  4. //负责控件移动的类
  5. privateHashtable_HashUIMoveKnob;
  6. publicForm1()
  7. {
  8. InitializeComponent();
  9. this._MouseHook=newMouseHook(this);
  10. this._HashUISizeKnob=newHashtable();
  11. this._HashUIMoveKnob=newHashtable();
  12. //为了简洁明了,我们在ControlAdded中来设置具体控件和UISizeKnob的关联
  13. this.ControlAdded+=newControlEventHandler(Form1_ControlAdded);
  14. }
  15. voidForm1_ControlAdded(objectsender,ControlEventArgse)
  16. {
  17. if(!(e.ControlisUISizeDot))
  18. {
  19. this._HashUISizeKnob.Add(e.Control,newUISizeKnob(e.Control));
  20. this._HashUIMoveKnob.Add(e.Control,newUIMoveKnob(e.Control));
  21. //点击控件的时候,显示控件的选择
  22. e.Control.Click+=newEventHandler(Control_Click);
  23. }
  24. }
  25. voidControl_Click(objectsender,EventArgse)
  26. {
  27. //寿险清除已经选择的控件
  28. foreach(UISizeKnobknobinthis._HashUISizeKnob.Values)
  29. {
  30. knob.ShowUISizeDots(false);
  31. }
  32. try
  33. {
  34. ((UISizeKnob)this._HashUISizeKnob[sender]).ShowUISizeDots(true);
  35. }
  36. catch{}
  37. }

相对来说实现单个控件的拖动比较简单,而实现多个控件的拖动,我们需要首先使用一个全局的变量来缓存我们所选择的控件,然后在此类中。拖动的时候,通过遍历此全局变量,一个个改变所选择控件的位置。

相关文章:

C#基础系列:开发自己的窗体设计器(总纲)

C#基础系列:开发自己的窗体设计器(在容器上拖动鼠标增加控件)

C#基础系列:开发自己的窗体设计器(实现控件的选择)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics