private void DataGrid_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                DataGridRow row = UIHelper.FindVisualParent <DataGridRow>(e.OriginalSource as FrameworkElement);
                if (row != null && row.IsSelected)
                {
                    _source     = UIHelper.FindVisualParent <DataGrid>(row).ItemsSource;
                    _itemToMove = row.Item;
                    DragDropEffects           finalEffects = DragDrop.DoDragDrop(row, _itemToMove, AllowedEffects);
                    DataGridDragDropEventArgs args         = new DataGridDragDropEventArgs()
                    {
                        Destination   = _destination,
                        Direction     = _direction,
                        DroppedObject = _itemToMove,
                        Effects       = finalEffects,
                        Source        = _source,
                        TargetObject  = _dropTarget
                    };

                    if (_dropTarget != null && Command != null && Command.CanExecute(args))
                    {
                        Command.Execute(args);

                        _itemToMove  = null;
                        _dropTarget  = null;
                        _source      = null;
                        _destination = null;
                        _direction   = DataGridDragDropDirection.Indeterminate;
                        _lastIndex   = -1;
                    }
                }
            }
        }
        private void DataGrid_CheckDropTarget(object sender, DragEventArgs e)
        {
            var row = UIHelper.FindVisualParent <DataGridRow>(DropTarget ?? e.OriginalSource as UIElement);

            if (row == null)
            {
                // Not over a DataGridRow
                e.Effects = DragDropEffects.None;
            }
            else
            {
                var curIndex = row.GetIndex();
                _direction = curIndex > _lastIndex ? DataGridDragDropDirection.Down : (curIndex < _lastIndex ? DataGridDragDropDirection.Up : _direction);
                _lastIndex = curIndex;

                e.Effects = ((e.AllowedEffects & DragDropEffects.Copy) == DragDropEffects.Copy) && (e.KeyStates & DragDropKeyStates.ControlKey) == DragDropKeyStates.ControlKey ? DragDropEffects.Copy : DragDropEffects.Move;
            }

            e.Handled = true;
        }
        private void DataGrid_Drop(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;

            // Verify that this is a valid drop and then store the drop target
            var row = UIHelper.FindVisualParent <DataGridRow>(e.OriginalSource as UIElement);

            if (row != null)
            {
                _destination = UIHelper.FindVisualParent <DataGrid>(row).ItemsSource;
                _dropTarget  = row.Item;
                if (_dropTarget != null)
                {
                    e.Effects = ((e.AllowedEffects & DragDropEffects.Copy) == DragDropEffects.Copy) && (e.KeyStates & DragDropKeyStates.ControlKey) == DragDropKeyStates.ControlKey ? DragDropEffects.Copy : DragDropEffects.Move;
                }
                var item = e.Data.GetData("data");
                var args = new DataGridDragDropEventArgs
                {
                    Destination   = _destination,
                    Direction     = _direction,
                    DroppedObject = item,
                    Effects       = e.Effects,
                    Source        = _source,
                    TargetObject  = _dropTarget
                };

                if (_dropTarget != null &&
                    Command != null &&
                    Command.CanExecute(args))
                {
                    Command.Execute(args);

                    _dropTarget  = null;
                    _source      = null;
                    _destination = null;
                    _direction   = DataGridDragDropDirection.Indeterminate;
                    _lastIndex   = -1;
                }
            }
        }