由于最近有需求,所以自定义了一个随意拖动元素的Behavior.
当然在使用这个自定义的Behavior时,有个小假设:拖动元素必须是Canvas容器的子元素。
实现原理比较简单低效:
监听被拖动元素的PointerMoved事件,当事件触发的时候,获取当前的指针信息,判断是否处于鼠标左键按下状态(Properties.IsLeftButtonPressed,在触摸屏上,手指移动时,该属性也为真),如果为真,就执行改变元素位置的代码,否则不做处理。
原理大致如上。
鉴于比较简单,直接上代码
public class DragBehavior : DependencyObject, IBehavior { private bool isTap = false; private FrameworkElement element; private Canvas surface; public DependencyObject AssociatedObject { get { throw new NotImplementedException(); } } public void Attach(DependencyObject associatedObject) { element = associatedObject as FrameworkElement; element.PointerMoved += Element_PointerMoved; } private void Element_PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e) { var point=e.GetCurrentPoint((UIElement)sender); if (point.Properties.IsLeftButtonPressed) { var pos = point.Position; pos.X = pos.X - element.ActualWidth / 2.0; pos.Y = pos.Y - element.ActualHeight / 2.0; var left = (double)element.GetValue(Canvas.LeftProperty); var top = (double)element.GetValue(Canvas.TopProperty); element.SetValue(Canvas.LeftProperty, left + pos.X); element.SetValue(Canvas.TopProperty, top + pos.Y); } } public void Detach() { if (element != null) { element.PointerMoved -= Element_PointerMoved; } } }
有必要解释的是,pos是相对于被拖动元素自身的位置偏移,而并不是相对于容器的偏移量。
var pos = point.Position; pos.X = pos.X - element.ActualWidth / 2.0; pos.Y = pos.Y - element.ActualHeight / 2.0
这两句目的在于,使指针位于元素中心,默认否则指针会在元素左上角处,比较难看。
最后就是如同普通的Behavior一样,附加到元素上就可以,不过元素一定要是Canvas容器的子元素,并且该元素继承自FrameworkElement(一般多从这儿继承)。
以上代码便是全部。使用时记着要添加Behaviors SDK的引用。
时间: 2024-10-08 21:17:26