// If the types of the dragged data and ItemsControl's source are compatible, // there are 3 situations to have into account when deciding the drop target: // 1. mouse is over an items container // 2. mouse is over the empty part of an ItemsControl, but ItemsControl is not empty // 3. mouse is over an empty ItemsControl. // The goal of this method is to decide on the values of the following properties: // targetItemContainer, insertionIndex and isInFirstHalf. private void DecideDropTarget(DragEventArgs e) { int targetItemsControlCount = _target.Items.Count; object draggedItem = e.Data.GetData(ItemsControlDragDrop.Format.Name); if (IsDropDataTypeAllowed(draggedItem)) { if (targetItemsControlCount > 0) { _hasVerticalOrientation = HasVerticalOrientation(_target.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement); _targetItemContainer = _target.ContainerFromElement((DependencyObject)e.OriginalSource) as FrameworkElement; if (_targetItemContainer != null) { Point positionRelativeToItemContainer = e.GetPosition(_targetItemContainer); _isInFirstHalf = IsInFirstHalf(_targetItemContainer, positionRelativeToItemContainer, _hasVerticalOrientation); _insertionIndex = _target.ItemContainerGenerator.IndexFromContainer(_targetItemContainer); if (!_isInFirstHalf) { _insertionIndex++; } } else { _targetItemContainer = _target.ItemContainerGenerator.ContainerFromIndex(targetItemsControlCount - 1) as FrameworkElement; _isInFirstHalf = false; _insertionIndex = targetItemsControlCount; } } else { _targetItemContainer = null; _insertionIndex = 0; } var droppingItem = new CanDropItemEventArgs(draggedItem, _insertionIndex); _target.RaiseEvent(droppingItem); if (!droppingItem.CanDrop) { _targetItemContainer = null; _insertionIndex = -1; e.Effects = DragDropEffects.None; } } else { _targetItemContainer = null; _insertionIndex = -1; e.Effects = DragDropEffects.None; } }
private void ListBox_OnCanDropItem(object sender, CanDropItemEventArgs e) { var segs = (IList<WordSegmentViewModel>) ListBox.ItemsSource; e.CanDrop = (e.Index == segs.Count || !segs[e.Index].IsBoundary) && (e.Index == 0 || !segs[e.Index - 1].IsBoundary); e.Handled = true; }
// If the types of the dragged data and ItemsControl's source are compatible, // there are 3 situations to have into account when deciding the drop target: // 1. mouse is over an items container // 2. mouse is over the empty part of an ItemsControl, but ItemsControl is not empty // 3. mouse is over an empty ItemsControl. // The goal of this method is to decide on the values of the following properties: // targetItemContainer, insertionIndex and isInFirstHalf. private void DecideDropTarget(DragEventArgs e) { int targetItemsControlCount = _target.Items.Count; object draggedItem = e.Data.GetData(ItemsControlDragDrop.Format.Name); if (IsDropDataTypeAllowed(draggedItem)) { if (targetItemsControlCount > 0) { _hasVerticalOrientation = HasVerticalOrientation(_target.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement); _targetItemContainer = _target.ContainerFromElement((DependencyObject)e.OriginalSource) as FrameworkElement; if (_targetItemContainer != null) { Point positionRelativeToItemContainer = e.GetPosition(_targetItemContainer); _isInFirstHalf = IsInFirstHalf(_targetItemContainer, positionRelativeToItemContainer, _hasVerticalOrientation); _insertionIndex = _target.ItemContainerGenerator.IndexFromContainer(_targetItemContainer); if (!_isInFirstHalf) _insertionIndex++; } else { _targetItemContainer = _target.ItemContainerGenerator.ContainerFromIndex(targetItemsControlCount - 1) as FrameworkElement; _isInFirstHalf = false; _insertionIndex = targetItemsControlCount; } } else { _targetItemContainer = null; _insertionIndex = 0; } var droppingItem = new CanDropItemEventArgs(draggedItem, _insertionIndex); _target.RaiseEvent(droppingItem); if (!droppingItem.CanDrop) { _targetItemContainer = null; _insertionIndex = -1; e.Effects = DragDropEffects.None; } } else { _targetItemContainer = null; _insertionIndex = -1; e.Effects = DragDropEffects.None; } }