• WinForm C#: Simple Runtime Control ReSizing and Dragging & Moving Class


    /*
    C#: Simple Runtime Control Sizing and Dragging Class

    首先声明如下代码改自
    CodeProject 同名文章(鸣谢原作者 Jim Korovessis: ~!@#$%^&*):
    http://www.codeproject.com/cs/miscctrl/CSPickBoxSample1.asp

    我做了如下改造:

    1.增加一个 ArrayList 存储 WiredControls
    2.增加 UnWireAllWiredControls() 方法,用于切换到控件"非设计"状态
    3.增加 WireControls() 方法,用于到控件"设计"状态
    4.增加支持键盘移动或改大小

    我会把我更改的代码高亮显示!
    */


    //You Can Save below code to one File named Noname1.cs
    //execute "csc noname1.cs" Directly!

    //PickBox
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;

    //namespace PickBoxTest
    //{
     /// <summary>
     /// This class implements sizing and moving functions for
     /// runtime editing of graphic controls
     /// </summary>
    public class PickBox
    {
     //////////////////////////////////////////////////////////////////
     // PRIVATE CONSTANTS AND VARIABLES
     //////////////////////////////////////////////////////////////////

     private const int BOX_SIZE = 8;
     private Color BOX_COLOR = Color.White;
    // private ContainerControl m_container;
     private  Control m_control;
     private Label[] lbl = new Label[8];
     private int startl;
     private int startt;
     private int startw;
     private int starth;
     private int startx;
     private int starty;
     private bool dragging;
     private Cursor[] arrArrow = new Cursor[]
                {
                 Cursors.SizeNWSE
                 ,Cursors.SizeNS
                 ,Cursors.SizeNESW
                 ,Cursors.SizeWE
                 ,Cursors.SizeNWSE
                 ,Cursors.SizeNS
                 ,Cursors.SizeNESW
                 ,Cursors.SizeWE
                };
     private Cursor oldCursor;

     private const int MIN_SIZE = 20;

     private Form ParentForm;

     //
     // Constructor creates 8 sizing handles & wires mouse events
     // to each that implement sizing functions
     //
     public PickBox()
     {
      for (int i = 0; i < 8; i++)
      {
       lbl[i] = new Label();
       lbl[i].TabIndex = i;
       lbl[i].FlatStyle = 0 ;
       lbl[i].BorderStyle = BorderStyle.FixedSingle;
       lbl[i].BackColor = BOX_COLOR;
       lbl[i].Cursor = arrArrow[i];
       lbl[i].Text = "";
       lbl[i].BringToFront();
       lbl[i].MouseDown += new MouseEventHandler(this.lbl_MouseDown);
       lbl[i].MouseMove += new MouseEventHandler(this.lbl_MouseMove);
       lbl[i].MouseUp += new MouseEventHandler(this.lbl_MouseUp);
      }
     }

     //////////////////////////////////////////////////////////////////
     // PUBLIC METHODS
     //////////////////////////////////////////////////////////////////

     //
     // Wires a Click event handler to the passed Control
     // that attaches a pick box to the control when it is clicked
     //

     //add by playyuer㊣Microshaoft.com
     // Store Controls for Design (resize or move)
     private ArrayList WiredControls = new ArrayList();

     public void WireControl(Control ctl)
     {
      //add by playyuer㊣Microshaoft.com
      //Store Wired Controls
      WiredControls.Add(ctl);

      if (ParentForm != ctl.FindForm())
      {
       ParentForm = ctl.FindForm();
       //ParentForm.KeyPreview = true;
      }

      ctl.Click += new EventHandler(this.SelectControl);

      //add by playyuer㊣Microshaoft.com
      //support resizing or moving control by Keyboard
      ctl.KeyDown += new KeyEventHandler(ctl_KeyDown);
     }

     //add by playyuer㊣Microshaoft.com
     //for Wire Controls that in WiredControls ArrayList
     public void WireControls()
     {
      if (WiredControls.Count > 0)
      {
       System.Collections.IEnumerator ie = WiredControls.GetEnumerator();
       while ( ie.MoveNext() )
       {
        this.WireControl((Control) ie.Current);
       }
      }
      
     }

     //add by playyuer㊣Microshaoft.com
     //for UnWire Controls that in WiredControls ArrayList
     public void UnWireAllWiredControls()
     {

      System.Collections.IEnumerator ie = WiredControls.GetEnumerator();
      Control c;
      while ( ie.MoveNext() )
      {
       c = (Control) ie.Current;
       c.Click -= new EventHandler(this.SelectControl);
       c.KeyDown -= new KeyEventHandler(ctl_KeyDown);

       if (m_control is Control)
       {
        m_control.Cursor = oldCursor;
        //Remove event any pre-existing event handlers appended by this class
        m_control.MouseDown -= new MouseEventHandler(this.ctl_MouseDown);
        m_control.MouseMove -= new MouseEventHandler(this.ctl_MouseMove);
        m_control.MouseUp -= new MouseEventHandler(this.ctl_MouseUp);

        m_control.KeyDown -= new KeyEventHandler(ctl_KeyDown);

        m_control = null;
       }
      }
      this.HideHandles();
     }

     /////////////////////////////////////////////////////////////////
     // PRIVATE METHODS
     /////////////////////////////////////////////////////////////////

     //
     // Attaches a pick box to the sender Control
     //
     private void SelectControl(object sender, EventArgs e)
     {

      if (m_control is Control)
      {
       m_control.Cursor = oldCursor;

       //Remove event any pre-existing event handlers appended by this class
       m_control.MouseDown -= new MouseEventHandler(this.ctl_MouseDown);
       m_control.MouseMove -= new MouseEventHandler(this.ctl_MouseMove);
       m_control.MouseUp -= new MouseEventHandler(this.ctl_MouseUp);

       m_control = null;
      }

      m_control = (Control) sender;

      //Add event handlers for moving the selected control around
      m_control.MouseDown += new MouseEventHandler(this.ctl_MouseDown);
      m_control.MouseMove += new MouseEventHandler(this.ctl_MouseMove);
      m_control.MouseUp += new MouseEventHandler(this.ctl_MouseUp);


      //Add sizing handles to Control's container (Form or PictureBox)
      for (int i = 0; i < 8; i++)
      {
       m_control.Parent.Controls.Add(lbl[i]);
       lbl[i].BringToFront();
      }

      //Position sizing handles around Control
      MoveHandles();

      //Display sizing handles
      ShowHandles();

      oldCursor = m_control.Cursor;
      m_control.Cursor = Cursors.SizeAll;
     }

     public void Remove()
     {
      HideHandles();
      m_control.Cursor = oldCursor;
     }

     private void ShowHandles()
     {
      if (m_control !=null)
      {
       for (int i = 0; i < 8; i++)
       {
        lbl[i].Visible = true;
       }
      }
     }

     private void HideHandles()
     {
      for (int i = 0; i < 8; i++)
      {
       lbl[i].Visible = false;
      }
     }

     private void MoveHandles()
     {
      int sX = m_control.Left - BOX_SIZE;
      int sY = m_control.Top - BOX_SIZE;
      int sW = m_control.Width + BOX_SIZE;
      int sH = m_control.Height + BOX_SIZE;
      int hB = BOX_SIZE / 2;

      int[] arrPosX = new int[]
             {
              sX+hB, sX + sW / 2
              ,sX + sW-hB
              ,sX + sW-hB
              ,sX + sW-hB
              ,sX + sW / 2
              ,sX+hB, sX+hB
             };
      int[] arrPosY = new int[]
             {
              sY+hB
              ,sY+hB
              ,sY+hB
              ,sY + sH / 2
              , sY + sH-hB
              ,sY + sH-hB
              ,sY + sH-hB
              ,sY + sH / 2
             };
      for (int i = 0; i < 8; i++)
       lbl[i].SetBounds(arrPosX[i], arrPosY[i], BOX_SIZE, BOX_SIZE);
     }

     /////////////////////////////////////////////////////////////////
     // MOUSE EVENTS THAT IMPLEMENT SIZING OF THE PICKED CONTROL
     /////////////////////////////////////////////////////////////////

     //
     // Store control position and size when mouse button pushed over
     // any sizing handle
     //
     private void lbl_MouseDown(object sender, MouseEventArgs e)
     {
      dragging = true;
      startl = m_control.Left;
      startt = m_control.Top;
      startw = m_control.Width;
      starth = m_control.Height;
      HideHandles();
     }

     //
     // Size the picked control in accordance with sizing handle being dragged
     // 0   1   2
     //  7       3
     //  6   5   4
     //
     private void lbl_MouseMove(object sender, MouseEventArgs e)
     {
      int l = m_control.Left;
      int w = m_control.Width;
      int t = m_control.Top;
      int h = m_control.Height;
      if (dragging)
      {
       switch (((Label)sender).TabIndex)
       {
        case 0 : // Dragging top-left sizing box
         l = startl + e.X < startl + startw - MIN_SIZE ? startl + e.X : startl + startw - MIN_SIZE;
         t = startt + e.Y < startt + starth - MIN_SIZE ? startt + e.Y : startt + starth - MIN_SIZE;
         w = startl + startw - m_control.Left;
         h = startt + starth - m_control.Top;
         break;
        case 1 : // Dragging top-center sizing box
         t = startt + e.Y < startt + starth - MIN_SIZE ? startt + e.Y : startt + starth - MIN_SIZE;
         h = startt + starth - m_control.Top;
         break;
        case 2 : // Dragging top-right sizing box
         w = startw + e.X > MIN_SIZE ? startw + e.X : MIN_SIZE;
         t = startt + e.Y < startt + starth - MIN_SIZE ? startt + e.Y : startt + starth - MIN_SIZE;
         h = startt + starth - m_control.Top;
         break;
        case 3 : // Dragging right-middle sizing box
         w = startw + e.X > MIN_SIZE ? startw + e.X : MIN_SIZE;
         break;
        case 4 : // Dragging right-bottom sizing box
         w = startw + e.X > MIN_SIZE ? startw + e.X : MIN_SIZE;
         h = starth + e.Y > MIN_SIZE ? starth + e.Y : MIN_SIZE;
         break;
        case 5 : // Dragging center-bottom sizing box
         h = starth + e.Y > MIN_SIZE ? starth + e.Y : MIN_SIZE;
         break;
        case 6 : // Dragging left-bottom sizing box
         l = startl + e.X < startl + startw - MIN_SIZE ? startl + e.X : startl + startw - MIN_SIZE;
         w = startl + startw - m_control.Left;
         h = starth + e.Y > MIN_SIZE ? starth + e.Y : MIN_SIZE;
         break;
        case 7 : // Dragging left-middle sizing box
         l = startl + e.X < startl + startw - MIN_SIZE ? startl + e.X : startl + startw - MIN_SIZE;
         w = startl + startw - m_control.Left;
         break;
       }
       l = (l < 0)? 0 : l;
       t = (t < 0)? 0 : t;
       m_control.SetBounds(l,t,w,h);
      }
     }

     //
     // Display sizing handles around picked control once sizing has completed
     //
     private void lbl_MouseUp(object sender, MouseEventArgs e)
     {
      dragging = false;
      MoveHandles();
      ShowHandles();
     }

     /////////////////////////////////////////////////////////////////
     // MOUSE EVENTS THAT MOVE THE PICKED CONTROL AROUND THE FORM
     /////////////////////////////////////////////////////////////////

     //
     // Get mouse pointer starting position on mouse down and hide sizing handles
     //
     private void ctl_MouseDown(object sender, MouseEventArgs e)
     {
      dragging = true;
      startx = e.X;
      starty = e.Y;
      HideHandles();
     }

     //
     // Reposition the dragged control
     //
     private void ctl_MouseMove(object sender, MouseEventArgs e)
     {
      if (dragging)
      {
       int l =  m_control.Left + e.X - startx;
       int t = m_control.Top + e.Y - starty;
       int w = m_control.Width;
       int h = m_control.Height;

       l = (l < 0)? 0 : ((l + w > m_control.Parent.ClientRectangle.Width)? m_control.Parent.ClientRectangle.Width - w : l);
       t = (t < 0)? 0 : ((t + h > m_control.Parent.ClientRectangle.Height)? m_control.Parent.ClientRectangle.Height - h : t);
       m_control.Left = l;
       m_control.Top = t;
      }
     }

     //
     // Display sizing handles around picked control once dragging has completed
     //
     private void ctl_MouseUp(object sender, MouseEventArgs e)
     {
      dragging = false;
      MoveHandles();
      ShowHandles();
     }

     private void ctl_KeyDown(object sender, KeyEventArgs e)
     {
      if (e.Modifiers == Keys.Control)
      {
       switch (e.KeyCode)
       {
        case Keys.Right :
         m_control.Left += 10;
         break;
        case Keys.Left :
         m_control.Left -= 10;
         break;
        case Keys.Up :
         m_control.Top -= 10;
         break;
        case Keys.Down :
         m_control.Top += 10;
         break;
       }
       MoveHandles();
      }
      else if (e.Modifiers == Keys.Shift)
      {
       switch (e.KeyCode)
       {
        case Keys.Right :
         m_control.Width += 10;
         break;
        case Keys.Left :
         m_control.Width -= 10;
         break;
        case Keys.Up :
         m_control.Height -= 10;
         break;
        case Keys.Down :
         m_control.Height += 10;
         break;
       }
       MoveHandles();
      }
      //((Control)sender).Select();
     }
    }
    //}

    //==================================================

    //WinForm Test
    //Form1
    //using System;
    //using System.Drawing;
    //using System.Collections;
    //using System.ComponentModel;
    //using System.Windows.Forms;
    //using System.Data;

    //namespace WindowsApplication1
    //{
     /// <summary>
     /// Form1 的摘要说明。
     /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
     private System.Windows.Forms.Button button1;
     private System.Windows.Forms.TextBox textBox1;
     private System.Windows.Forms.DataGrid dataGrid1;
     /// <summary>
     /// 必需的设计器变量。
     /// </summary>
     private System.ComponentModel.Container components = null;
     private System.Windows.Forms.DataGrid dataGrid2;
     private System.Windows.Forms.Button button2;

     //add by playyuer㊣Microshaoft.com
     private PickBox pb = new PickBox();
     public Form1()
     {
      //
      // Windows 窗体设计器支持所必需的
      //
      InitializeComponent();

      //
      // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
      //
     }

     /// <summary>
     /// 清理所有正在使用的资源。
     /// </summary>
     protected override void Dispose( bool disposing )
     {
      if( disposing )
      {
       if (components != null)
       {
        components.Dispose();
       }
      }
      base.Dispose( disposing );
     }

     #region Windows 窗体设计器生成的代码
     /// <summary>
     /// 设计器支持所需的方法 - 不要使用代码编辑器修改
     /// 此方法的内容。
     /// </summary>
     private void InitializeComponent()
     {
      this.button1 = new System.Windows.Forms.Button();
      this.textBox1 = new System.Windows.Forms.TextBox();
      this.dataGrid1 = new System.Windows.Forms.DataGrid();
      this.dataGrid2 = new System.Windows.Forms.DataGrid();
      this.button2 = new System.Windows.Forms.Button();
      ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
      ((System.ComponentModel.ISupportInitialize)(this.dataGrid2)).BeginInit();
      this.SuspendLayout();
      //
      // button1
      //
      this.button1.Location = new System.Drawing.Point(24, 16);
      this.button1.Name = "button1";
      this.button1.Size = new System.Drawing.Size(104, 40);
      this.button1.TabIndex = 0;
      this.button1.Text = "切换";
      this.button1.Click += new System.EventHandler(this.button1_Click);
      //
      // textBox1
      //
      this.textBox1.Location = new System.Drawing.Point(144, 32);
      this.textBox1.Name = "textBox1";
      this.textBox1.Size = new System.Drawing.Size(128, 21);
      this.textBox1.TabIndex = 1;
      this.textBox1.Text = "textBox1";
      //
      // dataGrid1
      //
      this.dataGrid1.DataMember = "";
      this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
      this.dataGrid1.Location = new System.Drawing.Point(32, 80);
      this.dataGrid1.Name = "dataGrid1";
      this.dataGrid1.Size = new System.Drawing.Size(160, 72);
      this.dataGrid1.TabIndex = 2;
      //
      // dataGrid2
      //
      this.dataGrid2.DataMember = "";
      this.dataGrid2.HeaderForeColor = System.Drawing.SystemColors.ControlText;
      this.dataGrid2.Location = new System.Drawing.Point(64, 208);
      this.dataGrid2.Name = "dataGrid2";
      this.dataGrid2.Size = new System.Drawing.Size(168, 64);
      this.dataGrid2.TabIndex = 3;
      //
      // button2
      //
      this.button2.Location = new System.Drawing.Point(280, 144);
      this.button2.Name = "button2";
      this.button2.Size = new System.Drawing.Size(152, 56);
      this.button2.TabIndex = 4;
      this.button2.Text = "button2";
      //
      // Form1
      //
      this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
      this.ClientSize = new System.Drawing.Size(608, 381);
      this.Controls.Add(this.button2);
      this.Controls.Add(this.dataGrid2);
      this.Controls.Add(this.dataGrid1);
      this.Controls.Add(this.textBox1);
      this.Controls.Add(this.button1);
      this.Name = "Form1";
      this.Text = "Form1";
      this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
      this.Load += new System.EventHandler(this.Form1_Load);
      ((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
      ((System.ComponentModel.ISupportInitialize)(this.dataGrid2)).EndInit();
      this.ResumeLayout(false);

     }
     #endregion

     /// <summary>
     /// 应用程序的主入口点。
     /// </summary>
     [STAThread]
     static void Main()
     {
      Application.Run(new Form1());
     }

     private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
     {

     }

     bool b = false;
     
     private void button1_Click(object sender, System.EventArgs e)
     {
      if (!b) 
      {
       this.Text = "Design Time";

       pb.WireControl(dataGrid1);
       pb.WireControl(textBox1);
       pb.WireControl(button2);
       pb.WireControl(dataGrid2);

      }
      else
      {
       this.Text = "Run Time";
       pb.UnWireAllWiredControls();
      }
      b = !b;
     }

     private void Form1_Load(object sender, System.EventArgs e)
     {

     }
    }
    //}

  • 相关阅读:
    思维导图
    Delphi 之弹出气泡消息提示
    delphi 响应鼠标进入控件消息
    Delphi 获取当前鼠标下的控件内容
    delphi TTBXToolBar 增加外部控件
    delphi button 实现下拉列表
    delphi 设置多屏幕
    电脑双屏改单屏后看不到文件问题的解决
    delphi ListView 设置固定列宽
    数字孪生(Digital twin)
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/179603.html
Copyright © 2020-2023  润新知