Skip to content

Instantly share code, notes, and snippets.

@bpatra
Last active August 29, 2015 13:57
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bpatra/9537240 to your computer and use it in GitHub Desktop.
detail of the implementation of the methods DragOver and Drop ChampionshipBetViewModel
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