DragAndDrop core
This commit is contained in:
547
Lattice.UI.DragDrop.WinUI/README.md
Normal file
547
Lattice.UI.DragDrop.WinUI/README.md
Normal file
@@ -0,0 +1,547 @@
|
||||
# Lattice.UI.DragDrop.WinUI
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

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

|
||||
|
||||
*Перетаскивание элементов между контейнерами и переупорядочивание списка*
|
||||
|
||||
## 📦 Особенности
|
||||
|
||||
✅ **Готовое решение для WinUI 3** - работает из коробки
|
||||
✅ **Attached Behaviors** - легко подключается к любым UIElement
|
||||
✅ **Визуальная обратная связь** - анимации и подсветка
|
||||
✅ **Переупорядочивание элементов** - drag-and-drop в списках
|
||||
✅ **Кастомизация стилей** - полный контроль над внешним видом
|
||||
✅ **Поддержка сложных сценариев** - вложенные элементы, зоны сброса
|
||||
✅ **Производительность** - оптимизировано для плавной работы
|
||||
|
||||
## 🚀 Быстрый старт
|
||||
|
||||
### 1. Установка
|
||||
|
||||
Добавьте пакет через NuGet:
|
||||
|
||||
```powershell
|
||||
Install-Package Lattice.UI.DragDrop.WinUI
|
||||
```
|
||||
|
||||
Или через Package Manager:
|
||||
|
||||
```xml
|
||||
<PackageReference Include="Lattice.UI.DragDrop.WinUI" Version="1.0.0" />
|
||||
```
|
||||
|
||||
### 2. Инициализация в приложении
|
||||
|
||||
```csharp
|
||||
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();
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 Использование
|
||||
|
||||
### Базовое перетаскивание
|
||||
|
||||
```csharp
|
||||
// Создаем перетаскиваемый элемент
|
||||
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));
|
||||
```
|
||||
|
||||
### Переупорядочивание элементов в списке
|
||||
|
||||
```csharp
|
||||
// Создаем контейнер с поддержкой переупорядочивания
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
### Кастомизация визуальной обратной связи
|
||||
|
||||
```csharp
|
||||
// Создаем кастомный стиль
|
||||
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 (Расширения)
|
||||
|
||||
```csharp
|
||||
// Основные методы расширения
|
||||
element.MakeDragSource(data); // Сделать перетаскиваемым
|
||||
element.MakeDropTarget(types); // Сделать целью сброса
|
||||
control.ApplyDragStyle(); // Применить стиль перетаскивания
|
||||
control.SetDragVisualState("Dragging"); // Установить визуальное состояние
|
||||
```
|
||||
|
||||
## 🎯 Примеры использования
|
||||
|
||||
### Пример 1: Файловый менеджер
|
||||
|
||||
```csharp
|
||||
// Перетаскивание файлов
|
||||
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
|
||||
|
||||
```csharp
|
||||
// Панель инструментов
|
||||
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: Календарь с событиями
|
||||
|
||||
```csharp
|
||||
// Событие календаря
|
||||
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` - общие стили для элементов
|
||||
|
||||
### Кастомизация через ресурсы
|
||||
|
||||
```xml
|
||||
<!-- 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` - над элементом перетаскивают объект
|
||||
|
||||
```csharp
|
||||
// Переключение состояний
|
||||
control.SetDragVisualState("Dragging", true); // С анимацией
|
||||
control.SetDragVisualState("Normal", false); // Без анимации
|
||||
```
|
||||
|
||||
## 🔧 Интеграция с Docking System
|
||||
|
||||
Система идеально интегрируется с Lattice Docking:
|
||||
|
||||
```csharp
|
||||
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 поток
|
||||
|
||||
### Рекомендации
|
||||
|
||||
```csharp
|
||||
// ✅ Правильно
|
||||
element.MakeDragSource(data);
|
||||
|
||||
// ❌ Избегать
|
||||
element.PointerPressed += (s, e) => { /* сложная логика */ };
|
||||
element.PointerMoved += (s, e) => { /* частые обновления */ };
|
||||
```
|
||||
|
||||
## 🧪 Тестирование
|
||||
|
||||
### Модульные тесты
|
||||
|
||||
```csharp
|
||||
[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 тесты
|
||||
|
||||
```csharp
|
||||
[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);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 Отладка
|
||||
|
||||
### Включение логов
|
||||
|
||||
```csharp
|
||||
// Включение подробного логирования
|
||||
#if DEBUG
|
||||
DragDropDebugger.EnableLogging = true;
|
||||
DragDropDebugger.LogLevel = LogLevel.Verbose;
|
||||
#endif
|
||||
```
|
||||
|
||||
### Визуальные подсказки
|
||||
|
||||
```csharp
|
||||
// Показать границы целей сброса
|
||||
DebugDropTargets.ShowBounds = true;
|
||||
|
||||
// Показать траекторию перетаскивания
|
||||
DebugDragTrail.Enabled = true;
|
||||
DebugDragTrail.Color = Colors.Red;
|
||||
```
|
||||
|
||||
## 📈 Производительность в production
|
||||
|
||||
### Мониторинг
|
||||
|
||||
```csharp
|
||||
// Сбор метрик
|
||||
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}");
|
||||
```
|
||||
|
||||
### Оптимизация для больших списков
|
||||
|
||||
```csharp
|
||||
// Виртуализация для списков
|
||||
var virtualizingList = new ListView
|
||||
{
|
||||
ItemsSource = largeCollection,
|
||||
VirtualizingStackPanel.VirtualizationMode = VirtualizationMode.Recycling
|
||||
};
|
||||
|
||||
// Оптимизация перетаскивания
|
||||
virtualizingList.MakeDropTarget(typeof(DataItem));
|
||||
virtualizingList.SetDragDropOptimization(true);
|
||||
```
|
||||
|
||||
## 🤝 Интеграция с другими компонентами Lattice
|
||||
|
||||
### Toolbox
|
||||
```csharp
|
||||
toolboxItem.MakeDragSource(new ToolboxItem
|
||||
{
|
||||
Type = typeof(Button),
|
||||
Icon = "🔘"
|
||||
});
|
||||
```
|
||||
|
||||
### Property Grid
|
||||
```csharp
|
||||
propertyItem.MakeDragSource(new PropertyValue
|
||||
{
|
||||
Name = "Background",
|
||||
Value = Colors.Blue
|
||||
});
|
||||
```
|
||||
|
||||
### Layout System
|
||||
```csharp
|
||||
layoutPanel.MakeDropTarget(typeof(UIElement));
|
||||
layoutPanel.SetDropPositionHandler((element, position) =>
|
||||
{
|
||||
return CalculateDropZone(position);
|
||||
});
|
||||
```
|
||||
|
||||
## 📚 Дополнительные ресурсы
|
||||
|
||||
### Документация
|
||||
- [Полная документация API](https://lattice-framework.github.io/ui-dragdrop/api/)
|
||||
- [Примеры использования](https://lattice-framework.github.io/ui-dragdrop/examples/)
|
||||
- [Руководство по стилизации](https://lattice-framework.github.io/ui-dragdrop/styling/)
|
||||
|
||||
### Видео туториалы
|
||||
- [Быстрый старт](https://youtube.com/playlist?list=...) - 15 минут
|
||||
- [Продвинутые техники](https://youtube.com/playlist?list=...) - 45 минут
|
||||
- [Интеграция с Docking](https://youtube.com/playlist?list=...) - 30 минут
|
||||
|
||||
### Сообщество
|
||||
- [GitHub Discussions](https://github.com/lattice-framework/ui-dragdrop/discussions) - вопросы и обсуждения
|
||||
- [Discord](https://discord.gg/lattice) - живое общение
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/lattice-ui-dragdrop) - технические вопросы
|
||||
|
||||
## 🐛 Отчет об ошибках
|
||||
|
||||
Нашли ошибку? [Создайте issue](https://github.com/lattice-framework/ui-dragdrop/issues) с подробным описанием:
|
||||
|
||||
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](LICENSE).
|
||||
|
||||
## 👥 Авторы
|
||||
|
||||
- **Команда Lattice Framework** - [@lattice-framework](https://github.com/lattice-framework)
|
||||
- **Главный разработчик** - [Ваше имя](https://github.com/yourusername)
|
||||
|
||||
## 🙏 Благодарности
|
||||
|
||||
Спасибо сообществу WinUI и всем контрибьюторам, которые помогают улучшать проект!
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<p>
|
||||
<strong>Lattice.UI.DragDrop.WinUI</strong> - часть <a href="https://github.com/lattice-framework">Lattice UI Framework</a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://github.com/lattice-framework/ui-dragdrop">GitHub</a> •
|
||||
<a href="https://lattice-framework.github.io">Документация</a> •
|
||||
<a href="https://discord.gg/lattice">Discord</a> •
|
||||
<a href="https://twitter.com/latticefw">Twitter</a>
|
||||
</p>
|
||||
</div>
|
||||
Reference in New Issue
Block a user