Files
Lattice/Lattice.UI.DragDrop.WinUI/Services/WinUIDragDropIntegrationService.cs
2026-01-18 16:33:35 +03:00

132 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}