public void Drop(IDropInfo dropInfo) { var targetIndex = dropInfo.InsertIndex; var selectedItems = this.GetItemsBlock(dropInfo.Data); if (!selectedItems.Any()) { return; } var sourceIndices = selectedItems.Select(c => FootballClubs.IndexOf(c)).ToArray(); var sourceMinIndex = sourceIndices.Min(); if (targetIndex < sourceMinIndex || targetIndex > sourceMinIndex + 1) { if (targetIndex < sourceMinIndex) { for (int i = 0; i < sourceMinIndex - targetIndex; i++) { sourceIndices = MoveAllLeft(FootballClubs, sourceIndices); } } else if (targetIndex > sourceMinIndex + 1) { for (int i = 0; i < targetIndex - sourceMinIndex - 1; i++) { sourceIndices = MoveAllRight(FootballClubs, sourceIndices); } } } }
public void DragOver(IDropInfo dropInfo) { var selectedIndices = this.GetItemsBlock(dropInfo.Data).Select(c => FootballClubs.IndexOf(c)).ToList(); //important: InsertIndex is the index of the item right AFTER the position we are inserting into //consequently the range is within (both included) 0 and Items.Count if (selectedIndices.Any() && !selectedIndices.Contains(dropInfo.InsertIndex)) { dropInfo.DropTargetAdorner = DropTargetAdorners.Insert; dropInfo.Effects = DragDropEffects.Copy; } }
//drag and drop only allows insertion of contiguous blocks... private IEnumerable <IFootballClub> GetItemsBlock(object data) { if (data is IFootballClub) { return(new[] { (IFootballClub)data }); } else if (data is IEnumerable <IFootballClub> ) { var block = ((IEnumerable <IFootballClub>)data).ToArray(); var sortedIndices = block.Select(c => FootballClubs.IndexOf(c)).OrderBy(i => i).ToArray(); if (IsANonDiscontiguousInterval(sortedIndices)) { return((IEnumerable <IFootballClub>)data); } return(Enumerable.Empty <IFootballClub>()); } else { return(Enumerable.Empty <IFootballClub>()); } }