'Arrangeable Stack panel

I am developing an arrangeable stack panel. When I touch or press the item and release the mouse move, the object or child in the stack panel is stick with it. My code is as below.

namespace Controls.ArrangableGrid
{
    using System;
    using System.Linq;
    using System.Windows;
    using System.Windows.Input;
    using System.ComponentModel;   
    using System.Windows.Controls;    
        
    using System.Windows.Media;
    using System.Windows.Documents;

    public class ArrangableControl : StackPanel
    {
        #region -   Variables   -

        private bool _isDown;
        private bool _isDragging;

        private Point _startPoint;
        private DragAdorner _adorner;
        private UIElement _draggedItem = null;
        private int _draggedItemIndex = -1;

        private ILoggingService _logging = null;
        private ILogger _logger;

        private CypherComponentModel _parentComponent = null;

        #endregion

        public ArrangableControl()
        {
            Orientation = Orientation.Horizontal;
            Background = Brushes.Transparent;

            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                Loaded += OnLoaded;
            }
        }

        #region -   Functions   -

        private void SetEvetns()
        {
                AllowDrop = true;

                Drop += OnDrop;
                
                StylusDown += OnEventDown;
                StylusUp += OnEventUp;
                StylusMove += OnEventMove;

                MouseLeftButtonDown += OnEventDown;
                MouseLeftButtonUp += OnEventUp;
                MouseMove += OnEventMove;                
        }

        private Point GetPosition(InputEventArgs e, IInputElement obj)
        {
            if (e is MouseEventArgs)
            {
                Mouse.Capture(obj);
                return (e as MouseEventArgs).GetPosition(obj);
            }                
            else if (e is TouchEventArgs)
            {
                (e as TouchEventArgs).TouchDevice.Capture(obj);
                return (e as TouchEventArgs).GetTouchPoint(obj).Position;
            }                
            else if (e is StylusEventArgs)
            {
                Stylus.Capture(obj);
                return (e as StylusEventArgs).GetPosition(obj);
            }
            return new Point();
        }

        private void DragStarted()
        {
            if (_draggedItem == null) return;

            _isDragging = true;

            _adorner = new DragAdorner(_draggedItem);
            var layer = AdornerLayer.GetAdornerLayer(_draggedItem);

            layer.Add(_adorner);
        }

        private void DragMoved()
        {
            var currentPosition = Mouse.GetPosition(this);

            _adorner.LeftOffset = currentPosition.X - _startPoint.X;
            _adorner.TopOffset = currentPosition.Y - _startPoint.Y;
        }

        private void DragFinished(bool cancelled, InputEventArgs e)
        {
            this.ReleaseMouseCapture();

            if (null != _adorner)
                AdornerLayer.GetAdornerLayer(_adorner.AdornedElement).Remove(_adorner);

            if (cancelled == false)
            {
                UIElement _dropItem = this.GetChildElement(GetPosition(e, this)) as UIElement;
                if (null != _dropItem)
                    DragDrop.DoDragDrop(_draggedItem, new DataObject("UIElement", e.Source, true), DragDropEffects.Move);
            }
            _adorner = null;
            _isDragging = false;
            _isDown = false;
        }

        #endregion

        #region -   Events   -

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (this.IsLoaded)
            {
                SetEvetns();
            }
        }        

        private void OnEventDown(object sender, InputEventArgs e)
        {
            if(e.Source != this)
            {
                _isDown = true;
                _isDragging = false;

                _startPoint = GetPosition(e, this);
                _draggedItem = e.Source as UIElement;

                if (null != _draggedItem)
                    _draggedItemIndex = this.Children.IndexOf(_draggedItem);
            }
        }

        private void OnEventUp(object sender, InputEventArgs e)
        {
            if (_isDown && _isDragging)
            {
                DragFinished(false, e);
                e.Handled = true;
            }
            else
            {
                e.Handled = true;

                ReleaseMouseCapture();
                ReleaseAllTouchCaptures();
                ReleaseStylusCapture();
            }
        }

        private void OnEventMove(object sender, InputEventArgs e)
        {
            if (_isDown)
            {
                if ((_isDragging == false) &&
                    ((Math.Abs(GetPosition(e, this).X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance) ||
                     (Math.Abs(GetPosition(e, this).Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)))
                    DragStarted();
                if (_isDragging)
                    DragMoved();
            }

            e.Handled = true;
        }

        private void OnDrop(object sender, DragEventArgs e)
        {
            try
            {
                UIElement droptarget = e.Source as UIElement;
                int droptargetIndex = this.Children.IndexOf(droptarget);

                if (_draggedItem != null && (droptargetIndex != _draggedItemIndex))
                {
                    if (droptargetIndex != -1)
                    {
                        this.Children.Remove(_draggedItem);
                        this.Children.Insert(droptargetIndex, _draggedItem);
                    }
                }
                _draggedItem = null;
                _draggedItemIndex = -1;
            }
            catch (Exception ex)
            {
                _logger.Error($"Drop Error: {ex} at {nameof(ArrangableControl)}");
            }
            finally
            {
                e.Handled = true;

                ReleaseMouseCapture();
                ReleaseAllTouchCaptures();
                ReleaseStylusCapture();
            }            
        }

        #endregion
    }
}

What that I am doing wrong in it, when I touch on screen or on mouse the object stuck to it, even if I release the touch or mouse, and while on dragging on touch panel it drops in midway.

I want both functionality drag and drop, and also swiping, if I pressed for 2 second it start drag and drop, while swiping it shouldn't be dragging and dropping.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source