zoukankan      html  css  js  c++  java
  • 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

    效果如下

  • 相关阅读:
    全景拼接
    krpano之字幕添加
    UML之时序图
    krpano之语音介绍
    小工具之录音(文字转语音)
    动态生成按钮的点击事件绑定
    登录之简单验证码
    登录之md5加密
    redis与mysql数据同步
    Sql Server 主从数据库配置
  • 原文地址:https://www.cnblogs.com/bfyx/p/9276452.html
Copyright © 2011-2022 走看看