ItemNudgeDropBehavior.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using Avalonia.Controls;
  2. using Avalonia.Input;
  3. using Avalonia.Interactivity;
  4. using Avalonia.Layout;
  5. using Avalonia.Media.Transformation;
  6. using Avalonia.Xaml.Interactivity;
  7. namespace Avalonia.Xaml.Interactions.Custom;
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. public class ItemNudgeDropBehavior : StyledElementBehavior<ItemsControl>
  12. {
  13. /// <summary>
  14. ///
  15. /// </summary>
  16. public static readonly StyledProperty<Orientation> OrientationProperty =
  17. AvaloniaProperty.Register<ItemNudgeDropBehavior, Orientation>(nameof(Orientation),
  18. defaultValue: Orientation.Vertical);
  19. /// <summary>
  20. ///
  21. /// </summary>
  22. public Orientation Orientation
  23. {
  24. get => GetValue(OrientationProperty);
  25. set => SetValue(OrientationProperty, value);
  26. }
  27. /// <inheritdoc />
  28. protected override void OnAttachedToVisualTree()
  29. {
  30. AssociatedObject?.AddHandler(DragDrop.DragLeaveEvent, OnDragLeave);
  31. AssociatedObject?.AddHandler(DragDrop.DragOverEvent, OnDragOver);
  32. AssociatedObject?.AddHandler(DragDrop.DropEvent, OnDrop);
  33. }
  34. /// <inheritdoc />
  35. protected override void OnDetachedFromVisualTree()
  36. {
  37. AssociatedObject?.RemoveHandler(DragDrop.DragLeaveEvent, OnDragLeave);
  38. AssociatedObject?.RemoveHandler(DragDrop.DragOverEvent, OnDragOver);
  39. AssociatedObject?.RemoveHandler(DragDrop.DropEvent, OnDrop);
  40. }
  41. private void ApplyTranslation(Control control, double x, double y)
  42. {
  43. var transformBuilder = new TransformOperations.Builder(1);
  44. transformBuilder.AppendTranslate(x, y);
  45. control.RenderTransform = transformBuilder.Build();
  46. }
  47. private void RemoveTranslations(object? sender)
  48. {
  49. if (sender is ItemsControl itemsControl)
  50. {
  51. foreach (var container in itemsControl.GetRealizedContainers())
  52. {
  53. ApplyTranslation(container, 0, 0);
  54. }
  55. }
  56. }
  57. private void OnDrop(object? sender, DragEventArgs e)
  58. {
  59. RemoveTranslations(sender);
  60. }
  61. private void OnDragLeave(object? sender, RoutedEventArgs e)
  62. {
  63. RemoveTranslations(sender);
  64. }
  65. private void OnDragOver(object? sender, DragEventArgs e)
  66. {
  67. if (sender is not ItemsControl itemsControl) return;
  68. var isHorizontal = Orientation == Orientation.Horizontal;
  69. var dragPosition = e.GetPosition(itemsControl);
  70. for (int index = 0; index < itemsControl.ItemCount; index++)
  71. {
  72. var container = itemsControl.ContainerFromIndex(index);
  73. if (container == null) continue;
  74. var containerMidPoint = isHorizontal ? container.Bounds.Center.X : container.Bounds.Center.Y;
  75. var translationX = isHorizontal && dragPosition.X <= containerMidPoint ? container.Bounds.Width : 0;
  76. var translationY = !isHorizontal && dragPosition.Y <= containerMidPoint ? container.Bounds.Height : 0;
  77. ApplyTranslation(container, translationX, translationY);
  78. }
  79. }
  80. }