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; /// /// Реализация менеджера контекстных меню для WinUI. /// public sealed class WinUIDockContextManager : DockContextManagerBase, IDisposable { private readonly ConcurrentDictionary _commands = new(); private MenuFlyout? _currentFlyout; private IDockControl? _currentContextTarget; /// /// Инициализирует новый экземпляр менеджера контекстных меню. /// public WinUIDockContextManager() { } /// 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); } /// public override void HideContextMenu() { if (_currentFlyout != null) { _currentFlyout.Hide(); _currentFlyout = null; } if (_currentContextTarget != null) { OnContextMenuHidden(); _currentContextTarget = null; } } /// /// Класс-заглушка для реализации ICommand. /// private sealed class RelayCommand : System.Windows.Input.ICommand { private readonly Action _execute; private readonly Func? _canExecute; public event EventHandler? CanExecuteChanged; public RelayCommand(Action execute, Func? 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); } /// public void Dispose() { HideContextMenu(); _commands.Clear(); } }