474 lines
21 KiB
C#
474 lines
21 KiB
C#
using Lattice.Core.DragDrop.Factories;
|
||
using Lattice.Core.DragDrop.Services;
|
||
using Lattice.UI.DragDrop.WinUI.Behaviors;
|
||
using Lattice.UI.DragDrop.WinUI.Controls;
|
||
using Lattice.UI.DragDrop.WinUI.Services;
|
||
using Microsoft.UI.Xaml;
|
||
using System;
|
||
|
||
namespace Lattice.UI.DragDrop.WinUI.Factories;
|
||
|
||
/// <summary>
|
||
/// Фабрика для создания компонентов системы перетаскивания WinUI.
|
||
/// Предоставляет методы для быстрой настройки drag-and-drop в приложениях WinUI.
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// Эта фабрика упрощает интеграцию системы перетаскивания в WinUI приложения,
|
||
/// предоставляя готовые методы для наиболее распространенных сценариев использования.
|
||
/// </remarks>
|
||
public static class WinUIDragDropFactory
|
||
{
|
||
#region Основные компоненты
|
||
|
||
/// <summary>
|
||
/// Создает и инициализирует менеджер перетаскивания для WinUI окна.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Окно WinUI, для которого создается менеджер перетаскивания.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Инициализированный экземпляр <see cref="WinUIDragDropManager"/>.
|
||
/// </returns>
|
||
/// <exception cref="ArgumentNullException">
|
||
/// Выбрасывается, когда <paramref name="window"/> равен null.
|
||
/// </exception>
|
||
/// <remarks>
|
||
/// Этот метод создает менеджер перетаскивания и настраивает его для работы с указанным окном.
|
||
/// Менеджер автоматически создает оверлей для визуальных элементов и подписывается на события.
|
||
/// </remarks>
|
||
/// <example>
|
||
/// <code>
|
||
/// public partial class MainWindow : Window
|
||
/// {
|
||
/// private WinUIDragDropManager _dragDropManager;
|
||
///
|
||
/// public MainWindow()
|
||
/// {
|
||
/// InitializeComponent();
|
||
/// _dragDropManager = WinUIDragDropFactory.CreateManager(this);
|
||
/// }
|
||
/// }
|
||
/// </code>
|
||
/// </example>
|
||
public static WinUIDragDropManager CreateManager(Window window)
|
||
{
|
||
if (window == null)
|
||
throw new ArgumentNullException(nameof(window));
|
||
|
||
var manager = WinUIDragDropManager.Instance;
|
||
manager.Initialize(window);
|
||
return manager;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает и инициализирует менеджер перетаскивания с пользовательскими настройками.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Окно WinUI, для которого создается менеджер перетаскивания.
|
||
/// </param>
|
||
/// <param name="configure">
|
||
/// Делегат для настройки менеджера перед инициализацией.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Инициализированный экземпляр <see cref="WinUIDragDropManager"/>.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Этот метод позволяет настроить параметры менеджера (например, смещение визуального элемента)
|
||
/// перед его инициализацией.
|
||
/// </remarks>
|
||
public static WinUIDragDropManager CreateManager(Window window, Action<WinUIDragDropManager> configure)
|
||
{
|
||
if (window == null)
|
||
throw new ArgumentNullException(nameof(window));
|
||
|
||
var manager = WinUIDragDropManager.Instance;
|
||
configure?.Invoke(manager);
|
||
manager.Initialize(window);
|
||
return manager;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает хост для визуальных элементов перетаскивания.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Окно, к которому будет привязан хост.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Экземпляр <see cref="WinUIDragDropHost"/>, готовый к использованию.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Хост управляет отображением визуальных элементов (drag-визуализация, drop-превью)
|
||
/// на оверлейном слое поверх основного содержимого окна.
|
||
/// </remarks>
|
||
public static WinUIDragDropHost CreateHost(Window window)
|
||
{
|
||
if (window == null)
|
||
throw new ArgumentNullException(nameof(window));
|
||
|
||
var host = new WinUIDragDropHost();
|
||
host.Initialize(window);
|
||
return host;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Поведения (Behaviors)
|
||
|
||
/// <summary>
|
||
/// Создает поведение источника перетаскивания для элемента WinUI.
|
||
/// </summary>
|
||
/// <param name="dragDropService">
|
||
/// Сервис перетаскивания, который будет управлять операциями.
|
||
/// </param>
|
||
/// <param name="host">
|
||
/// Хост для отображения визуальных элементов.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Экземпляр <see cref="WinUIDragSourceBehavior"/>, готовый к прикреплению к элементу.
|
||
/// </returns>
|
||
/// <exception cref="ArgumentNullException">
|
||
/// Выбрасывается, если любой из параметров равен null.
|
||
/// </exception>
|
||
/// <remarks>
|
||
/// Созданное поведение необходимо прикрепить к элементу с помощью метода <see cref="WinUIDragSourceBehavior.Attach"/>.
|
||
/// </remarks>
|
||
public static WinUIDragSourceBehavior CreateDragSourceBehavior(
|
||
IDragDropService dragDropService,
|
||
WinUIDragDropHost host)
|
||
{
|
||
if (dragDropService == null)
|
||
throw new ArgumentNullException(nameof(dragDropService));
|
||
if (host == null)
|
||
throw new ArgumentNullException(nameof(host));
|
||
|
||
return new WinUIDragSourceBehavior(dragDropService, host);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает поведение цели сброса для элемента WinUI.
|
||
/// </summary>
|
||
/// <param name="dragDropService">
|
||
/// Сервис перетаскивания, который будет управлять операциями.
|
||
/// </param>
|
||
/// <param name="host">
|
||
/// Хост для отображения визуальных элементов.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Экземпляр <see cref="WinUIDropTargetBehavior"/>, готовый к прикреплению к элементу.
|
||
/// </returns>
|
||
/// <exception cref="ArgumentNullException">
|
||
/// Выбрасывается, если любой из параметров равен null.
|
||
/// </exception>
|
||
/// <remarks>
|
||
/// Созданное поведение необходимо прикрепить к элементу с помощью метода <see cref="WinUIDropTargetBehavior.Attach"/>.
|
||
/// </remarks>
|
||
public static WinUIDropTargetBehavior CreateDropTargetBehavior(
|
||
IDragDropService dragDropService,
|
||
WinUIDragDropHost host)
|
||
{
|
||
if (dragDropService == null)
|
||
throw new ArgumentNullException(nameof(dragDropService));
|
||
if (host == null)
|
||
throw new ArgumentNullException(nameof(host));
|
||
|
||
return new WinUIDropTargetBehavior(dragDropService, host);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Визуальные элементы
|
||
|
||
/// <summary>
|
||
/// Создает визуальный элемент для отображения во время перетаскивания.
|
||
/// </summary>
|
||
/// <param name="dragData">
|
||
/// Данные, которые будут отображены в визуальном элементе.
|
||
/// </param>
|
||
/// <param name="opacity">
|
||
/// Прозрачность элемента (от 0.0 до 1.0).
|
||
/// </param>
|
||
/// <returns>
|
||
/// Экземпляр <see cref="DragAdorner"/>, настроенный для отображения указанных данных.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Созданный элемент можно использовать с методом <see cref="WinUIDragDropHost.ShowDragVisual"/>
|
||
/// для отображения во время операции перетаскивания.
|
||
/// </remarks>
|
||
public static DragAdorner CreateDragAdorner(object dragData, double opacity = 0.8)
|
||
{
|
||
return new DragAdorner
|
||
{
|
||
DragData = dragData,
|
||
Opacity = opacity
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает элемент предварительного просмотра для области сброса.
|
||
/// </summary>
|
||
/// <param name="color">
|
||
/// Цвет подсветки области. Если не указан, используется цвет из ресурсов темы.
|
||
/// </param>
|
||
/// <param name="thickness">
|
||
/// Толщина границы подсветки.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Экземпляр <see cref="DropPreviewAdorner"/>, готовый к отображению.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Этот элемент используется для визуального указания области, на которую можно сбросить данные.
|
||
/// </remarks>
|
||
public static DropPreviewAdorner CreateDropPreviewAdorner(
|
||
Windows.UI.Color? color = null,
|
||
double thickness = 2.0)
|
||
{
|
||
var adorner = new DropPreviewAdorner
|
||
{
|
||
PreviewThickness = thickness
|
||
};
|
||
|
||
if (color.HasValue)
|
||
{
|
||
adorner.PreviewColor = color.Value;
|
||
}
|
||
|
||
return adorner;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Готовые конфигурации для типовых сценариев
|
||
|
||
/// <summary>
|
||
/// Создает полную систему перетаскивания для WinUI приложения.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Главное окно приложения.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Кортеж, содержащий менеджер перетаскивания и сервис перетаскивания.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Этот метод создает все необходимые компоненты для работы перетаскивания в приложении.
|
||
/// Возвращаемый сервис можно использовать для создания дополнительных источников и целей.
|
||
/// </remarks>
|
||
public static (WinUIDragDropManager Manager, IDragDropService Service) CreateCompleteSystem(Window window)
|
||
{
|
||
var service = DragDropFactory.CreateDragDropService();
|
||
var manager = CreateManager(window);
|
||
return (manager, service);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает систему перетаскивания, оптимизированную для списков и коллекций.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Главное окно приложения.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Менеджер перетаскивания, настроенный для переупорядочивания элементов в списках.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Эта конфигурация устанавливает оптимальные параметры для перетаскивания элементов
|
||
/// внутри списков (например, для изменения порядка элементов в ListView или ItemsControl).
|
||
/// </remarks>
|
||
public static WinUIDragDropManager CreateListReorderSystem(Window window)
|
||
{
|
||
var manager = CreateManager(window, m =>
|
||
{
|
||
m.DragVisualOffset = new Core.Geometry.Point(-15, -15);
|
||
});
|
||
|
||
return manager;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает систему перетаскивания для файлов и документов.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Главное окно приложения.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Менеджер перетаскивания, настроенный для работы с файлами.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Эта конфигурация устанавливает увеличенный порог перетаскивания и специальные
|
||
/// визуальные эффекты, характерные для операций с файлами.
|
||
/// </remarks>
|
||
public static WinUIDragDropManager CreateFileDragDropSystem(Window window)
|
||
{
|
||
var manager = CreateManager(window, m =>
|
||
{
|
||
m.DragVisualOffset = new Core.Geometry.Point(-25, -25);
|
||
});
|
||
|
||
return manager;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает систему перетаскивания для графических редакторов и инструментов дизайна.
|
||
/// </summary>
|
||
/// <param name="window">
|
||
/// Главное окно приложения.
|
||
/// </param>
|
||
/// <returns>
|
||
/// Менеджер перетаскивания, настроенный для точного позиционирования.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Эта конфигурация уменьшает порог начала перетаскивания для более точного контроля
|
||
/// и устанавливает минималистичную визуализацию.
|
||
/// </remarks>
|
||
public static WinUIDragDropManager CreateDesignToolSystem(Window window)
|
||
{
|
||
var manager = CreateManager(window, m =>
|
||
{
|
||
m.DragVisualOffset = new Core.Geometry.Point(-10, -10);
|
||
});
|
||
|
||
return manager;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Вспомогательные методы
|
||
|
||
/// <summary>
|
||
/// Настраивает элемент как источник перетаскивания с использованием указанного менеджера.
|
||
/// </summary>
|
||
/// <param name="manager">
|
||
/// Менеджер перетаскивания, который будет управлять операцией.
|
||
/// </param>
|
||
/// <param name="element">
|
||
/// Элемент WinUI, который должен стать источником перетаскивания.
|
||
/// </param>
|
||
/// <param name="dragData">
|
||
/// Данные для перетаскивания. Если не указаны, будут использованы DataContext или Tag элемента.
|
||
/// </param>
|
||
/// <remarks>
|
||
/// Этот метод является оберткой вокруг <see cref="WinUIDragDropManager.MakeDragSource"/>,
|
||
/// предоставляя более удобный API.
|
||
/// </remarks>
|
||
public static void SetupAsDragSource(WinUIDragDropManager manager, Microsoft.UI.Xaml.FrameworkElement element, object dragData = null)
|
||
{
|
||
if (manager == null)
|
||
throw new ArgumentNullException(nameof(manager));
|
||
if (element == null)
|
||
throw new ArgumentNullException(nameof(element));
|
||
|
||
manager.MakeDragSource(element, dragData);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Настраивает элемент как цель сброса с использованием указанного менеджера.
|
||
/// </summary>
|
||
/// <param name="manager">
|
||
/// Менеджер перетаскивания, который будет управлять операцией.
|
||
/// </param>
|
||
/// <param name="element">
|
||
/// Элемент WinUI, который должен стать целью сброса.
|
||
/// </param>
|
||
/// <remarks>
|
||
/// Этот метод является оберткой вокруг <see cref="WinUIDragDropManager.MakeDropTarget"/>,
|
||
/// предоставляя более удобный API.
|
||
/// </remarks>
|
||
public static void SetupAsDropTarget(WinUIDragDropManager manager, Microsoft.UI.Xaml.FrameworkElement element)
|
||
{
|
||
if (manager == null)
|
||
throw new ArgumentNullException(nameof(manager));
|
||
if (element == null)
|
||
throw new ArgumentNullException(nameof(element));
|
||
|
||
manager.MakeDropTarget(element);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Настраивает контейнер для поддержки переупорядочивания дочерних элементов.
|
||
/// </summary>
|
||
/// <param name="manager">
|
||
/// Менеджер перетаскивания.
|
||
/// </param>
|
||
/// <param name="container">
|
||
/// Контейнер (например, StackPanel или Grid), дочерние элементы которого можно переупорядочивать.
|
||
/// </param>
|
||
/// <param name="childSelector">
|
||
/// Функция для получения данных перетаскивания из дочернего элемента.
|
||
/// Если не указана, используются DataContext дочерних элементов.
|
||
/// </param>
|
||
/// <remarks>
|
||
/// Этот метод автоматически настраивает все дочерние элементы контейнера как источники перетаскивания,
|
||
/// а сам контейнер — как цель сброса, создавая функциональность переупорядочивания.
|
||
/// </remarks>
|
||
public static void SetupReorderContainer(
|
||
WinUIDragDropManager manager,
|
||
Microsoft.UI.Xaml.Controls.Panel container,
|
||
Func<Microsoft.UI.Xaml.FrameworkElement, object> childSelector = null)
|
||
{
|
||
if (manager == null)
|
||
throw new ArgumentNullException(nameof(manager));
|
||
if (container == null)
|
||
throw new ArgumentNullException(nameof(container));
|
||
|
||
// Настраиваем контейнер как цель сброса
|
||
manager.MakeDropTarget(container);
|
||
|
||
// Настраиваем все дочерние элементы как источники перетаскивания
|
||
foreach (var child in container.Children)
|
||
{
|
||
if (child is Microsoft.UI.Xaml.FrameworkElement element)
|
||
{
|
||
var data = childSelector?.Invoke(element) ?? element.DataContext ?? element.Tag;
|
||
manager.MakeDragSource(element, data);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Методы для работы с XAML
|
||
|
||
/// <summary>
|
||
/// Настраивает прикрепленные свойства для элемента источника перетаскивания.
|
||
/// </summary>
|
||
/// <param name="element">
|
||
/// Элемент, который должен стать источником перетаскивания.
|
||
/// </param>
|
||
/// <param name="dragData">
|
||
/// Данные для перетаскивания.
|
||
/// </param>
|
||
/// <remarks>
|
||
/// Этот метод устанавливает attached properties, которые активируют поведение перетаскивания
|
||
/// при использовании в XAML. Эквивалентно установке свойств IsDragSource и DragData в XAML.
|
||
/// </remarks>
|
||
public static void SetupDragSourceInXaml(Microsoft.UI.Xaml.FrameworkElement element, object dragData)
|
||
{
|
||
if (element == null)
|
||
throw new ArgumentNullException(nameof(element));
|
||
|
||
// Устанавливаем attached properties
|
||
element.SetValue(Behaviors.WinUIDragSourceBehavior.IsEnabledProperty, true);
|
||
if (dragData != null)
|
||
{
|
||
element.SetValue(Behaviors.WinUIDragSourceBehavior.DragDataProperty, dragData);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Настраивает прикрепленные свойства для элемента цели сброса.
|
||
/// </summary>
|
||
/// <param name="element">
|
||
/// Элемент, который должен стать целью сброса.
|
||
/// </param>
|
||
/// <remarks>
|
||
/// Этот метод устанавливает attached properties, которые активируют поведение цели сброса
|
||
/// при использовании в XAML. Эквивалентно установке свойства IsDropTarget в XAML.
|
||
/// </remarks>
|
||
public static void SetupDropTargetInXaml(Microsoft.UI.Xaml.FrameworkElement element)
|
||
{
|
||
if (element == null)
|
||
throw new ArgumentNullException(nameof(element));
|
||
|
||
element.SetValue(Behaviors.WinUIDropTargetBehavior.IsEnabledProperty, true);
|
||
}
|
||
|
||
#endregion
|
||
} |