detail of the implementation of the methods DragOver and Drop ChampionshipBetViewModel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ChampionshipBetViewModel : IChampionshipBetViewModel, IDropTarget | |
{ | |
//constructor, fields and command same as previous sample | |
public ObservableCollection<IFootballClub> FootballClubs { get; private set; } | |
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; | |
} | |
} | |
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); | |
} | |
} | |
} | |
} | |
//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>(); | |
} | |
} | |
private static int[] MoveAllLeft<T>(ObservableCollection<T> collection, int[] sortedIndices) | |
{ | |
//implementation can be found on github | |
} | |
private static int[] MoveAllRight<T>(ObservableCollection<T> collection, int[] sortedIndices) | |
{ | |
//implementation can be found on github | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment