c# 可移动可改变大小的控件

2019-09-11 15:20:27 浏览数 (1)

因为业务需要,百度了个可移动可改变大小的控件,然后自己修改了下,功能类似vs的设计面板中的功能差不多,可拖拽,改变大小

拖动的

代码语言:javascript复制
 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
    }

改变大小的类

代码语言:javascript复制
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);

        }
    }

使用方法

代码语言:javascript复制
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");
        }

效果如下

0 人点赞