Skip to content

Commit fd01dc1

Browse files
authored
Observable collection Move behavior #355 (#362)
* Observable collection Move behavior #355 * Update src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs
1 parent 8b8d5c5 commit fd01dc1

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

src/GongSolutions.WPF.DragDrop/DefaultDropHandler.cs

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
45
using System.ComponentModel;
56
using System.Linq;
67
using System.Windows;
@@ -181,23 +182,27 @@ public virtual void Drop(IDropInfo dropInfo)
181182

182183
var destinationList = dropInfo.TargetCollection.TryGetList();
183184
var data = ExtractData(dropInfo.Data).OfType<object>().ToList();
184-
185+
bool forceMoveBehavior = false;
185186
var copyData = ShouldCopyData(dropInfo);
186187
if (!copyData)
187188
{
188189
var sourceList = dropInfo.DragInfo.SourceCollection.TryGetList();
189190
if (sourceList != null)
190191
{
191-
foreach (var o in data)
192+
forceMoveBehavior = SameObservableCollection(sourceList, destinationList);
193+
if (!forceMoveBehavior)
192194
{
193-
var index = sourceList.IndexOf(o);
194-
if (index != -1)
195+
foreach (var o in data)
195196
{
196-
sourceList.RemoveAt(index);
197-
// so, is the source list the destination list too ?
198-
if (destinationList != null && Equals(sourceList, destinationList) && index < insertIndex)
197+
var index = sourceList.IndexOf(o);
198+
if (index != -1)
199199
{
200-
--insertIndex;
200+
sourceList.RemoveAt(index);
201+
// so, is the source list the destination list too ?
202+
if (destinationList != null && Equals(sourceList, destinationList) && index < insertIndex)
203+
{
204+
--insertIndex;
205+
}
201206
}
202207
}
203208
}
@@ -223,7 +228,19 @@ public virtual void Drop(IDropInfo dropInfo)
223228
}
224229

225230
objects2Insert.Add(obj2Insert);
226-
destinationList.Insert(insertIndex++, obj2Insert);
231+
if (!cloneData && forceMoveBehavior)
232+
{
233+
int index = destinationList.IndexOf(o);
234+
if (insertIndex > index)
235+
{
236+
insertIndex--;
237+
}
238+
Move(destinationList, index, insertIndex++);
239+
}
240+
else
241+
{
242+
destinationList.Insert(insertIndex++, obj2Insert);
243+
}
227244
}
228245

229246
var selectDroppedItems = itemsControl is TabControl || (itemsControl != null && DragDrop.GetSelectDroppedItems(itemsControl));
@@ -234,6 +251,28 @@ public virtual void Drop(IDropInfo dropInfo)
234251
}
235252
}
236253

254+
private static void Move(IList list, int sourceIndex, int destinationIndex)
255+
{
256+
if (!IsObservableCollection(list))
257+
throw new ArgumentException("ObservableCollection<T> was expected", nameof(list));
258+
var method = list.GetType().GetMethod("Move",
259+
System.Reflection.BindingFlags.Instance
260+
| System.Reflection.BindingFlags.Public);
261+
method.Invoke(list, new object[] { sourceIndex, destinationIndex });
262+
}
263+
264+
private static bool SameObservableCollection(IList collection1, IList collection2)
265+
{
266+
return ReferenceEquals(collection1, collection2) && IsObservableCollection(collection1);
267+
}
268+
269+
private static bool IsObservableCollection(IList collection)
270+
{
271+
return
272+
collection.GetType().IsGenericType &&
273+
collection.GetType().GetGenericTypeDefinition() == typeof(ObservableCollection<>);
274+
}
275+
237276
protected static bool IsChildOf(UIElement targetItem, UIElement sourceItem)
238277
{
239278
var parent = ItemsControl.ItemsControlFromItemContainer(targetItem);

0 commit comments

Comments
 (0)