Доработан Docking
This commit is contained in:
@@ -21,7 +21,7 @@ public partial class App : Application
|
||||
themeManager.RegisterTheme(new FluentThemePack(true)); // Dark тема
|
||||
|
||||
// Применяем тему по умолчанию
|
||||
themeManager.ApplyTheme("Fluent");
|
||||
themeManager.ApplyTheme("Fluent Dark");
|
||||
|
||||
// Создаем главное окно
|
||||
_window = new MainWindow();
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
using Lattice.Core.DragDrop.Abstractions;
|
||||
using Lattice.Core.DragDrop.Models;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lattice.Example.DragDrop;
|
||||
|
||||
public class CustomDropHandler : IDropTarget
|
||||
{
|
||||
private readonly Action<object> _onDrop;
|
||||
|
||||
public CustomDropHandler(Action<object> onDrop)
|
||||
{
|
||||
_onDrop = onDrop;
|
||||
}
|
||||
|
||||
public async Task<bool> CanAcceptDropAsync(DropInfo dropInfo, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Принимаем только объекты типа DragDropItem
|
||||
return dropInfo.Data is DragDropItem;
|
||||
}
|
||||
|
||||
public async Task OnDragOverAsync(DropInfo dropInfo, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (dropInfo.Data is DragDropItem)
|
||||
{
|
||||
dropInfo.SuggestedEffects = Core.DragDrop.Enums.DragDropEffects.Copy;
|
||||
dropInfo.ShowVisualFeedback = true;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task OnDropAsync(DropInfo dropInfo, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (dropInfo.Data is DragDropItem item)
|
||||
{
|
||||
_onDrop(item);
|
||||
dropInfo.MarkAsHandled();
|
||||
}
|
||||
}
|
||||
|
||||
public Task OnDragLeaveAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||
@@ -41,11 +41,8 @@
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.260101001" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Lattice.Core.DragDrop\Lattice.Core.DragDrop.csproj" />
|
||||
<ProjectReference Include="..\Lattice.Themes.Core\Lattice.Themes.Core.csproj" />
|
||||
<ProjectReference Include="..\Lattice.Themes.Fluent\Lattice.Themes.Fluent.csproj" />
|
||||
<ProjectReference Include="..\Lattice.UI.DragDrop.WinUI\Lattice.UI.DragDrop.WinUI.csproj" />
|
||||
<ProjectReference Include="..\Lattice.UI.DragDrop\Lattice.UI.DragDrop.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -2,269 +2,140 @@
|
||||
x:Class="Lattice.Example.DragDrop.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Lattice.Example.DragDrop"
|
||||
xmlns:lattice="using:Lattice.UI.DragDrop.WinUI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
Title="Lattice Drag Drop Example">
|
||||
Title="Drag Drop Demo"
|
||||
>
|
||||
|
||||
<Grid>
|
||||
<Grid Background="#F0F2F5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Header -->
|
||||
<Border Grid.Row="0"
|
||||
Background="{ThemeResource Lattice.Brush.Accent}"
|
||||
Padding="12">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Инструкция -->
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="Просто перетащите элементы справа влево!"
|
||||
FontSize="14" Margin="20" HorizontalAlignment="Center"
|
||||
FontWeight="SemiBold"/>
|
||||
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="12">
|
||||
<FontIcon Glyph=""
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.OnAccent}"/>
|
||||
<TextBlock Text="Lattice Drag Drop Example"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Title}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.OnAccent}"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="12">
|
||||
<ToggleSwitch Header="Dark Mode"
|
||||
OffContent="Light"
|
||||
OnContent="Dark"
|
||||
Toggled="OnThemeToggleToggled"/>
|
||||
<Button Content="Stats"
|
||||
Click="OnStatsButtonClick"
|
||||
Style="{StaticResource AccentButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Main Content -->
|
||||
<Grid Grid.Row="1" Margin="24">
|
||||
<!-- Основное содержимое -->
|
||||
<Grid Grid.Row="1" Margin="20">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="4"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Left Panel - Sources -->
|
||||
<Border Grid.Column="0"
|
||||
Background="{ThemeResource Lattice.Brush.Background.Primary}"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Panel.Border}"
|
||||
BorderThickness="{ThemeResource Lattice.BorderThickness.Panel}"
|
||||
CornerRadius="{ThemeResource Lattice.CornerRadius.Panel}"
|
||||
Padding="{ThemeResource Lattice.Spacing.Panel}">
|
||||
<!-- ЦЕЛЕВАЯ ЗОНА (куда бросаем) -->
|
||||
<Border Grid.Column="0"
|
||||
Background="White"
|
||||
CornerRadius="10"
|
||||
BorderThickness="2"
|
||||
BorderBrush="#4CAF50"
|
||||
Padding="20"
|
||||
Margin="0,0,10,0"
|
||||
lattice:DragDropProperties.IsDropTarget="True">
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="Drag Sources"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Title}"
|
||||
FontWeight="{ThemeResource Lattice.FontWeight.Semibold}"
|
||||
Margin="0,0,0,12"/>
|
||||
<TextBlock Text="Drag items from here to the right panel"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Body}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"
|
||||
<TextBlock Text="🟢 ЦЕЛЕВАЯ ЗОНА"
|
||||
FontSize="16" FontWeight="Bold"
|
||||
Foreground="#4CAF50"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<TextBlock x:Name="DropInfoText"
|
||||
Text="Бросьте сюда элементы"
|
||||
FontSize="14"
|
||||
Foreground="#666"
|
||||
TextWrapping="Wrap"
|
||||
Margin="0,0,0,16"/>
|
||||
|
||||
<!-- Items that can be dragged -->
|
||||
<ItemsControl x:Name="SourceItemsControl">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Padding="12"
|
||||
Margin="0,0,0,8"
|
||||
Background="{ThemeResource Lattice.Brush.Background.Secondary}"
|
||||
CornerRadius="{ThemeResource Lattice.CornerRadius.Small}"
|
||||
BorderThickness="{ThemeResource Lattice.BorderThickness.Thin}"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Border.Primary}"
|
||||
lattice:DragDropProperties.IsDragSource="True"
|
||||
lattice:DragDropProperties.DragData="{Binding}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph=""
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Margin="0,0,12,0"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"/>
|
||||
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding Name}"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Body}"
|
||||
FontWeight="{ThemeResource Lattice.FontWeight.Medium}"/>
|
||||
<TextBlock Text="{Binding Description}"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Caption}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<!-- Custom drag source example -->
|
||||
<Border Padding="12"
|
||||
Margin="0,16,0,0"
|
||||
Background="{ThemeResource Lattice.Brush.Background.Secondary}"
|
||||
CornerRadius="{ThemeResource Lattice.CornerRadius.Small}"
|
||||
BorderThickness="{ThemeResource Lattice.BorderThickness.Thin}"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Border.Primary}"
|
||||
x:Name="CustomDragSource">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Custom Drag Source"
|
||||
FontSize="{ThemeResource Lattice.FontSize.BodyStrong}"
|
||||
FontWeight="{ThemeResource Lattice.FontWeight.Semibold}"/>
|
||||
<TextBlock Text="Drag this custom control"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Caption}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"
|
||||
Margin="0,4,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Splitter (простой прямоугольник) -->
|
||||
<Rectangle Grid.Column="1"
|
||||
Fill="{ThemeResource Lattice.Brush.Splitter.Normal}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Rectangle.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem Text="Reset Panels" Click="OnResetPanelsClick"/>
|
||||
</MenuFlyout>
|
||||
</Rectangle.ContextFlyout>
|
||||
</Rectangle>
|
||||
<!-- ЗОНА С ЭЛЕМЕНТАМИ (откуда тянем) -->
|
||||
<StackPanel Grid.Column="1"
|
||||
Background="White"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Margin="10,0,0,0">
|
||||
|
||||
<TextBlock Text="📦 ЭЛЕМЕНТЫ ДЛЯ ПЕРЕТАСКИВАНИЯ"
|
||||
FontSize="16" FontWeight="Bold"
|
||||
Foreground="#2196F3"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 1. TextBlock элемент -->
|
||||
<Border Padding="15"
|
||||
Background="#E3F2FD"
|
||||
CornerRadius="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#90CAF9"
|
||||
Margin="0,0,0,10"
|
||||
lattice:DragDropProperties.IsDragSource="True"
|
||||
lattice:DragDropProperties.DragData="TextBlock Element">
|
||||
|
||||
<TextBlock Text="📝 Это TextBlock"
|
||||
FontSize="14"
|
||||
Foreground="#1565C0"
|
||||
FontWeight="SemiBold"/>
|
||||
</Border>
|
||||
|
||||
<!-- 2. Border элемент -->
|
||||
<Border Padding="15"
|
||||
Background="#E8F5E9"
|
||||
CornerRadius="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#A5D6A7"
|
||||
Margin="0,0,0,10"
|
||||
lattice:DragDropProperties.IsDragSource="True"
|
||||
lattice:DragDropProperties.DragData="Border Element">
|
||||
|
||||
<!-- Right Panel - Targets -->
|
||||
<Border Grid.Column="2"
|
||||
Background="{ThemeResource Lattice.Brush.Background.Primary}"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Panel.Border}"
|
||||
BorderThickness="{ThemeResource Lattice.BorderThickness.Panel}"
|
||||
CornerRadius="{ThemeResource Lattice.CornerRadius.Panel}"
|
||||
Padding="{ThemeResource Lattice.Spacing.Panel}"
|
||||
lattice:DragDropProperties.IsDropTarget="True"
|
||||
x:Name="DropTargetArea">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<TextBlock Text="Drop Targets"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Title}"
|
||||
FontWeight="{ThemeResource Lattice.FontWeight.Semibold}"
|
||||
Margin="0,0,0,12"/>
|
||||
<TextBlock Text="Drop items here"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Body}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"
|
||||
TextWrapping="Wrap"
|
||||
Margin="0,0,0,16"/>
|
||||
|
||||
<!-- Dropped Items Display -->
|
||||
<ItemsControl x:Name="DroppedItemsControl">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Padding="12"
|
||||
Margin="0,0,0,8"
|
||||
Background="{ThemeResource Lattice.Brush.Background.Secondary}"
|
||||
CornerRadius="{ThemeResource Lattice.CornerRadius.Small}"
|
||||
BorderThickness="{ThemeResource Lattice.BorderThickness.Thin}"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Border.Primary}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph=""
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Margin="0,0,12,0"
|
||||
Foreground="{ThemeResource Lattice.Brush.Success}"/>
|
||||
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding Name}"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Body}"
|
||||
FontWeight="{ThemeResource Lattice.FontWeight.Medium}"/>
|
||||
<TextBlock Text="{Binding Description}"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Caption}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Content="Remove"
|
||||
Click="OnRemoveItemClick"
|
||||
Margin="12,0,0,0"
|
||||
Tag="{Binding}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<!-- Drop Instructions -->
|
||||
<Border Padding="16"
|
||||
Margin="0,16,0,0"
|
||||
Background="{ThemeResource Lattice.Brush.Drop.Preview}"
|
||||
CornerRadius="{ThemeResource Lattice.CornerRadius.Medium}"
|
||||
BorderThickness="{ThemeResource Lattice.BorderThickness.Medium}"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Accent}"
|
||||
x:Name="DropInstructionsBorder">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<FontIcon Glyph=""
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
FontSize="24"
|
||||
Foreground="{ThemeResource Lattice.Brush.Accent}"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="0,0,0,12"/>
|
||||
<TextBlock Text="Drop items here"
|
||||
FontSize="{ThemeResource Lattice.FontSize.BodyStrong}"
|
||||
FontWeight="{ThemeResource Lattice.FontWeight.Medium}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Accent}"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="Drag and drop items from the left panel"
|
||||
FontSize="{ThemeResource Lattice.FontSize.Caption}"
|
||||
Foreground="{ThemeResource Lattice.Brush.Accent}"
|
||||
HorizontalAlignment="Center"
|
||||
Opacity="0.7"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<TextBlock Text="🟩 Это Border"
|
||||
FontSize="14"
|
||||
Foreground="#2E7D32"
|
||||
FontWeight="SemiBold"/>
|
||||
<TextBlock Text="С рамкой и заливкой"
|
||||
FontSize="12"
|
||||
Foreground="#666"
|
||||
Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Border>
|
||||
|
||||
<!-- 3. Grid элемент -->
|
||||
<Border Padding="15"
|
||||
Background="#FFF3E0"
|
||||
CornerRadius="8"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#FFCC80"
|
||||
lattice:DragDropProperties.IsDragSource="True"
|
||||
lattice:DragDropProperties.DragData="Grid Element">
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Иконка -->
|
||||
<TextBlock Grid.Column="0"
|
||||
Text="🔲"
|
||||
FontSize="18"
|
||||
Margin="0,0,10,0"
|
||||
VerticalAlignment="Center"/>
|
||||
|
||||
<!-- Контент -->
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="Это Grid"
|
||||
FontSize="14"
|
||||
Foreground="#EF6C00"
|
||||
FontWeight="SemiBold"/>
|
||||
<TextBlock Text="С несколькими колонками"
|
||||
FontSize="12"
|
||||
Foreground="#666"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Status Bar -->
|
||||
<Border Grid.Row="2"
|
||||
Background="{ThemeResource Lattice.Brush.Background.Secondary}"
|
||||
BorderThickness="1,0,0,0"
|
||||
BorderBrush="{ThemeResource Lattice.Brush.Border.Primary}"
|
||||
Padding="12">
|
||||
<Grid>
|
||||
<TextBlock x:Name="StatusText"
|
||||
Text="Ready"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="12"
|
||||
HorizontalAlignment="Right">
|
||||
<TextBlock x:Name="DragStatsText"
|
||||
Text="Drag operations: 0"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"/>
|
||||
<TextBlock Text="|"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Disabled}"/>
|
||||
<TextBlock x:Name="DropStatsText"
|
||||
Text="Dropped items: 0"
|
||||
Foreground="{ThemeResource Lattice.Brush.Text.Secondary}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -1,421 +1,17 @@
|
||||
using Lattice.Core.DragDrop.Services;
|
||||
using Lattice.Themes;
|
||||
using Lattice.UI.DragDrop.WinUI.Factories;
|
||||
using Lattice.UI.DragDrop.WinUI.Services;
|
||||
using Lattice.UI.DragDrop.WinUI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lattice.Example.DragDrop;
|
||||
|
||||
public sealed partial class MainWindow : Window
|
||||
{
|
||||
private readonly ObservableCollection<DragDropItem> _sourceItems = new();
|
||||
private readonly ObservableCollection<DragDropItem> _droppedItems = new();
|
||||
|
||||
private WinUIDragDropManager? _dragDropManager;
|
||||
private IDragDropService? _dragDropService;
|
||||
|
||||
private int _dragOperationCount = 0;
|
||||
private bool _isInitialized = false;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
|
||||
// Создаем менеджер перетаскивания
|
||||
_dragDropManager = WinUIDragDropFactory.CreateManager(this, manager =>
|
||||
{
|
||||
// Настраиваем смещение визуального элемента
|
||||
manager.DragVisualOffset = new Core.Geometry.Point(-15, -15);
|
||||
});
|
||||
|
||||
_dragDropService = _dragDropManager.DragDropService;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
// Устанавливаем размер окна
|
||||
SetWindowSize(1200, 800);
|
||||
|
||||
// Инициализируем данные
|
||||
InitializeData();
|
||||
|
||||
// Инициализируем drag & drop систему
|
||||
InitializeDragDrop();
|
||||
|
||||
// Устанавливаем контекст данных
|
||||
SourceItemsControl.ItemsSource = _sourceItems;
|
||||
DroppedItemsControl.ItemsSource = _droppedItems;
|
||||
|
||||
Closed += MainWindow_Closing;
|
||||
// Обновляем видимость инструкций
|
||||
UpdateDropInstructions();
|
||||
}
|
||||
|
||||
private void MainWindow_Closing(object sender, WindowEventArgs args)
|
||||
{
|
||||
// Очищаем ресурсы
|
||||
_dragDropManager?.Dispose();
|
||||
}
|
||||
|
||||
private void InitializeData()
|
||||
{
|
||||
// Создаем тестовые данные для перетаскивания
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Document",
|
||||
Description = "Microsoft Word document",
|
||||
Icon = "Document",
|
||||
Type = "File"
|
||||
});
|
||||
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Image",
|
||||
Description = "PNG image file",
|
||||
Icon = "Pictures",
|
||||
Type = "File"
|
||||
});
|
||||
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Music",
|
||||
Description = "MP3 audio file",
|
||||
Icon = "Audio",
|
||||
Type = "File"
|
||||
});
|
||||
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Video",
|
||||
Description = "MP4 video file",
|
||||
Icon = "Video",
|
||||
Type = "File"
|
||||
});
|
||||
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Contact",
|
||||
Description = "Contact information",
|
||||
Icon = "Contact",
|
||||
Type = "Data"
|
||||
});
|
||||
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Link",
|
||||
Description = "Web URL",
|
||||
Icon = "Link",
|
||||
Type = "Link"
|
||||
});
|
||||
|
||||
_sourceItems.Add(new DragDropItem
|
||||
{
|
||||
Name = "Folder",
|
||||
Description = "File system folder",
|
||||
Icon = "Folder",
|
||||
Type = "Folder"
|
||||
});
|
||||
}
|
||||
|
||||
private void InitializeDragDrop()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
// Настраиваем кастомный источник перетаскивания
|
||||
_dragDropManager.MakeDragSource(CustomDragSource, new DragDropItem
|
||||
{
|
||||
Name = "Custom Element",
|
||||
Description = "This is a custom drag source example",
|
||||
Icon = "Favorite",
|
||||
Type = "Custom"
|
||||
});
|
||||
|
||||
// Настраиваем обработчик для области сброса
|
||||
_dragDropManager.MakeDropTarget(DropTargetArea);
|
||||
|
||||
// Подписываемся на события перетаскивания
|
||||
_dragDropService.DragStarted += OnDragStarted;
|
||||
_dragDropService.DragUpdated += OnDragUpdated;
|
||||
_dragDropService.DragCompleted += OnDragCompleted;
|
||||
_dragDropService.DragCancelled += OnDragCancelled;
|
||||
_dragDropService.DropTargetChanged += OnDropTargetChanged;
|
||||
_dragDropService.ErrorOccurred += OnDragDropError;
|
||||
|
||||
UpdateStats();
|
||||
|
||||
StatusText.Text = "Drag & Drop system initialized";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText.Text = $"Failed to initialize Drag & Drop: {ex.Message}";
|
||||
ShowErrorDialog("Initialization Error", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragStarted(object? sender, Core.DragDrop.Services.DragStartedEventArgs e)
|
||||
{
|
||||
_dragOperationCount++;
|
||||
UpdateStats();
|
||||
|
||||
StatusText.Text = $"Dragging started: {GetItemName(e.DragInfo.Data)}";
|
||||
}
|
||||
|
||||
private void OnDragUpdated(object? sender, Core.DragDrop.Services.DragUpdatedEventArgs e)
|
||||
{
|
||||
StatusText.Text = $"Dragging: {GetItemName(e.DragInfo.Data)} at ({e.Position.X:F0}, {e.Position.Y:F0})";
|
||||
}
|
||||
|
||||
private void OnDragCompleted(object? sender, Core.DragDrop.Services.DragCompletedEventArgs e)
|
||||
{
|
||||
// Проверяем, что элемент сброшен на нашу область
|
||||
if (e.DragInfo.Data is DragDropItem item)
|
||||
{
|
||||
// Добавляем элемент в список сброшенных
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
if (!_droppedItems.Contains(item))
|
||||
{
|
||||
_droppedItems.Add(item);
|
||||
|
||||
// Удаляем из источников, если это не кастомный элемент
|
||||
if (_sourceItems.Contains(item) && item.Name != "Custom Element")
|
||||
{
|
||||
_sourceItems.Remove(item);
|
||||
}
|
||||
|
||||
UpdateStats();
|
||||
UpdateDropInstructions();
|
||||
StatusText.Text = $"Item dropped: {item.Name}";
|
||||
|
||||
// Показываем уведомление
|
||||
ShowDropNotification(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusText.Text = "Drag completed";
|
||||
}
|
||||
}
|
||||
|
||||
private async void ShowDropNotification(DragDropItem item)
|
||||
{
|
||||
var notification = new TeachingTip
|
||||
{
|
||||
Title = "Item Dropped",
|
||||
Subtitle = $"Successfully dropped '{item.Name}'",
|
||||
IsOpen = true,
|
||||
PreferredPlacement = TeachingTipPlacementMode.TopRight,
|
||||
Target = DropTargetArea
|
||||
};
|
||||
|
||||
// Автоматически скрываем через 3 секунды
|
||||
await Task.Delay(3000);
|
||||
notification.IsOpen = false;
|
||||
}
|
||||
|
||||
private void OnDragCancelled(object? sender, Core.DragDrop.Services.DragCancelledEventArgs e)
|
||||
{
|
||||
StatusText.Text = "Drag cancelled";
|
||||
}
|
||||
|
||||
private void OnDropTargetChanged(object? sender, Core.DragDrop.Services.DropTargetChangedEventArgs e)
|
||||
{
|
||||
if (e.Target != null)
|
||||
{
|
||||
StatusText.Text = "Over drop target";
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusText.Text = "Not over drop target";
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnDragDropError(object? sender, Core.DragDrop.Services.DragDropErrorEventArgs e)
|
||||
{
|
||||
StatusText.Text = $"Error: {e.Exception.Message}";
|
||||
await ShowErrorDialog("Drag & Drop Error", e.Exception.Message);
|
||||
}
|
||||
|
||||
private string GetItemName(object? data)
|
||||
{
|
||||
if (data is DragDropItem item)
|
||||
{
|
||||
return item.Name;
|
||||
}
|
||||
return data?.ToString() ?? "Unknown";
|
||||
}
|
||||
|
||||
private void UpdateStats()
|
||||
{
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
DragStatsText.Text = $"Drag operations: {_dragOperationCount}";
|
||||
DropStatsText.Text = $"Dropped items: {_droppedItems.Count}";
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateDropInstructions()
|
||||
{
|
||||
DropInstructionsBorder.Visibility = _droppedItems.Count == 0 ?
|
||||
Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void OnThemeToggleToggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is ToggleSwitch toggle)
|
||||
{
|
||||
try
|
||||
{
|
||||
var themeManager = ThemeManager.Current;
|
||||
if (toggle.IsOn)
|
||||
{
|
||||
themeManager.ApplyTheme("Fluent Dark");
|
||||
}
|
||||
else
|
||||
{
|
||||
themeManager.ApplyTheme("Fluent");
|
||||
}
|
||||
|
||||
StatusText.Text = $"Theme changed to {(toggle.IsOn ? "Dark" : "Light")}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText.Text = $"Failed to change theme: {ex.Message}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnStatsButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_dragDropService != null)
|
||||
{
|
||||
var stats = _dragDropService.GetStats();
|
||||
|
||||
var dialog = new ContentDialog
|
||||
{
|
||||
Title = "Drag & Drop Statistics",
|
||||
Content = new ScrollViewer
|
||||
{
|
||||
Content = new StackPanel
|
||||
{
|
||||
Spacing = 8,
|
||||
Children =
|
||||
{
|
||||
CreateStatRow("Total Drag Operations:", stats.TotalDragOperations.ToString()),
|
||||
CreateStatRow("Successful Drops:", stats.SuccessfulDrops.ToString()),
|
||||
CreateStatRow("Cancelled Operations:", stats.CancelledOperations.ToString()),
|
||||
CreateStatRow("Errors:", stats.ErrorCount.ToString()),
|
||||
CreateStatRow("Registered Targets:", stats.RegisteredTargets.ToString()),
|
||||
CreateStatRow("Average Operation Time:",
|
||||
stats.AverageOperationTime.TotalMilliseconds.ToString("F0") + "ms")
|
||||
}
|
||||
}
|
||||
},
|
||||
PrimaryButtonText = "OK",
|
||||
XamlRoot = Content.XamlRoot
|
||||
};
|
||||
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private StackPanel CreateStatRow(string label, string value)
|
||||
{
|
||||
return new StackPanel
|
||||
{
|
||||
Orientation = Orientation.Horizontal,
|
||||
Spacing = 10,
|
||||
Children =
|
||||
{
|
||||
new TextBlock
|
||||
{
|
||||
Text = label,
|
||||
FontWeight = Microsoft.UI.Text.FontWeights.SemiBold,
|
||||
Width = 200
|
||||
},
|
||||
new TextBlock
|
||||
{
|
||||
Text = value
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void OnRemoveItemClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && button.Tag is DragDropItem item)
|
||||
{
|
||||
_droppedItems.Remove(item);
|
||||
UpdateStats();
|
||||
UpdateDropInstructions();
|
||||
|
||||
// Добавляем обратно в источники, если это не кастомный элемент
|
||||
if (item.Name != "Custom Element" && !_sourceItems.Contains(item))
|
||||
{
|
||||
_sourceItems.Add(item);
|
||||
}
|
||||
|
||||
StatusText.Text = $"Item removed: {item.Name}";
|
||||
}
|
||||
}
|
||||
|
||||
private void OnResetPanelsClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// Очищаем все сброшенные элементы
|
||||
foreach (var item in _droppedItems.ToList())
|
||||
{
|
||||
if (item.Name != "Custom Element" && !_sourceItems.Contains(item))
|
||||
{
|
||||
_sourceItems.Add(item);
|
||||
}
|
||||
}
|
||||
_droppedItems.Clear();
|
||||
UpdateStats();
|
||||
UpdateDropInstructions();
|
||||
|
||||
StatusText.Text = "Panels reset";
|
||||
}
|
||||
|
||||
private async Task ShowErrorDialog(string title, string message)
|
||||
{
|
||||
var dialog = new ContentDialog
|
||||
{
|
||||
Title = title,
|
||||
Content = message,
|
||||
PrimaryButtonText = "OK",
|
||||
XamlRoot = Content.XamlRoot
|
||||
};
|
||||
|
||||
await dialog.ShowAsync();
|
||||
}
|
||||
|
||||
// Метод для установки размера окна
|
||||
private void SetWindowSize(int width, int height)
|
||||
{
|
||||
try
|
||||
{
|
||||
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hwnd);
|
||||
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
|
||||
|
||||
appWindow.Resize(new Windows.Graphics.SizeInt32(width, height));
|
||||
|
||||
// Центрируем окно
|
||||
var displayArea = Microsoft.UI.Windowing.DisplayArea.GetFromWindowId(windowId,
|
||||
Microsoft.UI.Windowing.DisplayAreaFallback.Primary);
|
||||
var centerX = (displayArea.WorkArea.Width - width) / 2;
|
||||
var centerY = (displayArea.WorkArea.Height - height) / 2;
|
||||
|
||||
appWindow.Move(new Windows.Graphics.PointInt32(centerX, centerY));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Игнорируем ошибки при установке размера окна
|
||||
System.Diagnostics.Debug.WriteLine($"Failed to set window size: {ex.Message}");
|
||||
}
|
||||
XamlInitializer.Initialize(this);
|
||||
Title = "✅ Drag & Drop работает! Перетащите элементы →";
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Lattice.Example.DragDrop;
|
||||
|
||||
public class DragDropItem : INotifyPropertyChanged
|
||||
{
|
||||
private string _name = string.Empty;
|
||||
private string _description = string.Empty;
|
||||
private string _icon = string.Empty;
|
||||
private string _type = string.Empty;
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
if (_name != value)
|
||||
{
|
||||
_name = value;
|
||||
OnPropertyChanged(nameof(Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get => _description;
|
||||
set
|
||||
{
|
||||
if (_description != value)
|
||||
{
|
||||
_description = value;
|
||||
OnPropertyChanged(nameof(Description));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Icon
|
||||
{
|
||||
get => _icon;
|
||||
set
|
||||
{
|
||||
if (_icon != value)
|
||||
{
|
||||
_icon = value;
|
||||
OnPropertyChanged(nameof(Icon));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Type
|
||||
{
|
||||
get => _type;
|
||||
set
|
||||
{
|
||||
if (_type != value)
|
||||
{
|
||||
_type = value;
|
||||
OnPropertyChanged(nameof(Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public override string ToString() => $"{Name} ({Type})";
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
|
||||
namespace Lattice.Example.DragDrop;
|
||||
|
||||
public class PriorityToTextConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is int priority)
|
||||
{
|
||||
return priority switch
|
||||
{
|
||||
1 => "🔥 High",
|
||||
2 => "⚠️ Medium",
|
||||
3 => "📋 Low",
|
||||
_ => $"Priority {priority}"
|
||||
};
|
||||
}
|
||||
return "Normal";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Lattice.Example.DragDrop;
|
||||
|
||||
public static class WindowExtensions
|
||||
{
|
||||
public static void SetWindowSize(this Window window, int width, int height)
|
||||
{
|
||||
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
|
||||
var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hwnd);
|
||||
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
|
||||
|
||||
appWindow.Resize(new Windows.Graphics.SizeInt32(width, height));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user