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;
}
}
//大家如果觉得那里有问题 ,请指正吧
浙公网安备 33010602011771号