using GongSolutions.Wpf.DragDrop; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; namespace Dominion.NET_WPF.ViewModel { internal class CardListViewModel : IDropTarget { public bool PreserveSourceOrdering { get; set; } public ObservableCollection Cards { get; set; } public void ShowCards(IEnumerable cards, DominionBase.Piles.Visibility visibility) { var index = 0; Cards = new ObservableCollection(); var _visibility = visibility; foreach (var card in cards) { Cards.Add(new CardViewModel { CardName = card.Name, Card = card, Visibility = _visibility == DominionBase.Piles.Visibility.None ? DominionBase.Piles.Visibility.None : DominionBase.Piles.Visibility.All, OriginalIndex = index++ }); if (_visibility == DominionBase.Piles.Visibility.Top) _visibility = DominionBase.Piles.Visibility.None; } } public CardListViewModel() { Cards = new ObservableCollection(); } void IDropTarget.DragOver(DropInfo dropInfo) { var targetItem = dropInfo.TargetItem as CardViewModel; if (dropInfo.Data is CardViewModel && (targetItem != null || dropInfo.TargetCollection != null)) { dropInfo.Effects = DragDropEffects.Move; if (!PreserveSourceOrdering) dropInfo.DropTargetAdorner = DropTargetAdorners.Insert; } } void IDropTarget.Drop(DropInfo dropInfo) { if (dropInfo.DragInfo == null) return; var insertIndex = dropInfo.InsertIndex; IList sourceList = null; var destinationList = GetList(dropInfo.TargetCollection); var data = ExtractData(dropInfo.Data); if (dropInfo.DragInfo.VisualSource is ListBox lbSource && dropInfo.VisualTarget is ListBox lbTarget && lbSource.DataContext.GetType() == lbTarget.DataContext.GetType()) sourceList = GetList(dropInfo.DragInfo.SourceCollection); if (PreserveSourceOrdering) { foreach (var o in data) { sourceList.Remove(o); insertIndex = -1; if (destinationList.Any()) insertIndex = destinationList.Max(cvm => cvm.OriginalIndex < o.OriginalIndex ? destinationList.IndexOf(cvm) : -1); if (insertIndex == -1) destinationList.Insert(0, o); else if (insertIndex == destinationList.Count - 1) destinationList.Add(o); else destinationList.Insert(insertIndex + 1, o); } } else { if (sourceList != null) { foreach (var o in data) { var index = sourceList.IndexOf(o); if (index != -1) { sourceList.RemoveAt(index); if (sourceList == destinationList && index < insertIndex) --insertIndex; } } } foreach (var o in data) destinationList.Insert(insertIndex++, o); } } protected static IEnumerable ExtractData(object data) { var models = data as IEnumerable; return models ?? Enumerable.Repeat((CardViewModel)data, 1); } protected static IList GetList(IEnumerable enumerable) { if (enumerable is ICollectionView view) return view.SourceCollection as IList; return enumerable as IList; } } }