Добавлен example

This commit is contained in:
2026-01-25 07:56:35 +03:00
parent a902474345
commit 33abd94f6e
20 changed files with 1052 additions and 1 deletions

View File

@@ -0,0 +1,15 @@
<Application
x:Class="Lattice.Example.DragDrop.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Lattice.Example.DragDrop">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Fluent Theme Resources -->
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,33 @@
using Lattice.Themes;
using Lattice.Themes.Fluent;
using Microsoft.UI.Xaml;
namespace Lattice.Example.DragDrop;
public partial class App : Application
{
private Window? _window;
public App()
{
InitializeComponent();
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
// Регистрируем Fluent тему
var themeManager = ThemeManager.Current;
themeManager.RegisterTheme(new FluentThemePack(false)); // Light тема
themeManager.RegisterTheme(new FluentThemePack(true)); // Dark тема
// Применяем тему по умолчанию
themeManager.ApplyTheme("Fluent");
// Создаем главное окно
_window = new MainWindow();
_window.Activate();
// Регистрируем окно в трекере
WindowTracker.Register(_window);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,46 @@
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;
}
}

View File

@@ -0,0 +1,67 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>Lattice.Example.DragDrop</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
<UseWinUI>true</UseWinUI>
<WinUISDKReferences>false</WinUISDKReferences>
<EnableMsixTooling>true</EnableMsixTooling>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<!--
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored.
-->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7463" />
<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>
<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Explorer "Package and Publish" context menu entry to be enabled for this project even if
the Windows App SDK Nuget package has not yet been restored.
-->
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
</PropertyGroup>
<!-- Publish Properties -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,270 @@
<Window
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">
<Grid>
<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>
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="12">
<FontIcon Glyph="&#xE718;"
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.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}">
<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}"
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="&#xE7C5;"
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>
</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>
<!-- 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="&#xE8FB;"
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="&#xE896;"
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>
</StackPanel>
</ScrollViewer>
</Border>
</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>

View File

@@ -0,0 +1,421 @@
using Lattice.Core.DragDrop.Services;
using Lattice.Themes;
using Lattice.UI.DragDrop.WinUI.Factories;
using Lattice.UI.DragDrop.WinUI.Services;
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;
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}");
}
}
}

View File

@@ -0,0 +1,72 @@
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})";
}

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="dcfd6640-86d9-4ce7-bc17-24685f01b577"
Publisher="CN=frost"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="dcfd6640-86d9-4ce7-bc17-24685f01b577" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>Lattice.Example.DragDrop</DisplayName>
<PublisherDisplayName>frost</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="Lattice.Example.DragDrop"
Description="Lattice.Example.DragDrop"
BackgroundColor="transparent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@@ -0,0 +1,27 @@
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();
}
}

View File

@@ -0,0 +1,10 @@
{
"profiles": {
"Lattice.Example.DragDrop (Package)": {
"commandName": "MsixPackage"
},
"Lattice.Example.DragDrop (Unpackaged)": {
"commandName": "Project"
}
}
}

View File

@@ -0,0 +1,15 @@
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));
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Lattice.Example.DragDrop.app"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
</assembly>

View File

@@ -1,5 +1,10 @@
<Solution> <Solution>
<Folder Name="/demo/" /> <Folder Name="/demo/">
<Project Path="Lattice.Example.DragDrop/Lattice.Example.DragDrop.csproj" Id="d9f1ca2e-3173-459a-aa17-25b92bc82329">
<Platform Project="x64" />
<Deploy />
</Project>
</Folder>
<Folder Name="/src/" /> <Folder Name="/src/" />
<Folder Name="/src/Core/"> <Folder Name="/src/Core/">
<Project Path="Lattice.Core.Geometry/Lattice.Core.Geometry.csproj" Id="a84c6664-28fa-4082-9b91-6b2f3228ea53" /> <Project Path="Lattice.Core.Geometry/Lattice.Core.Geometry.csproj" Id="a84c6664-28fa-4082-9b91-6b2f3228ea53" />