using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
namespace Avalonia.Controls
{
///
/// Base class for menu controls.
///
public abstract class MenuBase : SelectingItemsControl, IFocusScope, IMenu
{
///
/// Defines the property.
///
public static readonly DirectProperty IsOpenProperty =
AvaloniaProperty.RegisterDirect(
nameof(IsOpen),
o => o.IsOpen);
///
/// Defines the event.
///
public static readonly RoutedEvent MenuOpenedEvent =
RoutedEvent.Register(nameof(MenuOpened), RoutingStrategies.Bubble);
///
/// Defines the event.
///
public static readonly RoutedEvent MenuClosedEvent =
RoutedEvent.Register(nameof(MenuClosed), RoutingStrategies.Bubble);
private bool _isOpen;
///
/// Initializes a new instance of the class.
///
protected MenuBase()
{
InteractionHandler = new DefaultMenuInteractionHandler(false);
}
///
/// Initializes a new instance of the class.
///
/// The menu interaction handler.
protected MenuBase(IMenuInteractionHandler interactionHandler)
{
InteractionHandler = interactionHandler ?? throw new ArgumentNullException(nameof(interactionHandler));
}
///
/// Initializes static members of the class.
///
static MenuBase()
{
MenuItem.SubmenuOpenedEvent.AddClassHandler((x, e) => x.OnSubmenuOpened(e));
}
///
/// Gets a value indicating whether the menu is open.
///
public bool IsOpen
{
get { return _isOpen; }
protected set { SetAndRaise(IsOpenProperty, ref _isOpen, value); }
}
///
IMenuInteractionHandler IMenu.InteractionHandler => InteractionHandler;
///
IMenuItem? IMenuElement.SelectedItem
{
get
{
var index = SelectedIndex;
return (index != -1) ?
(IMenuItem?)ItemContainerGenerator.ContainerFromIndex(index) :
null;
}
set
{
SelectedIndex = value is not null ?
ItemContainerGenerator.IndexFromContainer(value) : -1;
}
}
///
IEnumerable IMenuElement.SubItems
{
get
{
return ItemContainerGenerator.Containers
.Select(x => x.ContainerControl)
.OfType();
}
}
///
/// Gets the interaction handler for the menu.
///
protected IMenuInteractionHandler InteractionHandler { get; }
///
/// Occurs when a is opened.
///
public event EventHandler? MenuOpened
{
add { AddHandler(MenuOpenedEvent, value); }
remove { RemoveHandler(MenuOpenedEvent, value); }
}
///
/// Occurs when a is closed.
///
public event EventHandler? MenuClosed
{
add { AddHandler(MenuClosedEvent, value); }
remove { RemoveHandler(MenuClosedEvent, value); }
}
///
/// Closes the menu.
///
public abstract void Close();
///
/// Opens the menu.
///
public abstract void Open();
///
bool IMenuElement.MoveSelection(NavigationDirection direction, bool wrap) => MoveSelection(direction, wrap);
///
protected override IItemContainerGenerator CreateItemContainerGenerator()
{
return new ItemContainerGenerator