Control 的DraggerHelper, 拖动控件从此变得很简单。。。

程序员经常要实现拖动控件的功能,一般实现这个功能,都要注册事件,然后写MouseMove的代码,

Point point = Point.Empty;

control.MouseDown += control_MouseDown;
control.MouseMove += control_MouseMove;
 control.MouseLeave += control_MouseLeave;

如果程序的很多地方都有这个逻辑的话,那么代码就会有一大部分的重复了。

 

在网上如果你搜索控件拖动的话,大部分代码都是上面的代码,重复的逻辑,重复的故事。

于是我想,能不能写一个帮助类,当需要拖动的时候,只要调用EnableDrag方法就行了,如下:

private void Form1_Load(object sender, EventArgs e)
{
    DraggerHelper.EnableDrag(button1);
    DraggerHelper.EnableDrag(label1);

    DraggerHelper.DisableDrag(button1);
    DraggerHelper.DisableDrag(label1);
}

 

要实现这个效果,需要一些小技巧,当然,这些已经封装进了DraggerHelper 类。

完整的代码如下:

完整的代码using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ControlDragger
{
    public static class DraggerHelper
    {
        private static DraggerHelperCore helperCore = new DraggerHelperCore();

        public static void EnableDrag(this Control control)
        {
            helperCore.EnableDrag(control);
        }

        public static bool IsControlCanDrag(this Control control)
        {
            return helperCore.IsControlCanDrag(control);
        }

        public static void DisableDrag(this Control control)
        {
            helperCore.DisableDrag(control);
        }
    }

    internal sealed class DraggerHelperCore
    {
        /// <summary>
        /// 光标状态
        /// </summary>
        private enum EnumMousePointPosition
        {
            MouseSizeNone = 0, //'无   
            MouseSizeRight = 1, //'拉伸右边框   
            MouseSizeLeft = 2, //'拉伸左边框   
            MouseSizeBottom = 3, //'拉伸下边框   
            MouseSizeTop = 4, //'拉伸上边框   
            MouseSizeTopLeft = 5, //'拉伸左上角   
            MouseSizeTopRight = 6, //'拉伸右上角   
            MouseSizeBottomLeft = 7, //'拉伸左下角   
            MouseSizeBottomRight = 8, //'拉伸右下角   
            MouseDrag = 9   // '鼠标拖动
        }

        private const int Band = 5;
        private const int MinWidth = 10;
        private const int MinHeight = 10;
        private EnumMousePointPosition m_MousePointPosition;

        internal class DragControlProperty
        {
            public Point PositionMovePoint { get; set; }

            public Point SizeChangeMovePoint { get; set; }
        }

        Dictionary<Control, DragControlProperty> controlPropertyDic = new Dictionary<Control, DragControlProperty>();

        public bool IsControlCanDrag(Control control)
        {
            return controlPropertyDic.ContainsKey(control);
        }

        public void EnableDrag(Control control)
        {
            if (!controlPropertyDic.ContainsKey(control))
            {
                controlPropertyDic.Add(control, new DragControlProperty() { });

                control.MouseDown += control_MouseDown;
                control.MouseMove += control_MouseMove;
                control.MouseLeave += control_MouseLeave;
            }
        }

        public void DisableDrag(Control control)
        {
            if (controlPropertyDic.ContainsKey(control))
            {
                controlPropertyDic.Remove(control);

                control.MouseDown -= control_MouseDown;
                control.MouseMove -= control_MouseMove;
                control.MouseLeave -= control_MouseLeave;
            }
        }

        void control_MouseLeave(object sender, EventArgs e)
        {
            m_MousePointPosition = EnumMousePointPosition.MouseSizeNone;
            Cursor.Current = Cursors.Arrow;
        }

        void control_MouseMove(object sender, MouseEventArgs e)
        {
            Control lCtrl = (sender as Control);
            DragControlProperty property = GetControlProperty(lCtrl);

            if (e.Button == MouseButtons.Left)
            {
                switch (m_MousePointPosition)
                {
                    case EnumMousePointPosition.MouseDrag:
                        lCtrl.Left = lCtrl.Left + e.X - property.PositionMovePoint.X;
                        lCtrl.Top = lCtrl.Top + e.Y - property.PositionMovePoint.Y;
                        break;
                    case EnumMousePointPosition.MouseSizeBottom:
                        lCtrl.Height = lCtrl.Height + e.Y - property.SizeChangeMovePoint.Y;
                        property.SizeChangeMovePoint = e.Location; //'记录光标拖动的当前点   
                        break;
                    case EnumMousePointPosition.MouseSizeBottomRight:
                        lCtrl.Width = lCtrl.Width + e.X - property.SizeChangeMovePoint.X;
                        lCtrl.Height = lCtrl.Height + e.Y - property.SizeChangeMovePoint.Y;
                        property.SizeChangeMovePoint = e.Location; //'记录光标拖动的当前点   
                        break;
                    case EnumMousePointPosition.MouseSizeRight:
                        lCtrl.Width = lCtrl.Width + e.X - property.SizeChangeMovePoint.X;
                        //       lCtrl.Height = lCtrl.Height + e.Y - property.p1.Y;   
                        property.SizeChangeMovePoint = e.Location; //'记录光标拖动的当前点   
                        break;
                    case EnumMousePointPosition.MouseSizeTop:
                        lCtrl.Top = lCtrl.Top + (e.Y - property.PositionMovePoint.Y);
                        lCtrl.Height = lCtrl.Height - (e.Y - property.PositionMovePoint.Y);
                        break;
                    case EnumMousePointPosition.MouseSizeLeft:
                        lCtrl.Left = lCtrl.Left + e.X - property.PositionMovePoint.X;
                        lCtrl.Width = lCtrl.Width - (e.X - property.PositionMovePoint.X);
                        break;
                    case EnumMousePointPosition.MouseSizeBottomLeft:
                        lCtrl.Left = lCtrl.Left + e.X - property.PositionMovePoint.X;
                        lCtrl.Width = lCtrl.Width - (e.X - property.PositionMovePoint.X);
                        lCtrl.Height = lCtrl.Height + e.Y - property.SizeChangeMovePoint.Y;
                        property.SizeChangeMovePoint = e.Location; //'记录光标拖动的当前点   
                        break;
                    case EnumMousePointPosition.MouseSizeTopRight:
                        lCtrl.Top = lCtrl.Top + (e.Y - property.PositionMovePoint.Y);
                        lCtrl.Width = lCtrl.Width + (e.X - property.SizeChangeMovePoint.X);
                        lCtrl.Height = lCtrl.Height - (e.Y - property.PositionMovePoint.Y);
                        property.SizeChangeMovePoint = e.Location; //'记录光标拖动的当前点   
                        break;
                    case EnumMousePointPosition.MouseSizeTopLeft:
                        lCtrl.Left = lCtrl.Left + e.X - property.PositionMovePoint.X;
                        lCtrl.Top = lCtrl.Top + (e.Y - property.PositionMovePoint.Y);
                        lCtrl.Width = lCtrl.Width - (e.X - property.PositionMovePoint.X);
                        lCtrl.Height = lCtrl.Height - (e.Y - property.PositionMovePoint.Y);
                        break;
                    default:
                        break;
                }
                if (lCtrl.Width < MinWidth) lCtrl.Width = MinWidth;
                if (lCtrl.Height < MinHeight) lCtrl.Height = MinHeight;
            }
            else
            {
                m_MousePointPosition = MousePointPosition(lCtrl.Size, e);   //'判断光标的位置状态   
                switch (m_MousePointPosition)   //'改变光标   
                {
                    case EnumMousePointPosition.MouseSizeNone:
                        Cursor.Current = Cursors.Arrow;        //'箭头   
                        break;
                    case EnumMousePointPosition.MouseDrag:
                        Cursor.Current = Cursors.SizeAll;      //'四方向   
                        break;
                    case EnumMousePointPosition.MouseSizeBottom:
                        Cursor.Current = Cursors.SizeNS;       //'南北   
                        break;
                    case EnumMousePointPosition.MouseSizeTop:
                        Cursor.Current = Cursors.SizeNS;       //'南北   
                        break;
                    case EnumMousePointPosition.MouseSizeLeft:
                        Cursor.Current = Cursors.SizeWE;       //'东西   
                        break;
                    case EnumMousePointPosition.MouseSizeRight:
                        Cursor.Current = Cursors.SizeWE;       //'东西   
                        break;
                    case EnumMousePointPosition.MouseSizeBottomLeft:
                        Cursor.Current = Cursors.SizeNESW;     //'东北到南西   
                        break;
                    case EnumMousePointPosition.MouseSizeBottomRight:
                        Cursor.Current = Cursors.SizeNWSE;     //'东南到西北   
                        break;
                    case EnumMousePointPosition.MouseSizeTopLeft:
                        Cursor.Current = Cursors.SizeNWSE;     //'东南到西北   
                        break;
                    case EnumMousePointPosition.MouseSizeTopRight:
                        Cursor.Current = Cursors.SizeNESW;     //'东北到南西   
                        break;
                    default:
                        break;
                }
            }

        }

        void control_MouseDown(object sender, MouseEventArgs e)
        {
            var property = GetControlProperty(sender as Control);

            property.PositionMovePoint = e.Location;
            property.SizeChangeMovePoint = e.Location;
        }

        private DragControlProperty GetControlProperty(Control control)
        {
            return controlPropertyDic[control];
        }

        private EnumMousePointPosition MousePointPosition(Size size, System.Windows.Forms.MouseEventArgs e)
        {

            if ((e.X >= -1 * Band) | (e.X <= size.Width) | (e.Y >= -1 * Band) | (e.Y <= size.Height))
            {
                if (e.X < Band)
                {
                    if (e.Y < Band) { return EnumMousePointPosition.MouseSizeTopLeft; }
                    else
                    {
                        if (e.Y > -1 * Band + size.Height)
                        { return EnumMousePointPosition.MouseSizeBottomLeft; }
                        else
                        { return EnumMousePointPosition.MouseSizeLeft; }
                    }
                }
                else
                {
                    if (e.X > -1 * Band + size.Width)
                    {
                        if (e.Y < Band)
                        { return EnumMousePointPosition.MouseSizeTopRight; }
                        else
                        {
                            if (e.Y > -1 * Band + size.Height)
                            { return EnumMousePointPosition.MouseSizeBottomRight; }
                            else
                            { return EnumMousePointPosition.MouseSizeRight; }
                        }
                    }
                    else
                    {
                        if (e.Y < Band)
                        {
                            return EnumMousePointPosition.MouseSizeTop;
                        }
                        else
                        {
                            if (e.Y > -1 * Band + size.Height)
                            {
                                return EnumMousePointPosition.MouseSizeBottom;
                            }
                            else
                            {
                                return EnumMousePointPosition.MouseDrag;
                            }
                        }
                    }
                }
            }
            else
            {
                return EnumMousePointPosition.MouseSizeNone;
            }
        }

    }

}

 

这里是如何使用DragHelper的例子:

private void Form1_Load(object sender, EventArgs e)
{
    DraggerHelper.EnableDrag(button1);
    DraggerHelper.EnableDrag(label1);

    DraggerHelper.DisableDrag(button1);
    DraggerHelper.DisableDrag(label1);
}

private void button1_Click(object sender, EventArgs e)
{
    if (label1.IsControlCanDrag())
    {
        label1.DisableDrag();
    }
    else
    {
        label1.EnableDrag();
    }
}

 完整的代码:ControlDragger.rar

 

本文参考了:WCCC的杰出的文章:http://www.cnblogs.com/whc-blog/archive/2011/08/26/2154038.html

另外本文不讨论设计,虽然我知道当前设计不一定是最好的,很多复杂的情况都没有涵盖到,不过基本的情况已经覆盖了,欢迎大家扩展和填充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
介绍:用ViewDragHelper实现的activity切换动画。运行效果:使用说明: 你可以将这个库当成view来用:将DraggerView添加到root layout,并且在里面加入两个layout。<com.github.library.DraggerView     android:layout_width="match_parent"     android:layout_height="match_parent"     dragger_layout:drag_view_id="@ id/drag_view"     dragger_layout:shadow_view_id="@ id/shadow_view"     dragger_layout:drag_position="top">       <FrameLayout           android:id="@ id/shadow_view"           android:layout_width="match_parent"           android:layout_height="match_parent"           android:background="@color/transparent"           android:visibility="invisible"/>         <LinearLayout           android:id="@ id/drag_view"           android:layout_width="match_parent"           android:layout_height="match_parent"/>   </com.github.library.DraggerView>style文件中这样设置<style name="YourTheme" parent="Theme.AppCompat.Light.DarkActionBar">     <item name="android:windowIsTranslucent">true</item>       <item name="android:windowBackground">@android:color/transparent</item>       <item name="android:windowNoTitle">true</item>       <item name="windowActionBar">false</item>       <item name="android:windowAnimationStyle">@null</item> </style>manifest中<activity     android:name="com.github.dragger.BaseActivity"     android:theme="@style/YourTheme"/>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值