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

156 lines
5.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 Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Lattice.UI.DragDrop.WinUI.Controls;
/// <summary>
/// Оверлей для отображения визуальных элементов перетаскивания.
/// </summary>
public class DragDropOverlay : Canvas
{
private readonly List<UIElement> _dragVisuals = new();
private readonly List<DropPreviewAdorner> _dropAdorners = new();
/// <summary>
/// Инициализирует новый экземпляр класса <see cref="DragDropOverlay"/>.
/// </summary>
public DragDropOverlay()
{
IsHitTestVisible = false;
Background = null;
// Устанавливаем высокий Z-Index, чтобы быть поверх всего
Canvas.SetZIndex(this, 10000);
}
/// <summary>
/// Показывает визуальное представление перетаскивания.
/// </summary>
/// <param name="dragVisual">Визуальное представление.</param>
/// <param name="initialX">Начальная позиция X.</param>
/// <param name="initialY">Начальная позиция Y.</param>
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;
}
/// <summary>
/// Обновляет позицию визуального представления перетаскивания.
/// </summary>
/// <param name="dragVisual">Визуальное представление.</param>
/// <param name="x">Новая позиция X.</param>
/// <param name="y">Новая позиция Y.</param>
public void UpdateDragVisualPosition(UIElement dragVisual, double x, double y)
{
if (Children.Contains(dragVisual))
{
SetLeft(dragVisual, x);
SetTop(dragVisual, y);
}
}
/// <summary>
/// Скрывает визуальное представление перетаскивания.
/// </summary>
/// <param name="dragVisual">Визуальное представление.</param>
public void HideDragVisual(UIElement dragVisual)
{
dragVisual.Visibility = Visibility.Collapsed;
if (Children.Contains(dragVisual))
{
Children.Remove(dragVisual);
_dragVisuals.Remove(dragVisual);
}
}
/// <summary>
/// Показывает предварительный просмотр области сброса.
/// </summary>
/// <param name="bounds">Границы области.</param>
/// <returns>Созданный элемент предварительного просмотра.</returns>
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;
}
/// <summary>
/// Обновляет предварительный просмотр области сброса.
/// </summary>
/// <param name="adorner">Элемент предварительного просмотра.</param>
/// <param name="bounds">Новые границы.</param>
public void UpdateDropPreview(DropPreviewAdorner adorner, Core.Geometry.Rect bounds)
{
adorner.UpdatePosition(bounds);
}
/// <summary>
/// Скрывает все предварительные просмотры областей сброса.
/// </summary>
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();
}
}
/// <summary>
/// Скрывает все визуальные элементы.
/// </summary>
public void ClearAllVisuals()
{
foreach (var visual in _dragVisuals.ToList())
{
HideDragVisual(visual);
}
HideAllDropPreviews();
}
/// <summary>
/// Получает текущий элемент перетаскивания.
/// </summary>
/// <returns>Элемент перетаскивания или null.</returns>
public UIElement? GetCurrentDragVisual()
{
return _dragVisuals.FirstOrDefault();
}
}