diff --git a/src/Avalonia.Controls/Flyouts/MenuFlyout.cs b/src/Avalonia.Controls/Flyouts/MenuFlyout.cs new file mode 100644 index 0000000000..8eea5f211d --- /dev/null +++ b/src/Avalonia.Controls/Flyouts/MenuFlyout.cs @@ -0,0 +1,87 @@ +using System.Collections; +using System.Collections.Specialized; +using Avalonia.Collections; +using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; +using Avalonia.Input; +using Avalonia.Metadata; +using Avalonia.Styling; + +#nullable enable + +namespace Avalonia.Controls +{ + public class MenuFlyout : FlyoutBase + { + public MenuFlyout() + { + _items = new AvaloniaList(); + } + + public static readonly DirectProperty ItemsProperty = + ItemsControl.ItemsProperty.AddOwner(x => x.Items, + (x, v) => x.Items = v); + + public static readonly DirectProperty ItemTemplateProperty = + AvaloniaProperty.RegisterDirect(nameof(ItemTemplate), + x => x.ItemTemplate, (x, v) => x.ItemTemplate = v); + + public Styles? FlyoutPresenterStyle + { + get + { + if (_styles == null) + { + _styles = new Styles(); + _styles.CollectionChanged += OnMenuFlyoutPresenterStyleChanged; + } + + return _styles; + } + } + + [Content] + public IEnumerable Items + { + get => _items; + set => SetAndRaise(ItemsProperty, ref _items, value); + } + + public IDataTemplate? ItemTemplate + { + get => _itemTemplate; + set => SetAndRaise(ItemTemplateProperty, ref _itemTemplate, value); + } + + private Styles? _styles; + private bool _stylesDirty = true; + private IEnumerable _items; + private IDataTemplate? _itemTemplate; + + protected override Control CreatePresenter() + { + return new MenuFlyoutPresenter + { + [!ItemsControl.ItemsProperty] = this[!ItemsProperty], + [!ItemsControl.ItemTemplateProperty] = this[!ItemTemplateProperty] + }; + } + + protected override void OnOpened() + { + if (_styles != null && _stylesDirty) + { + // Presenter for flyout generally shouldn't be public, so + // we should be ok to just reset the styles + _popup.Child.Styles.Clear(); + _popup.Child.Styles.Add(_styles); + } + base.OnOpened(); + } + + private void OnMenuFlyoutPresenterStyleChanged(object sender, NotifyCollectionChangedEventArgs e) + { + _stylesDirty = true; + } + } +} diff --git a/src/Avalonia.Controls/Flyouts/MenuFlyoutPresenter.cs b/src/Avalonia.Controls/Flyouts/MenuFlyoutPresenter.cs new file mode 100644 index 0000000000..7e59d824fa --- /dev/null +++ b/src/Avalonia.Controls/Flyouts/MenuFlyoutPresenter.cs @@ -0,0 +1,36 @@ +using Avalonia.Controls.Generators; +using Avalonia.Controls.Platform; +using Avalonia.Controls.Primitives; +using Avalonia.LogicalTree; + +namespace Avalonia.Controls +{ + public class MenuFlyoutPresenter : MenuBase + { + public MenuFlyoutPresenter() + :base(new DefaultMenuInteractionHandler(true)) + { + + } + + public override void Close() + { + // DefaultMenuInteractionHandler calls this + var host = this.FindLogicalAncestorOfType(); + if (host != null) + { + host.IsOpen = false; + } + } + + public override void Open() + { + //Ignore + } + + protected override IItemContainerGenerator CreateItemContainerGenerator() + { + return new MenuItemContainerGenerator(this); + } + } +} diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml index abc02a6371..ae1fe42031 100644 --- a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml +++ b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml @@ -809,5 +809,10 @@ 1 + + + + + diff --git a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml index 6a2a04f732..5af24f57a8 100644 --- a/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml +++ b/src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml @@ -807,5 +807,10 @@ 1 + + + + + diff --git a/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml b/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml index 0acb8f4f6e..16e05ffdfd 100644 --- a/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml @@ -59,4 +59,6 @@ + + diff --git a/src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml b/src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml index 2be49d007b..3a8df060fa 100644 --- a/src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml @@ -1,4 +1,9 @@ + + 1 + 0 + + + +