using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using System; using System.Collections.Generic; using System.Linq; namespace Lattice.UI.DragDrop.WinUI.Controls; /// /// Оверлей для отображения визуальных элементов перетаскивания. /// public class DragDropOverlay : Canvas { private readonly List _dragVisuals = new(); private readonly List _dropAdorners = new(); /// /// Инициализирует новый экземпляр класса . /// public DragDropOverlay() { IsHitTestVisible = false; Background = null; // Устанавливаем высокий Z-Index, чтобы быть поверх всего Canvas.SetZIndex(this, 10000); } /// /// Показывает визуальное представление перетаскивания. /// /// Визуальное представление. /// Начальная позиция X. /// Начальная позиция Y. public void ShowDragVisual(UIElement dragVisual, double initialX, double initialY) { if (!Children.Contains(dragVisual)) { Children.Add(dragVisual); _dragVisuals.Add(dragVisual); } SetLeft(dragVisual, initialX); SetTop(dragVisual, initialY); dragVisual.Visibility = Visibility.Visible; } /// /// Обновляет позицию визуального представления перетаскивания. /// /// Визуальное представление. /// Новая позиция X. /// Новая позиция Y. public void UpdateDragVisualPosition(UIElement dragVisual, double x, double y) { if (Children.Contains(dragVisual)) { SetLeft(dragVisual, x); SetTop(dragVisual, y); } } /// /// Скрывает визуальное представление перетаскивания. /// /// Визуальное представление. public void HideDragVisual(UIElement dragVisual) { dragVisual.Visibility = Visibility.Collapsed; if (Children.Contains(dragVisual)) { Children.Remove(dragVisual); _dragVisuals.Remove(dragVisual); } } /// /// Показывает предварительный просмотр области сброса. /// /// Границы области. /// Созданный элемент предварительного просмотра. public DropPreviewAdorner ShowDropPreview(Core.Geometry.Rect bounds) { var adorner = new DropPreviewAdorner { PreviewColor = Windows.UI.Color.FromArgb(100, 0, 120, 215), PreviewThickness = 2.0 }; Children.Add(adorner); _dropAdorners.Add(adorner); adorner.Show(bounds); return adorner; } /// /// Обновляет предварительный просмотр области сброса. /// /// Элемент предварительного просмотра. /// Новые границы. public void UpdateDropPreview(DropPreviewAdorner adorner, Core.Geometry.Rect bounds) { adorner.UpdatePosition(bounds); } /// /// Скрывает все предварительные просмотры областей сброса. /// public void HideAllDropPreviews() { foreach (var adorner in _dropAdorners.ToList()) { adorner.Hide(); var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) }; timer.Tick += (s, e) => { timer.Stop(); if (Children.Contains(adorner)) { Children.Remove(adorner); } _dropAdorners.Remove(adorner); }; timer.Start(); } } /// /// Скрывает все визуальные элементы. /// public void ClearAllVisuals() { foreach (var visual in _dragVisuals.ToList()) { HideDragVisual(visual); } HideAllDropPreviews(); } /// /// Получает текущий элемент перетаскивания. /// /// Элемент перетаскивания или null. public UIElement? GetCurrentDragVisual() { return _dragVisuals.FirstOrDefault(); } }