DragAndDrop core
This commit is contained in:
116
Lattice.UI.Docking.WinUI/Services/WinUIDockContextManager.cs
Normal file
116
Lattice.UI.Docking.WinUI/Services/WinUIDockContextManager.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using Lattice.UI.Docking.Abstractions;
|
||||
using Lattice.UI.Docking.Services;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Lattice.UI.Docking.WinUI.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Реализация менеджера контекстных меню для WinUI.
|
||||
/// </summary>
|
||||
public sealed class WinUIDockContextManager : DockContextManagerBase, IDisposable
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, IDockCommand> _commands = new();
|
||||
private MenuFlyout? _currentFlyout;
|
||||
private IDockControl? _currentContextTarget;
|
||||
|
||||
/// <summary>
|
||||
/// Инициализирует новый экземпляр менеджера контекстных меню.
|
||||
/// </summary>
|
||||
public WinUIDockContextManager()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void ShowContextMenu(IDockControl element, double x, double y)
|
||||
{
|
||||
if (element is not FrameworkElement uiElement) return;
|
||||
|
||||
// Создаем контекстное меню
|
||||
var flyout = new MenuFlyout();
|
||||
|
||||
// Получаем команды для элемента
|
||||
var commands = GetCommandsForElement(element);
|
||||
|
||||
foreach (var command in commands)
|
||||
{
|
||||
var item = new MenuFlyoutItem
|
||||
{
|
||||
Text = command.Name,
|
||||
Command = new RelayCommand(() => ExecuteCommand(command, element))
|
||||
};
|
||||
|
||||
// Добавляем иконку, если есть
|
||||
if (!string.IsNullOrEmpty(command.Icon))
|
||||
{
|
||||
// TODO: Добавить иконку команды
|
||||
}
|
||||
|
||||
flyout.Items.Add(item);
|
||||
}
|
||||
|
||||
// Если команд нет, не показываем меню
|
||||
if (flyout.Items.Count == 0) return;
|
||||
|
||||
// Закрываем предыдущее меню, если оно открыто
|
||||
HideContextMenu();
|
||||
|
||||
// Сохраняем ссылки
|
||||
_currentFlyout = flyout;
|
||||
_currentContextTarget = element;
|
||||
|
||||
// Показываем меню
|
||||
flyout.ShowAt(uiElement, new Windows.Foundation.Point(x, y));
|
||||
|
||||
// Вызываем событие
|
||||
OnContextMenuShown(element, x, y);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void HideContextMenu()
|
||||
{
|
||||
if (_currentFlyout != null)
|
||||
{
|
||||
_currentFlyout.Hide();
|
||||
_currentFlyout = null;
|
||||
}
|
||||
|
||||
if (_currentContextTarget != null)
|
||||
{
|
||||
OnContextMenuHidden();
|
||||
_currentContextTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Класс-заглушка для реализации ICommand.
|
||||
/// </summary>
|
||||
private sealed class RelayCommand : System.Windows.Input.ICommand
|
||||
{
|
||||
private readonly Action _execute;
|
||||
private readonly Func<bool>? _canExecute;
|
||||
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
|
||||
public RelayCommand(Action execute, Func<bool>? canExecute = null)
|
||||
{
|
||||
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object? parameter) => _canExecute?.Invoke() ?? true;
|
||||
|
||||
public void Execute(object? parameter) => _execute();
|
||||
|
||||
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
HideContextMenu();
|
||||
_commands.Clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user