c# 可移動可改變大小的控件


因為業務需要,百度了個可移動可改變大小的控件,然后自己修改了下,功能類似vs的設計面板中的功能差不多,可拖拽,改變大小

拖動的

 public class MoveControl
    {
        #region 自定義事件
        /// <summary>
        /// 控件移動時觸發事件
        /// </summary>
        public event EventHandler ControlMoving;
        /// <summary>
        /// 控件移動完成觸發事件
        /// </summary>
        public event EventHandler ControlMoved;
        /// <summary>
        /// 控件改變大小時觸發事件
        /// </summary>
        public event EventHandler ControlResizing;
        /// <summary>
        /// 控件改變大小完成觸發事件
        /// </summary>
        public event EventHandler ControlResized;
        /// <summary>
        /// 選中控件時發生
        /// </summary>
        public event EventHandler ControlSelected;
        #endregion
        /// <summary>
        /// 是否可調整尺寸
        /// </summary>
        bool m_blnResize = true;
        MoveControlType m_moveType;
        #region Constructors
        /// <summary>
        /// 功能描述:構造函數
        /// 作  者:beck.huang
        /// 創建日期:2018-07-07 09:20:41
        /// 任務編號:中餐
        /// </summary>
        /// <param name="ctrl">ctrl</param>
        /// <param name="blnResize">是否可調整尺寸</param>
        /// <param name="moveType">移動模式</param>
        public MoveControl(Control ctrl, bool blnResize = true, MoveControlType moveType = MoveControlType.ANY)
        {
            m_blnResize = blnResize;
            m_moveType = moveType;
            currentControl = ctrl;
            AddEvents();
        }
        #endregion

        #region Fields
        private Control currentControl; //傳入的控件
        private Point pPoint; //上個鼠標坐標
        private Point cPoint; //當前鼠標坐標
        FrameControl fc;//邊框控件
        #endregion

        #region Properties

        #endregion

        #region Methods
        /// <summary>
        /// 掛載事件
        /// </summary>
        private void AddEvents()
        {
            currentControl.MouseClick -= new MouseEventHandler(MouseClick);
            currentControl.MouseClick += new MouseEventHandler(MouseClick);
            currentControl.MouseDown -= new MouseEventHandler(MouseDown);
            currentControl.MouseDown += new MouseEventHandler(MouseDown);
            currentControl.MouseMove -= new MouseEventHandler(MouseMove);
            currentControl.MouseMove += new MouseEventHandler(MouseMove);
            currentControl.MouseUp -= new MouseEventHandler(MouseUp);
            currentControl.MouseUp += new MouseEventHandler(MouseUp);
        }

        /// <summary>
        /// 繪制拖拉時的黑色邊框
        /// </summary>
        public static void DrawDragBound(Control ctrl)
        {
            ctrl.Refresh();
            Graphics g = ctrl.CreateGraphics();
            int width = ctrl.Width;
            int height = ctrl.Height;
            Point[] ps = new Point[5]{new Point(0,0),new Point(width -1,0),
                new Point(width -1,height -1),new Point(0,height-1),new Point(0,0)};
            g.DrawLines(new Pen(Color.Black), ps);
        }

        #endregion

        #region Events
        /// <summary>
        /// 鼠標單擊事件:用來顯示邊框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void MouseClick(object sender, MouseEventArgs e)
        {
            if (m_blnResize)
            {
                this.currentControl.Parent.Refresh();//刷新父容器,清除掉其他控件的邊框
                for (int i = currentControl.Parent.Controls.Count-1; i >=0; i--)
                {
                    Control item = currentControl.Parent.Controls[i];
                    if (item is FrameControl)
                    {
                        currentControl.Parent.Controls.RemoveAt(i);
                    }
                }
                
                this.currentControl.BringToFront();
                fc = new FrameControl(this.currentControl);
                fc.ControlResized += fc_ControlResized;
                fc.ControlResizing += fc_ControlResizing;
                this.currentControl.Parent.Controls.Add(fc);
                fc.Visible = true;
                fc.Draw();
            }
            if (ControlSelected != null)
            {
                ControlSelected(this.currentControl, e);
            }
        }

        /// <summary>
        /// 功能描述:控件改變大小時事件
        /// 作  者:beck.huang
        /// 創建日期:2018-07-07 09:51:27
        /// 任務編號:中餐
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">e</param>
        void fc_ControlResizing(object sender, EventArgs e)
        {
            if (ControlResizing != null)
            {
                ControlResizing(sender, e);
            }
        }

        /// <summary>
        /// 功能描述:控件改變大小完成事件
        /// 作  者:beck.huang
        /// 創建日期:2018-07-07 09:51:12
        /// 任務編號:中餐
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">e</param>
        void fc_ControlResized(object sender, EventArgs e)
        {
            if (ControlResized != null)
            {
                ControlResized(sender, e);
            }
        }

        /// <summary>
        /// 鼠標按下事件:記錄當前鼠標相對窗體的坐標
        /// </summary>
        void MouseDown(object sender, MouseEventArgs e)
        {
            pPoint = Cursor.Position;
        }

        /// <summary>
        /// 鼠標移動事件:讓控件跟着鼠標移動
        /// </summary>
        void MouseMove(object sender, MouseEventArgs e)
        {
            if (m_moveType != MoveControlType.NONE)
            {
                if (m_moveType == MoveControlType.ANY)
                {
                    Cursor.Current = Cursors.SizeAll;
                }
                else if (m_moveType == MoveControlType.VERTICAL)
                {
                    Cursor.Current = Cursors.HSplit;
                }
                else
                {
                    Cursor.Current = Cursors.VSplit;
                }
                // Cursor.Current = Cursors.SizeAll; //當鼠標處於控件內部時,顯示光標樣式為SizeAll
                //當鼠標左鍵按下時才觸發
                if (e.Button == MouseButtons.Left)
                {
                    MoveControl.DrawDragBound(this.currentControl);
                    if (fc != null) fc.Visible = false; //先隱藏
                    cPoint = Cursor.Position;//獲得當前鼠標位置

                    int x = cPoint.X - pPoint.X;
                    int y = cPoint.Y - pPoint.Y;
                    if (m_moveType == MoveControlType.ANY)
                    {
                        currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y + y);
                    }
                    else if (m_moveType == MoveControlType.VERTICAL)
                    {
                        currentControl.Location = new Point(currentControl.Location.X, currentControl.Location.Y + y);
                    }
                    else
                    {
                        currentControl.Location = new Point(currentControl.Location.X + x, currentControl.Location.Y);
                    }
                    pPoint = cPoint;
                    if (ControlMoving != null)
                    {
                        ControlMoving(currentControl, e);
                    }
                }
            }
        }

        /// <summary>
        /// 鼠標彈起事件:讓自定義的邊框出現
        /// </summary>
        void MouseUp(object sender, MouseEventArgs e)
        {
            this.currentControl.Refresh();
            if (fc != null)
            {
                fc.Visible = true;
                fc.Draw();
            }
            if (ControlMoved != null)
            {
                ControlMoved(currentControl, e);
            }
        }
        #endregion
    }
    /// <summary>
    /// 移動控件模式
    /// </summary>
    public enum MoveControlType
    {
        /// <summary>
        /// 任意
        /// </summary>
        ANY = 0,
        /// <summary>
        /// 垂直
        /// </summary>
        VERTICAL,
        /// <summary>
        /// 水平
        /// </summary>
        HORIZONTAL,
        /// <summary>
        /// 不可移動
        /// </summary>
        NONE
    }
View Code

改變大小的類

public class FrameControl : UserControl
    {
        /// <summary>
        /// 控件改變大小時觸發事件
        /// </summary>
        public event EventHandler ControlResizing;
        /// <summary>
        /// 控件改變大小完成觸發事件
        /// </summary>
        public event EventHandler ControlResized;
        #region Constructors
        /// <summary>
        /// 構造函數
        /// </summary>
        public FrameControl(Control ctrl)
        {
            baseControl = ctrl;
            AddEvents();
            CreateBounds();
        }
        #endregion

        #region Fields
        const int Band = 6; //調整大小的響應邊框
        private int MinWidth = 20; //最小寬度
        private int MinHeight = 20;//最小高度
        Size square = new Size(Band, Band);//小矩形大小
        Control baseControl; //基礎控件,即被包圍的控件
        Rectangle[] smallRects = new Rectangle[8];//邊框中的八個小圓圈
        Rectangle[] sideRects = new Rectangle[4];//四條邊框,用來做響應區域
        Point[] linePoints = new Point[5];//四條邊,用於畫虛線
        Graphics g; //畫圖板
        Rectangle ControlRect; //控件包含邊框的區域  
        private Point pPoint; //上個鼠標坐標
        private Point cPoint; //當前鼠標坐標
        private MousePosOnCtrl mpoc;
       
        #endregion

        #region Properties
        /// <summary>
        /// 鼠標在控件中位置
        /// </summary>
        enum MousePosOnCtrl
        {
            NONE = 0,
            TOP = 1,
            RIGHT = 2,
            BOTTOM = 3,
            LEFT = 4,
            TOPLEFT = 5,
            TOPRIGHT = 6,
            BOTTOMLEFT = 7,
            BOTTOMRIGHT = 8,
        }
        #endregion

        #region Methods
        /// <summary>
        /// 加載事件
        /// </summary>
        private void AddEvents()
        {
            this.Name = "FrameControl" + baseControl.Name;            
            this.MouseDown += new MouseEventHandler(FrameControl_MouseDown);
            this.MouseMove += new MouseEventHandler(FrameControl_MouseMove);
            this.MouseUp += new MouseEventHandler(FrameControl_MouseUp);
        }

        #region 創建邊框
        /// <summary>
        /// 建立控件可視區域
        /// </summary>
        private void CreateBounds()
        {
            //創建邊界
            int X = baseControl.Bounds.X - square.Width - 1;
            int Y = baseControl.Bounds.Y - square.Height - 1;
            int Height = baseControl.Bounds.Height + (square.Height * 2) + 2;
            int Width = baseControl.Bounds.Width + (square.Width * 2) + 2;
            this.Bounds = new Rectangle(X, Y, Width, Height);
            this.BringToFront();           
            SetRectangles();           
            //設置可視區域
            this.Region = new Region(BuildFrame());
            g = this.CreateGraphics();
        }

        /// <summary>
        /// 設置定義8個小矩形的范圍
        /// </summary>
        void SetRectangles()
        {
            //左上
            smallRects[0] = new Rectangle(new Point(0, 0), square);
            //右上
            smallRects[1] = new Rectangle(new Point(this.Width - square.Width - 1, 0), square);
            //左下
            smallRects[2] = new Rectangle(new Point(0, this.Height - square.Height - 1), square);
            //右下
            smallRects[3] = new Rectangle(new Point(this.Width - square.Width - 1, this.Height - square.Height - 1), square);
            //上中
            smallRects[4] = new Rectangle(new Point(this.Width / 2 - 1, 0), square);
            //下中
            smallRects[5] = new Rectangle(new Point(this.Width / 2 - 1, this.Height - square.Height - 1), square);
            //左中
            smallRects[6] = new Rectangle(new Point(0, this.Height / 2 - 1), square);
            //右中
            smallRects[7] = new Rectangle(new Point(square.Width + baseControl.Width + 1, this.Height / 2 - 1), square);

            //四條邊線
            //左上
            linePoints[0] = new Point(square.Width / 2, square.Height / 2);
            //右上
            linePoints[1] = new Point(this.Width - square.Width / 2 - 1, square.Height / 2);
            //右下
            linePoints[2] = new Point(this.Width - square.Width / 2 - 1, this.Height - square.Height / 2);
            //左下
            linePoints[3] = new Point(square.Width / 2, this.Height - square.Height / 2 - 1);
            //左上
            linePoints[4] = new Point(square.Width / 2, square.Height / 2);

            //整個包括周圍邊框的范圍
            ControlRect = new Rectangle(new Point(0, 0), this.Bounds.Size);
        }

        /// <summary>
        /// 設置邊框控件可視區域
        /// </summary>
        /// <returns></returns>
        private GraphicsPath BuildFrame()
        {
            GraphicsPath path = new GraphicsPath();
            //上邊框
            sideRects[0] = new Rectangle(0, 0, this.Width - square.Width - 1, square.Height + 1);
            //左邊框
            sideRects[1] = new Rectangle(0, square.Height + 1, square.Width + 1, this.Height - square.Height - 1);
            //下邊框
            sideRects[2] = new Rectangle(square.Width + 1, this.Height - square.Height - 1, this.Width - square.Width - 1, square.Height + 1);
            //右邊框
            sideRects[3] = new Rectangle(this.Width - square.Width - 1, 0, square.Width + 1, this.Height - square.Height - 1);

            path.AddRectangle(sideRects[0]);
            path.AddRectangle(sideRects[1]);
            path.AddRectangle(sideRects[2]);
            path.AddRectangle(sideRects[3]);
            return path;
        }
        #endregion

        /// <summary>
        /// 繪圖
        /// </summary>
        public void Draw()
        {
            this.BringToFront();
            //g.FillRectangles(Brushes.LightGray, sideRects); //填充四條邊框的內部
            Pen pen = new Pen(Color.Black);
            pen.DashStyle = DashStyle.Dot;//設置為虛線,用虛線畫四邊,模擬微軟效果
            g.DrawLines(pen, linePoints);//繪制四條邊線
            g.FillRectangles(Brushes.White, smallRects); //填充8個小矩形的內部
            foreach (Rectangle smallRect in smallRects)
            {
                g.DrawEllipse(Pens.Black, smallRect);    //繪制8個小橢圓
            }
            //g.DrawRectangles(Pens.Black, smallRects);  //繪制8個小矩形的黑色邊線
        }

        /// <summary>
        /// 設置光標狀態
        /// </summary>
        public bool SetCursorShape(int x, int y)
        {
            Point point = new Point(x, y);
            if (!ControlRect.Contains(point))
            {
                Cursor.Current = Cursors.Arrow;
                return false;
            }
            else if (smallRects[0].Contains(point))
            {
                Cursor.Current = Cursors.SizeNWSE;
                mpoc = MousePosOnCtrl.TOPLEFT;
            }
            else if (smallRects[1].Contains(point))
            {
                Cursor.Current = Cursors.SizeNESW;
                mpoc = MousePosOnCtrl.TOPRIGHT;
            }
            else if (smallRects[2].Contains(point))
            {
                Cursor.Current = Cursors.SizeNESW;
                mpoc = MousePosOnCtrl.BOTTOMLEFT;
            }
            else if (smallRects[3].Contains(point))
            {
                Cursor.Current = Cursors.SizeNWSE;
                mpoc = MousePosOnCtrl.BOTTOMRIGHT;
            }
            else if (sideRects[0].Contains(point))
            {
                Cursor.Current = Cursors.SizeNS;
                mpoc = MousePosOnCtrl.TOP;
            }
            else if (sideRects[1].Contains(point))
            {
                Cursor.Current = Cursors.SizeWE;
                mpoc = MousePosOnCtrl.LEFT;
            }
            else if (sideRects[2].Contains(point))
            {
                Cursor.Current = Cursors.SizeNS;
                mpoc = MousePosOnCtrl.BOTTOM;
            }
            else if (sideRects[3].Contains(point))
            {
                Cursor.Current = Cursors.SizeWE;
                mpoc = MousePosOnCtrl.RIGHT;
            }
            else
            {
                Cursor.Current = Cursors.Arrow;
            }
            return true;
        }

        /// <summary>
        /// 控件移動
        /// </summary>
        private void ControlMove(MouseEventArgs e)
        {
            cPoint = Cursor.Position;
            int x = cPoint.X - pPoint.X;
            int y = cPoint.Y - pPoint.Y;
            switch (this.mpoc)
            {
                case MousePosOnCtrl.TOP:
                    if (baseControl.Height - y > MinHeight)
                    {
                        baseControl.Top += y;
                        baseControl.Height -= y;
                    }
                    else
                    {
                        baseControl.Top -= MinHeight - baseControl.Height;
                        baseControl.Height = MinHeight;
                    }
                    break;
                case MousePosOnCtrl.BOTTOM:
                    if (baseControl.Height + y > MinHeight)
                    {
                        baseControl.Height += y;
                    }
                    else
                    {
                        baseControl.Height = MinHeight;
                    }
                    break;
                case MousePosOnCtrl.LEFT:
                    if (baseControl.Width - x > MinWidth)
                    {
                        baseControl.Left += x;
                        baseControl.Width -= x;
                    }
                    else
                    {
                        baseControl.Left -= MinWidth - baseControl.Width;
                        baseControl.Width = MinWidth;
                    }

                    break;
                case MousePosOnCtrl.RIGHT:
                    if (baseControl.Width + x > MinWidth)
                    {
                        baseControl.Width += x;
                    }
                    else
                    {
                        baseControl.Width = MinWidth;
                    }
                    break;
                case MousePosOnCtrl.TOPLEFT:
                    if (baseControl.Height - y > MinHeight)
                    {
                        baseControl.Top += y;
                        baseControl.Height -= y;
                    }
                    else
                    {
                        baseControl.Top -= MinHeight - baseControl.Height;
                        baseControl.Height = MinHeight;
                    }
                    if (baseControl.Width - x > MinWidth)
                    {
                        baseControl.Left += x;
                        baseControl.Width -= x;
                    }
                    else
                    {
                        baseControl.Left -= MinWidth - baseControl.Width;
                        baseControl.Width = MinWidth;
                    }
                    break;
                case MousePosOnCtrl.TOPRIGHT:
                    if (baseControl.Height - y > MinHeight)
                    {
                        baseControl.Top += y;
                        baseControl.Height -= y;
                    }
                    else
                    {
                        baseControl.Top -= MinHeight - baseControl.Height;
                        baseControl.Height = MinHeight;
                    }
                    if (baseControl.Width + x > MinWidth)
                    {
                        baseControl.Width += x;
                    }
                    else
                    {
                        baseControl.Width = MinWidth;
                    }
                    break;
                case MousePosOnCtrl.BOTTOMLEFT:
                    if (baseControl.Height + y > MinHeight)
                    {
                        baseControl.Height += y;
                    }
                    else
                    {
                        baseControl.Height = MinHeight;
                    }
                    if (baseControl.Width - x > MinWidth)
                    {
                        baseControl.Left += x;
                        baseControl.Width -= x;
                    }
                    else
                    {
                        baseControl.Left -= MinWidth - baseControl.Width;
                        baseControl.Width = MinWidth;
                    }
                    break;
                case MousePosOnCtrl.BOTTOMRIGHT:
                    if (baseControl.Height + y > MinHeight)
                    {
                        baseControl.Height += y;
                    }
                    else
                    {
                        baseControl.Height = MinHeight;
                    }
                    if (baseControl.Width + x > MinWidth)
                    {
                        baseControl.Width += x;
                    }
                    else
                    {
                        baseControl.Width = MinWidth;
                    }
                    break;

            }
            pPoint = Cursor.Position;
            if (ControlResizing != null)
            {
                ControlResizing(baseControl, e);
            }
        }

        #endregion

        #region Events
        /// <summary>
        /// 鼠標按下事件:記錄當前鼠標相對窗體的坐標
        /// </summary>
        void FrameControl_MouseDown(object sender, MouseEventArgs e)
        {
            pPoint = Cursor.Position;
        }

        /// <summary>
        /// 鼠標移動事件:讓控件跟着鼠標移動
        /// </summary>
        void FrameControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Visible = false;
                MoveControl.DrawDragBound(baseControl);
                ControlMove(e);
            }
            else
            {
                this.Visible = true;
                SetCursorShape(e.X, e.Y); //更新鼠標指針樣式
            }
        }

        /// <summary>
        /// 鼠標彈起事件:讓自定義的邊框出現
        /// </summary>
        void FrameControl_MouseUp(object sender, MouseEventArgs e)
        {
            this.baseControl.Refresh(); //刷掉黑色邊框
            this.Visible = true;
            CreateBounds();
            Draw();
            if (ControlResized != null)
            {
                ControlResized(this.baseControl, e);
            }
        }
        #endregion

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // FrameControl
            // 
            this.BackColor = System.Drawing.Color.Transparent;
            this.Name = "FrameControl";
            this.ResumeLayout(false);

        }
    }
View Code

使用方法

private void Form1_Load(object sender, EventArgs e)
        {
            //this.TransparencyKey = SystemColors.Control;
            foreach (Control subCtrl in this.Controls)
            {
              MoveControl mc=  new MoveControl(subCtrl,false, MoveControlType.HORIZONTAL);
              mc.ControlMoving += mc_ControlMoving;
              mc.ControlMoved += mc_ControlMoved;
              mc.ControlResized += mc_ControlResized;
              mc.ControlResizing += mc_ControlResizing;
            }
        }

        void mc_ControlResizing(object sender, EventArgs e)
        {
            Console.WriteLine("Resizing");
        }

        void mc_ControlResized(object sender, EventArgs e)
        {
            Console.WriteLine("Resized");
        }

        void mc_ControlMoved(object sender, EventArgs e)
        {
            Console.WriteLine("moved");
        }

        void mc_ControlMoving(object sender, EventArgs e)
        {
            Console.WriteLine("moving");
        }
View Code

效果如下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM