Доработара WinUI реализация.
This commit is contained in:
@@ -7,14 +7,53 @@ using System;
|
||||
|
||||
namespace Lattice.UI.DragDrop.WinUI.Services;
|
||||
|
||||
public class WinUIDragDropHost : IDragDropHost
|
||||
/// <summary>
|
||||
/// Хост для управления визуальными элементами перетаскивания в окне WinUI.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Этот класс отвечает за отображение и управление визуальными элементами
|
||||
/// во время операций перетаскивания, включая:
|
||||
/// - Drag-визуализацию (элемент, следующий за курсором)
|
||||
/// - Drop-превью (подсветка областей сброса)
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Хост создает оверлейный слой поверх всего содержимого окна для корректного
|
||||
/// отображения визуальных элементов поверх других UI-компонентов.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class WinUIDragDropHost : IDragDropHost, IDisposable
|
||||
{
|
||||
private readonly DragDropOverlay _overlay;
|
||||
private readonly Window _window;
|
||||
private DragDropOverlay? _overlay;
|
||||
private Window? _window;
|
||||
private bool _disposed;
|
||||
|
||||
public WinUIDragDropHost(Window window)
|
||||
/// <summary>
|
||||
/// Инициализирует хост для работы с указанным окном.
|
||||
/// </summary>
|
||||
/// <param name="window">Окно, в котором будет работать перетаскивание.</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// Выбрасывается, если <paramref name="window"/> равен null.
|
||||
/// </exception>
|
||||
/// <exception cref="ObjectDisposedException">
|
||||
/// Выбрасывается, если хост уже был удален.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Этот метод создает оверлейный слой и добавляет его в визуальное дерево окна.
|
||||
/// Если содержимое окна не является <see cref="Panel"/>, создается контейнер <see cref="Grid"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Метод должен быть вызван один раз перед использованием других методов хоста.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public void Initialize(Window window)
|
||||
{
|
||||
if (_disposed) throw new ObjectDisposedException(nameof(WinUIDragDropHost));
|
||||
|
||||
_window = window ?? throw new ArgumentNullException(nameof(window));
|
||||
|
||||
// Создаем оверлей
|
||||
_overlay = new DragDropOverlay();
|
||||
|
||||
// Добавляем оверлей в окно
|
||||
@@ -22,33 +61,58 @@ public class WinUIDragDropHost : IDragDropHost
|
||||
{
|
||||
panel.Children.Add(_overlay);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Если контент не Panel, создаем Grid
|
||||
var grid = new Grid();
|
||||
grid.Children.Add(_window.Content as UIElement ?? new Grid());
|
||||
grid.Children.Add(_overlay);
|
||||
_window.Content = grid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Отображает визуальное представление перетаскиваемого элемента.
|
||||
/// </summary>
|
||||
/// <param name="dragVisual">Визуальный элемент для отображения.</param>
|
||||
/// <param name="position">Позиция отображения в координатах экрана.</param>
|
||||
/// <remarks>
|
||||
/// Визуальный элемент будет отображен на оверлейном слое в указанной позиции
|
||||
/// и будет следовать за курсором при обновлении через <see cref="UpdateDragVisualPosition"/>.
|
||||
/// </remarks>
|
||||
public void ShowDragVisual(object dragVisual, Point position)
|
||||
{
|
||||
if (_overlay == null || _disposed) return;
|
||||
|
||||
if (dragVisual is UIElement element)
|
||||
{
|
||||
_overlay.ShowDragVisual(element, position.X, position.Y);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void UpdateDragVisualPosition(object dragVisual, Point position)
|
||||
{
|
||||
if (_overlay == null || _disposed) return;
|
||||
|
||||
if (dragVisual is UIElement element)
|
||||
{
|
||||
_overlay.UpdateDragVisualPosition(element, position.X, position.Y);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void HideDragVisual(object dragVisual)
|
||||
{
|
||||
if (_overlay == null || _disposed) return;
|
||||
|
||||
if (dragVisual is UIElement element)
|
||||
{
|
||||
_overlay.HideDragVisual(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Скрываем все, если передан null
|
||||
// Скрываем все визуальные элементы
|
||||
var current = _overlay.GetCurrentDragVisual();
|
||||
if (current != null)
|
||||
{
|
||||
@@ -57,16 +121,40 @@ public class WinUIDragDropHost : IDragDropHost
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ShowDropAdorner(IDropVisualAdorner adorner)
|
||||
{
|
||||
if (_overlay == null || _disposed) return;
|
||||
|
||||
if (adorner is DropPreviewAdorner dropAdorner)
|
||||
{
|
||||
// TODO: Показываем превью сброса
|
||||
// Для WinUI пока просто игнорируем
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void HideDropAdorner(IDropVisualAdorner adorner)
|
||||
{
|
||||
if (_overlay == null || _disposed) return;
|
||||
|
||||
_overlay.HideAllDropPreviews();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
if (_overlay != null && _window?.Content is Panel panel)
|
||||
{
|
||||
panel.Children.Remove(_overlay);
|
||||
_overlay.ClearAllVisuals();
|
||||
}
|
||||
|
||||
_overlay = null;
|
||||
_window = null;
|
||||
_disposed = true;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user