Browse Source

Add MenuFlyout

pull/5682/head
amwx 5 years ago
parent
commit
4bd187d362
  1. 87
      src/Avalonia.Controls/Flyouts/MenuFlyout.cs
  2. 36
      src/Avalonia.Controls/Flyouts/MenuFlyoutPresenter.cs
  3. 5
      src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml
  4. 5
      src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml
  5. 2
      src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml
  6. 5
      src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml
  7. 36
      src/Avalonia.Themes.Fluent/Controls/MenuFlyoutPresenter.xaml

87
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<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;
}
}
}

36
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<Popup>();
if (host != null)
{
host.IsOpen = false;
}
}
public override void Open()
{
//Ignore
}
protected override IItemContainerGenerator CreateItemContainerGenerator()
{
return new MenuItemContainerGenerator(this);
}
}
}

5
src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesDark.xaml

@ -809,5 +809,10 @@
<StaticResource x:Key="CalendarDatePickerForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CalendarDatePickerBorderBrush" ResourceKey="SystemControlForegroundBaseMediumBrush" />
<Thickness x:Key="CalendarDatePickerBorderThemeThickness">1</Thickness>
<!-- Resources for FlyoutPresenter.xaml -->
<StaticResource x:Key="FlyoutPresenterBackground" ResourceKey="SystemControlBackgroundChromeMediumLowBrush" />
<StaticResource x:Key="FlyoutBorderThemeBrush" ResourceKey="SystemControlForegroundChromeHighBrush" />
</Style.Resources>
</Style>

5
src/Avalonia.Themes.Fluent/Accents/FluentControlResourcesLight.xaml

@ -807,5 +807,10 @@
<StaticResource x:Key="CalendarDatePickerForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
<StaticResource x:Key="CalendarDatePickerBorderBrush" ResourceKey="SystemControlForegroundBaseMediumBrush" />
<Thickness x:Key="CalendarDatePickerBorderThemeThickness">1</Thickness>
<!-- Resources for FlyoutPresenter.xaml -->
<StaticResource x:Key="FlyoutPresenterBackground" ResourceKey="SystemControlBackgroundChromeMediumLowBrush" />
<StaticResource x:Key="FlyoutBorderThemeBrush" ResourceKey="SystemControlForegroundChromeHighBrush" />
</Style.Resources>
</Style>

2
src/Avalonia.Themes.Fluent/Controls/FluentControls.xaml

@ -59,4 +59,6 @@
<StyleInclude Source="avares://Avalonia.Themes.Fluent/Controls/SplitView.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Fluent/Controls/DatePicker.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Fluent/Controls/TimePicker.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Fluent/Controls/MenuFlyoutPresenter.xaml"/>
</Styles>

5
src/Avalonia.Themes.Fluent/Controls/FlyoutPresenter.xaml

@ -1,4 +1,9 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Styles.Resources>
<Thickness x:Key="FlyoutBorderThemeThickness">1</Thickness>
<Thickness x:Key="FlyoutBorderThemePadding">0</Thickness>
</Styles.Resources>
<Style Selector="FlyoutPresenter">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />

36
src/Avalonia.Themes.Fluent/Controls/MenuFlyoutPresenter.xaml

@ -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…
Cancel
Save