[uwp]自定义Behavior之随意拖动

  由于最近有需求,所以自定义了一个随意拖动元素的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的引用。

 

    

 

posted @ 2016-03-26 14:57  DemoApp  阅读(1151)  评论(1编辑  收藏  举报