控件拖动、调整大小

//
///文件名称:ControlMove.cs
///生成时间:2005.8.2
///作    者:龙照凯
///功能说明:
///          控件拖动、调整大小类(任何具备拖动能力的控件均可)
///          1、实现控件在父控件内随意拖动
///          2、可通过触模柄调整控件大小
///          3、可通过键盘对控件位置进行微调
///          4、DELETE快捷键删除控件
///

using System;
using System.Windows.Forms;
using System.Drawing;

namespace ImageTool
{
    /** <summary>
    /// ControlMove 的摘要说明。
    /// </summary>
    public class ControlMove
    {

        private定义#region private定义

        private const int MIN_SIZE = 10; //对控缩放的最小值
        private const int BOX_SIZE = 7;  //调整大小触模柄方框大小

        public  bool _IsCtrlKey = false;
        private TextBox _textbox;
        private Control _MControl = null;
        private bool _IsMouseDown = false;
        private Point _oPointClicked;
        private Color BOX_COLOR = Color.White;
        private Label[] _lbl = new Label[8];
        private int _startl, _startt, _startw, _starth;
        private bool _dragging;
        private    Cursor[] _arrArrow = new Cursor[] {Cursors.SizeNWSE, Cursors.SizeNS,
                                                    Cursors.SizeNESW, Cursors.SizeWE, Cursors.SizeNWSE, Cursors.SizeNS,
                                                    Cursors.SizeNESW, Cursors.SizeWE};

        #endregion

        构造函数#region 构造函数

        /** <summary>
        /// 构造控件拖动对象
        /// </summary>
        /// <param name="moveControl">需要拖动的控件</param>
        public ControlMove(Control moveControl)
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
            _MControl = moveControl;
            _MControl.MouseDown += new MouseEventHandler(this.Control_MouseDown);
            _MControl.MouseUp += new MouseEventHandler(this.Control_MouseUp);
            _MControl.MouseMove += new MouseEventHandler(this.Control_MouseMove);
            _MControl.Click += new System.EventHandler(this.Control_Click);

            //构造8个调整大小触模柄
            for (int i = 0; i<8; i++)
            {
                _lbl[i] = new Label();
                _lbl[i].TabIndex = i;
                _lbl[i].FlatStyle = 0 ;
                _lbl[i].BorderStyle = BorderStyle.FixedSingle;
                _lbl[i].BackColor = BOX_COLOR;
                _lbl[i].Cursor = _arrArrow[i];
                _lbl[i].Text = "";
                _lbl[i].BringToFront();
                _lbl[i].MouseDown += new MouseEventHandler(this.handle_MouseDown);
                _lbl[i].MouseMove += new MouseEventHandler(this.handle_MouseMove);
                _lbl[i].MouseUp += new MouseEventHandler(this.handle_MouseUp);
            }

            CreateTextBox();
            Create();

            //Control_Click((object)sender, (System.EventArgs)e);
        }

        #endregion

        需拖动控件键盘事件#region 需拖动控件键盘事件

        private void textBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyValue == 37 || e.KeyValue == 38 || e.KeyValue == 39 || e.KeyValue == 40)
            {
                if (e.KeyValue == 37)
                    _MControl.Left -= 1;
                if (e.KeyValue == 38)
                    _MControl.Top -=1;
                if (e.KeyValue == 39)
                    _MControl.Left += 1;
                if (e.KeyValue == 40)
                    _MControl.Top +=1;
                MoveHandles();
                ControlLocality();
                _MControl.Visible = true;
            }

            if (e.KeyValue == 46)
            {
                for (int i = 0; i<8; i++)
                {
                    _MControl.Parent.Controls.Remove(_lbl[i]);
                }
                _MControl.Parent.Controls.Remove(_MControl);
                _textbox.Parent.Controls.Remove(_textbox);
            }

            if (e.KeyValue == 17)
            {
                _IsCtrlKey = true;
                //MessageBox.Show("a");
            }
        }

        #endregion

        需拖动控件鼠标事件#region 需拖动控件鼠标事件

        private void Control_Click(object sender, System.EventArgs e)
        {
            _textbox.Focus();
            _MControl = (sender as Control);
            MoveHandles();

            if (_IsCtrlKey == false)
            {
                for(int i=0;i<_MControl.Parent.Controls.Count;i++)
                {
                    if(_MControl.Parent.Controls[i].Text.Trim().Length == 0 && _MControl.Parent.Controls[i] is Label)
                    {
                        _MControl.Parent.Controls[i].Visible = false;
                    }
                }
            }
        }

        private void Control_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            _IsMouseDown = true;
            _oPointClicked = new Point(e.X,e.Y);
            for (int i = 0; i<8; i++)
            {
                _MControl.Parent.Controls.Add(_lbl[i]);
                _lbl[i].BringToFront();
            }
            HideHandles();
        }

        private void Control_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            _IsMouseDown = false;
            MoveHandles();
            ShowHandles();
            _MControl.Visible = true;
        }

        private void Control_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if(_IsMouseDown)
            {
                int l =  _MControl.Left + e.X - _oPointClicked.X;
                int t = _MControl.Top + e.Y - _oPointClicked.Y;
                int w = _MControl.Width;
                int h = _MControl.Height;
                l =(l<0)?0:((l+w > _MControl.Parent.ClientRectangle.Width)?
                    _MControl.Parent.ClientRectangle.Width-w:l);
                t =(t<0)?0:((t+h> _MControl.Parent.ClientRectangle.Height)?
                    _MControl.Parent.ClientRectangle.Height-h:t);
                _MControl.Left = l;
                _MControl.Top = t;
                ControlLocality();
            }
            //_MControl.Cursor=Cursors.SizeAll;
        }

        #endregion

        调整大小触模柄鼠标事件#region 调整大小触模柄鼠标事件

        private void handle_MouseDown(object sender, MouseEventArgs e)
        {
            _dragging = true;
            _startl = _MControl.Left;
            _startt = _MControl.Top;
            _startw = _MControl.Width;
            _starth = _MControl.Height;
            HideHandles();
        }

        // 通过触模柄调整控件大小
        //    0   1   2
        //  7       3
        //  6   5   4
        private void handle_MouseMove(object sender, MouseEventArgs e)
        {
            int l = _MControl.Left;
            int w = _MControl.Width;
            int t = _MControl.Top;
            int h = _MControl.Height;
            if (_dragging)
            {
                switch (((Label)sender).TabIndex)
                {
                        //l算法:控件左边X坐标 + 鼠标在触模柄X坐标 < 控件左边X坐标 + 父控件宽度 - 控件大小 ?控件左边X坐标 + 鼠标在触模柄X坐标 :控件左边X坐标 + 父控件宽度 - 控件大小 
                        //t算法:
                        //w算法:
                        //h算法:
                    case 0: // _dragging top-left sizing box
                        l = _startl + e.X < _startl + _startw - MIN_SIZE ? _startl + e.X : _startl + _startw - MIN_SIZE;
                        t = _startt + e.Y < _startt + _starth - MIN_SIZE ? _startt + e.Y : _startt + _starth - MIN_SIZE;
                        w = _startl + _startw - _MControl.Left;
                        h = _startt + _starth - _MControl.Top;
                        break;
                    case 1: // _dragging top-center sizing box
                        t = _startt + e.Y < _startt + _starth - MIN_SIZE ? _startt + e.Y : _startt + _starth - MIN_SIZE;
                        h = _startt + _starth - _MControl.Top;
                        break;
                    case 2: // _dragging top-right sizing box
                        w = _startw + e.X > MIN_SIZE ? _startw + e.X : MIN_SIZE;
                        t = _startt + e.Y < _startt + _starth - MIN_SIZE ? _startt + e.Y : _startt + _starth - MIN_SIZE;
                        h = _startt + _starth - _MControl.Top;
                        break;
                    case 3: // _dragging right-middle sizing box
                        w = _startw + e.X > MIN_SIZE ? _startw + e.X : MIN_SIZE;
                        break;
                    case 4: // _dragging right-bottom sizing box
                        w = _startw + e.X > MIN_SIZE ? _startw + e.X : MIN_SIZE;
                        h = _starth + e.Y > MIN_SIZE ? _starth + e.Y : MIN_SIZE;
                        break;
                    case 5: // _dragging center-bottom sizing box
                        h = _starth + e.Y > MIN_SIZE ? _starth + e.Y : MIN_SIZE;
                        break;
                    case 6: // _dragging left-bottom sizing box
                        l = _startl + e.X < _startl + _startw - MIN_SIZE ? _startl + e.X : _startl + _startw - MIN_SIZE;
                        w = _startl + _startw - _MControl.Left;
                        h = _starth + e.Y > MIN_SIZE ? _starth + e.Y : MIN_SIZE;
                        break;
                    case 7: // _dragging left-middle sizing box
                        l = _startl + e.X < _startl + _startw - MIN_SIZE ? _startl + e.X : _startl + _startw - MIN_SIZE;
                        w = _startl + _startw - _MControl.Left;
                        break;
                }
                l =(l<0)?0:l;
                t =(t<0)?0:t;
                _MControl.SetBounds(l,t,w,h);
            }
        }

        private void handle_MouseUp(object sender, MouseEventArgs e)
        {
            _dragging = false;
            MoveHandles();
            ShowHandles();
        }

        #endregion

        private方法#region private方法

        private void Create()
        {
            //_IsMouseDown = true;
            //_oPointClicked = new Point(e.X,e.Y);
            for (int i = 0; i<8; i++)
            {
                _MControl.Parent.Controls.Add(_lbl[i]);
                _lbl[i].BringToFront();
            }
            HideHandles();
        }

        private void CreateTextBox()
        {
            _textbox = new TextBox();
            _textbox.CreateControl();
            _textbox.Parent = _MControl.Parent;
            _textbox.Width = 0;
            _textbox.Height = 0;
            _textbox.TabStop = true;
            _textbox.KeyDown += new System.Windows.Forms.KeyEventHandler(textBox_KeyDown);
        }

        private void ControlLocality()
        {
            if (_MControl.Location.X < 0)
            {
                _MControl.Visible = false;
                _MControl.Left = 0;
            }
            if (_MControl.Location.Y < 0)
            {
                _MControl.Visible = false;
                _MControl.Top = 0;
            }
            if (_MControl.Location.X + _MControl.Width > _MControl.Parent.Width)
            {
                _MControl.Visible = false;
                _MControl.Left = _MControl.Parent.Width - _MControl.Width;
            }
            if (_MControl.Location.Y + _MControl.Height > _MControl.Parent.Height)
            {
                _MControl.Visible = false;
                _MControl.Top = _MControl.Parent.Height - _MControl.Height;
            }
        }

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

        private void MoveHandles()
        {
            int sX = _MControl.Left - BOX_SIZE;
            int sY = _MControl.Top - BOX_SIZE;
            int sW = _MControl.Width + BOX_SIZE;
            int sH = _MControl.Height + BOX_SIZE;
            int hB = BOX_SIZE / 2;
            int[] arrPosX = new int[] {sX+hB, sX + sW / 2, sX + sW-hB, sX + sW-hB,
                                          sX + sW-hB, sX + sW / 2, sX+hB, sX+hB};
            int[] arrPosY = new int[] {sY+hB, sY+hB, sY+hB, sY + sH / 2, sY + sH-hB,
                                          sY + sH-hB, sY + sH-hB, sY + sH / 2};
            for(int i=0; i<8; i++)
            {
                _lbl[i].SetBounds(arrPosX[i], arrPosY[i], BOX_SIZE, BOX_SIZE);
            }
        }

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

        #endregion
    }
}
 

作用是在运行时刻自动对其它可视控件进行动态的位置/大小调整.这个控件实现的功能和VB.Net的窗体布局功能类似.比如你的窗体中有一个DBGrid控件,占了很大一部分,下边有几个按钮 现在需要窗体的大小可调,以使DBGrid可以看到更多的数据,这样的话,窗体上的控件就都需要调整,不然只有窗体变化,而控件不动的话就达不到预期效果,而且很难看.原来的方式是在窗口的Resize事件中添加调整控件大小/位置的代码,这样做的话比较麻烦,要自己手动去计算宽度/偏移,然后将这些代码写死在程序中,以后增加控件或者调整布局都需要重新计算/修改代码,不利于维护. 有了这个控件就方便多了,Resize事件中一行代码不用写,只需将这个控件拖动到窗体上,然后设置被调整控件的Tag属性,在运行时刻就可以进行调整了.VB6ResizerLib 2.0 版本新增分隔条控件,运行时可动态调整.同时修改了1.x版本中控件在退出程序前不会被释放及其导致的一系列问题.VB6ResizerLib 2.2 修正了2.0版本中使用DesignTimeInit模式的时候可能会导致VB崩溃的问题.使用说明:启动VB程序,打开一个工程.按Ctrl+T打开部件对话框.找到并选中VB6ResizerLib后点击确定.将工具箱中新出现的VB6Resizer控件拖动到窗体上即可.被调整控件需要使用Tag属性定义调整规则,方式如下:H-调整控件自身高度.W-调整空间自身宽度.T-调整控件与容器顶部距离.L-调整控件与容器左侧距离.例如―HW‖表示自动调整高度和宽度.TL的优先级高于HW,如果Tag同时包含T和H,则仅T有效.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值