前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c# 可移动可改变大小的控件

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

作者头像
冰封一夏
发布2019-09-11 15:20:27
1.9K0
发布2019-09-11 15:20:27
举报

因为业务需要,百度了个可移动可改变大小的控件,然后自己修改了下,功能类似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");
        }

效果如下

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档