|
@@ -2,6 +2,7 @@
|
|
using System.Windows;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Input;
|
|
|
|
+using System.Windows.Media;
|
|
|
|
|
|
namespace Waaagh.Behaviors {
|
|
namespace Waaagh.Behaviors {
|
|
sealed public class ItemsDraggable {
|
|
sealed public class ItemsDraggable {
|
|
@@ -64,15 +65,19 @@ namespace Waaagh.Behaviors {
|
|
if (args.LeftButton != MouseButtonState.Pressed) {
|
|
if (args.LeftButton != MouseButtonState.Pressed) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (sender is ItemsControl sourceItemsControl == false) {
|
|
|
|
|
|
+ if (sender is ItemsControl source == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (sourceItemsControl.ItemsSource is IList == false) {
|
|
|
|
|
|
+ if (source.ItemsSource is IList == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (GetDragDropEventSource(ref sourceItemsControl, out Control sourceControl, args.GetPosition) == false) {
|
|
|
|
|
|
+ if (GetElement(source, args.GetPosition(source)) is Control sourceControl == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ if (GetParent(sourceControl) is ItemsControl sourceItemsControl == false) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
DataObject data = new DataObject();
|
|
DataObject data = new DataObject();
|
|
data.SetData(DraggableDataFormat, sourceControl.DataContext);
|
|
data.SetData(DraggableDataFormat, sourceControl.DataContext);
|
|
data.SetData(DraggableCollectionFormat, sourceItemsControl.ItemsSource);
|
|
data.SetData(DraggableCollectionFormat, sourceItemsControl.ItemsSource);
|
|
@@ -95,22 +100,25 @@ namespace Waaagh.Behaviors {
|
|
if (args.Effects == DragDropEffects.None) {
|
|
if (args.Effects == DragDropEffects.None) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- if (sender is ItemsControl targetItemsControl == false) {
|
|
|
|
|
|
+ if (sender is ItemsControl target == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- // 获取 拖拽源
|
|
|
|
- object? sourceData = args.Data.GetData(DraggableDataFormat) as object;
|
|
|
|
- IList? sourceCollection = args.Data.GetData(DraggableCollectionFormat) as IList;
|
|
|
|
- if (sourceData == null || sourceCollection == null) {
|
|
|
|
|
|
+ // 获取 放置目标
|
|
|
|
+ if (GetElement(target, args.GetPosition(target)) is Control targetControl == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- // 获取 放置目标
|
|
|
|
- if (GetDragDropEventSource(ref targetItemsControl, out Control targetControl, args.GetPosition) == false) {
|
|
|
|
|
|
+ if (GetParent(targetControl) is ItemsControl targetItemsControl == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
if (targetItemsControl.ItemsSource is IList targetCollection == false) {
|
|
if (targetItemsControl.ItemsSource is IList targetCollection == false) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ // 获取 拖拽源
|
|
|
|
+ object? sourceData = args.Data.GetData(DraggableDataFormat) as object;
|
|
|
|
+ IList? sourceCollection = args.Data.GetData(DraggableCollectionFormat) as IList;
|
|
|
|
+ if (sourceData == null || sourceCollection == null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
// 判断 集合元素类型
|
|
// 判断 集合元素类型
|
|
object? targetData = targetControl.DataContext;
|
|
object? targetData = targetControl.DataContext;
|
|
if (CheckCollectionElementType(sourceCollection, targetCollection) == false) {
|
|
if (CheckCollectionElementType(sourceCollection, targetCollection) == false) {
|
|
@@ -210,6 +218,51 @@ namespace Waaagh.Behaviors {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ static private Control? GetElement(ItemsControl source, Point point) {
|
|
|
|
+ if (GetItemContainerType(source) is Type type == false) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ DependencyObject? dp = source.InputHitTest(point) as DependencyObject;
|
|
|
|
+ while (dp != null) {
|
|
|
|
+ if (dp.GetType().Equals(type)) {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ dp = VisualTreeHelper.GetParent(dp);
|
|
|
|
+ }
|
|
|
|
+ return dp as Control;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static private ItemsControl? GetParent(Control control) {
|
|
|
|
+ for (DependencyObject dp = VisualTreeHelper.GetParent(control); dp != null; dp = VisualTreeHelper.GetParent(dp)) {
|
|
|
|
+ if (dp is ItemsControl parent && parent.ItemContainerGenerator.ContainerFromItem(control.DataContext) != null) {
|
|
|
|
+ return parent;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static private Type? GetItemContainerType(ItemsControl source) {
|
|
|
|
+ if (source == null) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ if (source is ListView) {
|
|
|
|
+ return typeof(ListViewItem);
|
|
|
|
+ }
|
|
|
|
+ else if (source is ListBox) {
|
|
|
|
+ return typeof(ListBoxItem);
|
|
|
|
+ }
|
|
|
|
+ else if (source is TreeView || source is TreeViewItem) {
|
|
|
|
+ return typeof(TreeViewItem);
|
|
|
|
+ }
|
|
|
|
+ // else if (source is GridView) {
|
|
|
|
+ // return typeof(GridViewColumn);
|
|
|
|
+ // }
|
|
|
|
+ if (source.Items.Count > 0) {
|
|
|
|
+ return source.ItemContainerGenerator.ContainerFromIndex(0)?.GetType();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
static private bool CheckCollectionElementType(IList collection1, IList collection2) {
|
|
static private bool CheckCollectionElementType(IList collection1, IList collection2) {
|
|
return collection1.GetType().GetGenericArguments()[0] == collection2.GetType().GetGenericArguments()[0];
|
|
return collection1.GetType().GetGenericArguments()[0] == collection2.GetType().GetGenericArguments()[0];
|
|
}
|
|
}
|