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

Lattice.UI.DragDrop.WinUI

Lattice Framework WinUI 3 Windows 10+ Version License

Полнофункциональная реализация системы перетаскивания для WinUI 3 в составе Lattice UI Framework.

🎉 Демо

Drag & Drop Demo

Перетаскивание элементов между контейнерами и переупорядочивание списка

📦 Особенности

Готовое решение для WinUI 3 - работает из коробки
Attached Behaviors - легко подключается к любым UIElement
Визуальная обратная связь - анимации и подсветка
Переупорядочивание элементов - drag-and-drop в списках
Кастомизация стилей - полный контроль над внешним видом
Поддержка сложных сценариев - вложенные элементы, зоны сброса
Производительность - оптимизировано для плавной работы

🚀 Быстрый старт

1. Установка

Добавьте пакет через NuGet:

Install-Package Lattice.UI.DragDrop.WinUI

Или через Package Manager:

<PackageReference Include="Lattice.UI.DragDrop.WinUI" Version="1.0.0" />

2. Инициализация в приложении

using Lattice.UI.DragDrop.WinUI.Extensions;
using Lattice.UI.DragDrop.WinUI.Helpers;

public MainWindow()
{
    InitializeComponent();
    
    // Инициализация ресурсов
    ResourceHelper.InitializeDragDropResources();
    
    // Настройка примеров перетаскивания
    SetupDragDropExamples();
}

private void SetupDragDropExamples()
{
    // Пример 1: Перетаскивание текста
    var textBlock = new TextBlock { Text = "Перетащи меня" };
    textBlock.MakeDragSource("Пример данных");
    
    // Пример 2: Цель сброса
    var border = new Border { Background = new SolidColorBrush(Colors.LightGray) };
    border.MakeDropTarget(typeof(string));
    
    // Пример 3: Стилизация
    var button = new Button { Content = "Кнопка" };
    button.ApplyDragStyle();
    button.EnableDragVisualFeedback();
}

🎨 Использование

Базовое перетаскивание

// Создаем перетаскиваемый элемент
var dragSource = new Border
{
    Background = new SolidColorBrush(Colors.LightBlue),
    Child = new TextBlock { Text = "Drag me" }
};

// Делаем элемент перетаскиваемым
dragSource.MakeDragSource(dragSource); // Можно передать любые данные

// Создаем цель сброса
var dropTarget = new Border
{
    Background = new SolidColorBrush(Colors.LightGreen)
};

// Делаем элемент целью сброса
dropTarget.MakeDropTarget(typeof(Border));

Переупорядочивание элементов в списке

// Создаем контейнер с поддержкой переупорядочивания
var reorderContainer = new StackPanel();
reorderContainer.MakeDropTarget(typeof(UIElement));

// Добавляем перетаскиваемые элементы
for (int i = 0; i < 5; i++)
{
    var item = new Border
    {
        Background = new SolidColorBrush(Colors.White),
        BorderBrush = new SolidColorBrush(Colors.Gray),
        BorderThickness = new Thickness(1),
        Margin = new Thickness(0, 0, 0, 5),
        Child = new TextBlock { Text = $"Item {i + 1}" }
    };
    
    item.MakeDragSource(item);
    reorderContainer.Children.Add(item);
}

Кастомизация визуальной обратной связи

// Создаем кастомный стиль
var customStyle = new Style(typeof(Control));
customStyle.Setters.Add(new Setter(Control.BackgroundProperty, 
    new SolidColorBrush(Colors.Yellow)));
customStyle.Setters.Add(new Setter(Control.BorderBrushProperty, 
    new SolidColorBrush(Colors.Red)));

// Применяем стиль к элементу
var element = new Button { Content = "Custom Style" };
element.SetDropFeedbackStyle(customStyle);
element.MakeDragSource("data");

📁 Структура API

Behaviors (Поведения)

Класс Описание
WinUIDragSourceBehavior Прикрепляемое поведение для источников
WinUIDropTargetBehavior Прикрепляемое поведение для целей

Controls (Контролы)

Контрол Назначение
DragAdorner Визуальное представление перетаскивания
DropPreviewAdorner Предпросмотр области сброса
DragDropOverlay Оверлей для визуальных элементов

Services (Сервисы)

Сервис Назначение
WinUIDragVisualProvider Создание визуальных элементов
DragDropConfigurationService Централизованная настройка

Extensions (Расширения)

// Основные методы расширения
element.MakeDragSource(data);           // Сделать перетаскиваемым
element.MakeDropTarget(types);          // Сделать целью сброса
control.ApplyDragStyle();               // Применить стиль перетаскивания
control.SetDragVisualState("Dragging"); // Установить визуальное состояние

🎯 Примеры использования

Пример 1: Файловый менеджер

// Перетаскивание файлов
var fileItem = new ListViewItem { Content = "Document.pdf" };
fileItem.MakeDragSource(new FileData { Path = "C:\\Files\\Document.pdf" });

// Папка - цель сброса
var folderItem = new ListViewItem { Content = "Downloads" };
folderItem.MakeDropTarget(typeof(FileData));
folderItem.SetDropHandler(new FileDropHandler());

Пример 2: Конструктор UI

// Панель инструментов
var toolbox = new StackPanel();
toolbox.MakeChildrenDraggable(element => new ControlTemplate 
{ 
    Type = element.GetType(), 
    Name = element.Name 
});

// Область дизайна
var designArea = new Canvas();
designArea.MakeDropTarget(typeof(ControlTemplate));

// Обработчик сброса
designArea.Drop += (sender, e) =>
{
    var template = e.DataView.GetData<ControlTemplate>();
    var control = Activator.CreateInstance(template.Type);
    Canvas.SetLeft(control, e.GetPosition(designArea).X);
    Canvas.SetTop(control, e.GetPosition(designArea).Y);
    designArea.Children.Add(control);
};

Пример 3: Календарь с событиями

// Событие календаря
var calendarEvent = new Border
{
    Background = new SolidColorBrush(Colors.CornflowerBlue),
    Child = new TextBlock { Text = "Meeting at 10:00" }
};

calendarEvent.MakeDragSource(new CalendarEvent 
{ 
    Id = 1, 
    Title = "Meeting",
    StartTime = DateTime.Now 
});

// Ячейка календаря
var timeSlot = new Border
{
    Background = new SolidColorBrush(Colors.White),
    BorderBrush = new SolidColorBrush(Colors.LightGray)
};

timeSlot.MakeDropTarget(typeof(CalendarEvent));

🎨 Темы и стилизация

Встроенные стили

Проект включает готовые стили в папке Themes/:

  • DragAdorner.xaml - стиль для визуального элемента перетаскивания
  • DropPreviewAdorner.xaml - стиль для предпросмотра сброса
  • DragDropStyles.xaml - общие стили для элементов

Кастомизация через ресурсы

<!-- App.xaml или Generic.xaml -->
<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ms-appx:///Lattice.UI.DragDrop.WinUI/Themes/Generic.xaml" />
    </ResourceDictionary.MergedDictionaries>
    
    <!-- Переопределение стилей -->
    <Style x:Key="CustomDragAdornerStyle" TargetType="dragDrop:DragAdorner">
        <Setter Property="Background" Value="Red" />
        <Setter Property="Opacity" Value="0.9" />
    </Style>
</ResourceDictionary>

Визуальные состояния

Элементы поддерживают следующие визуальные состояния:

  • Normal - обычное состояние
  • Dragging - элемент перетаскивается
  • DragOver - над элементом перетаскивают объект
// Переключение состояний
control.SetDragVisualState("Dragging", true); // С анимацией
control.SetDragVisualState("Normal", false);  // Без анимации

🔧 Интеграция с Docking System

Система идеально интегрируется с Lattice Docking:

using Lattice.UI.DragDrop.WinUI.Extensions;
using Lattice.UI.Docking.WinUI;

public class DockPane : ContentControl
{
    public DockPane()
    {
        // Делаем панель перетаскиваемой
        this.MakeDragSource(new DockPaneDragData
        {
            Pane = this,
            ContentType = Content?.GetType(),
            Title = Title
        });
        
        // Устанавливаем визуальную обратную связь
        this.ApplyDragStyle();
        this.EnableDragVisualFeedback();
    }
}

public class DockArea : ContentControl
{
    public DockArea()
    {
        // Область докинга принимает панели
        this.MakeDropTarget(typeof(DockPaneDragData));
        
        // Кастомный обработчик
        this.SetDropHandler(new DockDropHandler());
    }
}

📊 Производительность

Оптимизации

  1. Минимальные перерисовки - обновление только при необходимости
  2. Кэширование визуальных элементов - повторное использование
  3. Эффективные алгоритмы поиска - быстрый поиск целей сброса
  4. Асинхронная обработка - не блокирует UI поток

Рекомендации

// ✅ Правильно
element.MakeDragSource(data);

// ❌ Избегать
element.PointerPressed += (s, e) => { /* сложная логика */ };
element.PointerMoved += (s, e) => { /* частые обновления */ };

🧪 Тестирование

Модульные тесты

[TestClass]
public class DragDropTests
{
    [TestMethod]
    public void MakeDragSource_EnablesDragging()
    {
        var element = new Border();
        element.MakeDragSource("test");
        
        Assert.IsTrue(element.IsDragSource());
    }
    
    [TestMethod]
    public void MakeDropTarget_AcceptsCorrectTypes()
    {
        var element = new Border();
        element.MakeDropTarget(typeof(string), typeof(int));
        
        Assert.IsTrue(element.IsDropTarget());
    }
}

UI тесты

[TestClass]
public class DragDropUITests
{
    [UITestMethod]
    public async Task DragAndDrop_BetweenElements()
    {
        await UITestHelper.Run(async window =>
        {
            var source = new Border { Background = new SolidColorBrush(Colors.Blue) };
            var target = new Border { Background = new SolidColorBrush(Colors.Green) };
            
            source.MakeDragSource("data");
            target.MakeDropTarget(typeof(string));
            
            // Симуляция перетаскивания
            await SimulateDrag(source, target);
            
            // Проверка результатов
            Assert.IsTrue(dropOccurred);
        });
    }
}

🔍 Отладка

Включение логов

// Включение подробного логирования
#if DEBUG
DragDropDebugger.EnableLogging = true;
DragDropDebugger.LogLevel = LogLevel.Verbose;
#endif

Визуальные подсказки

// Показать границы целей сброса
DebugDropTargets.ShowBounds = true;

// Показать траекторию перетаскивания
DebugDragTrail.Enabled = true;
DebugDragTrail.Color = Colors.Red;

📈 Производительность в production

Мониторинг

// Сбор метрик
var metrics = DragDropPerformanceCollector.Collect();
Console.WriteLine($"Drag operations: {metrics.DragCount}");
Console.WriteLine($"Average drag time: {metrics.AverageDragTimeMs}ms");
Console.WriteLine($"Drop success rate: {metrics.DropSuccessRate:P}");

Оптимизация для больших списков

// Виртуализация для списков
var virtualizingList = new ListView
{
    ItemsSource = largeCollection,
    VirtualizingStackPanel.VirtualizationMode = VirtualizationMode.Recycling
};

// Оптимизация перетаскивания
virtualizingList.MakeDropTarget(typeof(DataItem));
virtualizingList.SetDragDropOptimization(true);

🤝 Интеграция с другими компонентами Lattice

Toolbox

toolboxItem.MakeDragSource(new ToolboxItem 
{ 
    Type = typeof(Button), 
    Icon = "🔘" 
});

Property Grid

propertyItem.MakeDragSource(new PropertyValue 
{ 
    Name = "Background", 
    Value = Colors.Blue 
});

Layout System

layoutPanel.MakeDropTarget(typeof(UIElement));
layoutPanel.SetDropPositionHandler((element, position) =>
{
    return CalculateDropZone(position);
});

📚 Дополнительные ресурсы

Документация

Видео туториалы

Сообщество

🐛 Отчет об ошибках

Нашли ошибку? Создайте issue с подробным описанием:

  1. Шаги для воспроизведения
  2. Ожидаемое поведение
  3. Фактическое поведение
  4. Скриншоты или видео
  5. Версии: Windows, WinUI, Lattice

🚀 Roadmap

Версия 1.1 (Q2 2024)

  • Поддержка touch-жестов
  • Анимации с физикой
  • Расширенная визуализация

Версия 1.2 (Q3 2024)

  • Интеграция с Windows Shell
  • Поддержка виртуальных данных
  • Улучшенная доступность

Версия 2.0 (Q4 2024)

  • Кроссплатформенная поддержка (Uno Platform)
  • WebAssembly поддержка
  • Расширенный набор контролов

📄 Лицензия

MIT License. Подробности в файле LICENSE.

👥 Авторы

🙏 Благодарности

Спасибо сообществу WinUI и всем контрибьюторам, которые помогают улучшать проект!


Lattice.UI.DragDrop.WinUI - часть Lattice UI Framework

GitHubДокументацияDiscordTwitter