DragAndDrop core
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using Lattice.Core.DragDrop.Services;
|
||||
using Lattice.UI.DragDrop.Abstractions;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
|
||||
namespace Lattice.UI.DragDrop.WinUI.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис интеграции Drag & Drop с WinUI приложением.
|
||||
/// </summary>
|
||||
public class WinUIDragDropIntegrationService : IDisposable
|
||||
{
|
||||
private readonly IDragDropService _dragDropService;
|
||||
private readonly IDragVisualProvider _dragVisualProvider;
|
||||
private readonly Canvas _overlayCanvas;
|
||||
private readonly Window _window;
|
||||
private object? _currentDragVisual;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр класса <see cref="WinUIDragDropIntegrationService"/>.
|
||||
/// </summary>
|
||||
public WinUIDragDropIntegrationService(
|
||||
Window window,
|
||||
IDragDropService dragDropService,
|
||||
IDragVisualProvider dragVisualProvider)
|
||||
{
|
||||
_window = window ?? throw new ArgumentNullException(nameof(window));
|
||||
_dragDropService = dragDropService ?? throw new ArgumentNullException(nameof(dragDropService));
|
||||
_dragVisualProvider = dragVisualProvider ?? throw new ArgumentNullException(nameof(dragVisualProvider));
|
||||
|
||||
// Создаем оверлейный Canvas для визуальных элементов
|
||||
_overlayCanvas = new Canvas
|
||||
{
|
||||
IsHitTestVisible = false,
|
||||
Background = null
|
||||
};
|
||||
|
||||
// Подписываемся на события перетаскивания
|
||||
SubscribeToEvents();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Встраивает оверлей в указанный контейнер.
|
||||
/// </summary>
|
||||
public void AttachToContainer(Panel container)
|
||||
{
|
||||
if (container == null)
|
||||
throw new ArgumentNullException(nameof(container));
|
||||
|
||||
// Убеждаемся, что оверлей находится поверх всех элементов
|
||||
Canvas.SetZIndex(_overlayCanvas, int.MaxValue);
|
||||
container.Children.Add(_overlayCanvas);
|
||||
}
|
||||
|
||||
private void SubscribeToEvents()
|
||||
{
|
||||
_dragDropService.DragStarted += OnDragStarted;
|
||||
_dragDropService.DragUpdated += OnDragUpdated;
|
||||
_dragDropService.DragCompleted += OnDragCompleted;
|
||||
_dragDropService.DragCancelled += OnDragCancelled;
|
||||
}
|
||||
|
||||
private void UnsubscribeFromEvents()
|
||||
{
|
||||
_dragDropService.DragStarted -= OnDragStarted;
|
||||
_dragDropService.DragUpdated -= OnDragUpdated;
|
||||
_dragDropService.DragCompleted -= OnDragCompleted;
|
||||
_dragDropService.DragCancelled -= OnDragCancelled;
|
||||
}
|
||||
|
||||
private void OnDragStarted(object? sender, DragStartedEventArgs e)
|
||||
{
|
||||
// Создаем визуальное представление
|
||||
_currentDragVisual = _dragVisualProvider.CreateDragVisual(
|
||||
e.DragInfo,
|
||||
e.StartPosition);
|
||||
|
||||
// Добавляем на оверлей
|
||||
if (_currentDragVisual is UIElement element)
|
||||
{
|
||||
_overlayCanvas.Children.Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragUpdated(object? sender, DragUpdatedEventArgs e)
|
||||
{
|
||||
if (_currentDragVisual != null)
|
||||
{
|
||||
_dragVisualProvider.UpdateDragVisualPosition(_currentDragVisual, e.Position);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragCompleted(object? sender, DragCompletedEventArgs e)
|
||||
{
|
||||
CleanupDragVisual();
|
||||
}
|
||||
|
||||
private void OnDragCancelled(object? sender, DragCancelledEventArgs e)
|
||||
{
|
||||
CleanupDragVisual();
|
||||
}
|
||||
|
||||
private void CleanupDragVisual()
|
||||
{
|
||||
if (_currentDragVisual != null)
|
||||
{
|
||||
_dragVisualProvider.ReleaseDragVisual(_currentDragVisual);
|
||||
_currentDragVisual = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
UnsubscribeFromEvents();
|
||||
CleanupDragVisual();
|
||||
|
||||
if (_overlayCanvas.Parent is Panel parent)
|
||||
{
|
||||
parent.Children.Remove(_overlayCanvas);
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user