Files
Lattice/Lattice.UI.DragDrop.WinUI/Factories/WinUIDragDropFactory.cs

474 lines
21 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.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
}