7 changed files with 176 additions and 0 deletions
@ -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<object>(); |
|||
} |
|||
|
|||
public static readonly DirectProperty<MenuFlyout, IEnumerable> ItemsProperty = |
|||
ItemsControl.ItemsProperty.AddOwner<MenuFlyout>(x => x.Items, |
|||
(x, v) => x.Items = v); |
|||
|
|||
public static readonly DirectProperty<MenuFlyout, IDataTemplate?> ItemTemplateProperty = |
|||
AvaloniaProperty.RegisterDirect<MenuFlyout, IDataTemplate?>(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; |
|||
} |
|||
} |
|||
} |
|||
@ -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<Popup>(); |
|||
if (host != null) |
|||
{ |
|||
host.IsOpen = false; |
|||
} |
|||
} |
|||
|
|||
public override void Open() |
|||
{ |
|||
//Ignore
|
|||
} |
|||
|
|||
protected override IItemContainerGenerator CreateItemContainerGenerator() |
|||
{ |
|||
return new MenuItemContainerGenerator(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
|
|||
<Style Selector="MenuFlyoutPresenter"> |
|||
<Setter Property="Background" Value="{DynamicResource MenuFlyoutPresenterBackground}" /> |
|||
<Setter Property="BorderBrush" Value="{DynamicResource MenuFlyoutPresenterBorderBrush}" /> |
|||
<Setter Property="BorderThickness" Value="{DynamicResource MenuFlyoutPresenterBorderThemeThickness}" /> |
|||
<Setter Property="Padding" Value="{DynamicResource MenuFlyoutPresenterThemePadding}" /> |
|||
<Setter Property="MaxWidth" Value="{DynamicResource FlyoutThemeMaxWidth}" /> |
|||
<Setter Property="MinHeight" Value="{DynamicResource MenuFlyoutThemeMinHeight}" /> |
|||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" /> |
|||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" /> |
|||
<Setter Property="Template"> |
|||
<ControlTemplate> |
|||
<Border Name="LayoutRoot" |
|||
Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Padding="{DynamicResource FlyoutBorderThemePadding}"> |
|||
<ScrollViewer HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" |
|||
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"> |
|||
<ItemsPresenter Name="PART_ItemsPresenter" |
|||
Items="{TemplateBinding Items}" |
|||
ItemsPanel="{TemplateBinding ItemsPanel}" |
|||
ItemTemplate="{TemplateBinding ItemTemplate}" |
|||
Margin="{DynamicResource MenuFlyoutScrollerMargin}" |
|||
KeyboardNavigation.TabNavigation="Continue" |
|||
Grid.IsSharedSizeScope="True" /> |
|||
</ScrollViewer> |
|||
</Border> |
|||
</ControlTemplate> |
|||
</Setter> |
|||
</Style> |
|||
<Style Selector="MenuFlyoutPresenter /template/ Border#LayoutRoot"> |
|||
<Setter Property="CornerRadius" Value="{DynamicResource OverlayCornerRadius}" /> |
|||
</Style> |
|||
</Styles> |
|||
Loading…
Reference in new issue