秋天的梦想

 

silverlight 中实现拖动的扩展方法

      今天刚加入博客园,希望能认识更多的朋友。
      silverlight 中,大家可能常常要实现拖动功能,如果写的不好的话,工程中可能会到处都出现MouseLeftButtonDown,MouseMove等事件。
      所以把我常常使用的一个实现拖动的扩展方法分享给大家,使用这个方法,你只要是FrameworkElement的对象,你就可以直接调用这个拓展方法,实现拖动。这个扩展方法,主要是针对FrameworkElement对象,也许你会问为什么为什么不针对UIElement对象,这是因为UIElement对象没有parent属性,而在sl中实现拖动往往是针对Canvas的Children。这个扩展方法已经重载了一个根据设定边界实现拖动的方法,设定边界可以传入一个DragBound得对象,没有用结构体,是因为考虑到具体应用中或许要对设定边界进行一定的逻辑控制。
      如果你希望你被拖动的对象可以取消拖动,那你可以让你拖动的对象继承一下IDrag接口,通过设定IsDrag属性就可以决定是否让对象被拖动。
      废话先不说了,把代码分享给大家,哪里写的不好请指正(第一次写技术博客,所以不会排版,所以大家就不要责怪啦)。

 public static class ExtendMethords
    {
        /// <summary>
        /// 核心拖动扩展方法
        /// </summary>
        /// <param name="dragTarget">被拖动的对象</param>
        /// <param name="dragElement">可用鼠标拖拽的部分</param>
        /// <param name="bound">被拖动对象可移动的范围</param>
        /// <returns></returns>
        public static bool BindDrag(this FrameworkElement dragTarget, FrameworkElement dragElement, DragBound bound)
        {
            bool result = false;
            if (dragTarget.Parent != null && (dragTarget.Parent as Canvas) != null)
            {
                Canvas moveCvs = dragTarget.Parent as Canvas;
                Point downPosition = new Point();
                Point ParentPosition = new Point();
                bool isDrag = false;
                DragBoundCheck check = new DragBoundCheck(dragTarget, bound);
                dragElement.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
                {
                    IDrag dragObj = dragTarget as IDrag;
                    if (dragObj != null && dragObj.IsDrag == false)
                    {
                        return;
                    }
                    if (dragElement.CaptureMouse())
                    {
                        downPosition = e.GetPosition(dragElement);
                        Point mouseOnParentPosition = e.GetPosition(moveCvs);
                        Point mouseOnSlPosition = e.GetPosition(null);
                        ParentPosition = mouseOnSlPosition.Sub(mouseOnParentPosition);
                        isDrag = true;
                    }
                };
                dragElement.MouseMove += delegate(object sender, MouseEventArgs e)
                {
                    if (isDrag)
                    {
                        Point mouseOnSlPosition = e.GetPosition(null);
                        Point targetOnSlPosition = mouseOnSlPosition.Sub(downPosition);
                        targetOnSlPosition = check.GetInBoundPosition(targetOnSlPosition);
                        Point targetOnParentPosition = targetOnSlPosition.Sub(ParentPosition);
                        dragTarget.SetPosition(targetOnParentPosition);

                    }
                };
                dragElement.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e)
                {
                    if (isDrag)
                    {
                        isDrag = false;
                        dragElement.ReleaseMouseCapture();
                    }
                };
                result = true;
            }
            return result;
        }
        /// <summary>
        /// 拖动扩展方法,可以被到处拖动
        /// </summary>
        /// <param name="dragTarget">被拖动的对象</param>
        /// <param name="dragElement">用鼠标拖拽的部分</param>
        /// <returns></returns>
        public static bool BindDrag(this FrameworkElement dragTarget, FrameworkElement dragElement)
        {
            DragBound bound = new DragBound();
            return BindDrag(dragTarget, dragElement, bound);
        }
        /// <summary>
        /// 拖动扩展方法,可用鼠标拖拽的部分就是被拖动对象本身
        /// </summary>
        /// <param name="dragTarget"></param>
        /// <param name="bound"></param>
        /// <returns></returns>
        public static bool BindDrag(this FrameworkElement dragTarget, DragBound bound)
        {

            return BindDrag(dragTarget, dragTarget, bound);
        }
        /// <summary>
        /// 没有任何限定的拖动方法
        /// </summary>
        /// <param name="dragTarget"></param>
        /// <returns></returns>
        public static bool BindDrag(this FrameworkElement dragTarget)
        {
            DragBound bound = new DragBound();
            return BindDrag(dragTarget, bound);
        }

         //一下几个函数比较简单,大家一看就明白,就不写注释了,呵呵。
        public static void SetLeft(this FrameworkElement element,double leftPosition)
        {
            element.SetValue(Canvas.LeftProperty, leftPosition);
        }
        public static void SetTop(this FrameworkElement element, double topPosition)
        {
            element.SetValue(Canvas.TopProperty, topPosition);
        }
        public static void SetPosition(this FrameworkElement element, Point position)
        {
            element.SetLeft(position.X);
            element.SetTop(position.Y);
        }

        public static Point Sub(this Point selfPoint, Point subPoint)
        {
            Point result = new Point(selfPoint.X - subPoint.X, selfPoint.Y - subPoint.Y);
            return result;
        }
        public static Point Add(this Point selfPoint, Point addPoint)
        {
            Point result = new Point(selfPoint.X + addPoint.X, selfPoint.Y + addPoint.Y);
            return result;
        }
    
    }

      //函数里面有这么几个类,逻辑也很简单,就直接贴在这里了
      

      public interface IDrag
    {
        bool IsDrag { set; get; }
    }
    /// <summary>
    /// 检测位置是否在设定的范围内
    /// </summary>
    internal class DragBoundCheck
    {
        private FrameworkElement element;
        private DragBound bound;
        public DragBoundCheck(FrameworkElement element,DragBound bound)
        {
                this.element = element;
                this.bound = bound;
        }

        public Point GetInBoundPosition(Point newPosition)
        {
         
            if (newPosition.X > bound.Right-element.ActualWidth)
            {
                newPosition.X = bound.Right - element.ActualWidth;
            }
            if (newPosition.X < bound.Left)
            {
                newPosition.X = bound.Left;
            }
            if (newPosition.Y < bound.Top)
            {
                newPosition.Y = bound.Top;
            }
            if (newPosition.Y > bound.Bottom-element.ActualHeight)
            {
                newPosition.Y = bound.Bottom - element.ActualHeight;
            }
            return newPosition;
        }
    }
    /// <summary>
    ///  设定拖动的范围
    /// </summary>
    public class DragBound
    {
        public double Top { set; get; }
        public double Bottom
        {
            set;
            get;
        }
        public double Left { set; get; }
        public double Right
        {
            set;
            get;
        }
        public DragBound()
        {
            Top = 0.0;
            Left = 0.0;
            //Right = (double)System.Windows.Browser.HtmlPage.Window.Eval("window");
            //Bottom = (double)System.Windows.Browser.HtmlPage.Window.Eval("window");
            Right = double.MaxValue;
            Bottom = double.MaxValue;
        }
    }

      //大家如果觉得那里有问题 ,请指正吧

posted on 2009-09-14 22:12  秋天的梦想  阅读(972)  评论(4)    收藏  举报

导航