From 4f11ecdd38a6dc7bd50a342b22537f6970de7e95 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 12 Sep 2018 13:07:32 +0200 Subject: [PATCH 1/2] Added an example of dynamic menus to the ControlCatalog. Creates a menu using `DataTemplates` on the MenuPage. --- samples/ControlCatalog/App.xaml | 9 ++- samples/ControlCatalog/Pages/MenuPage.xaml | 59 ++++++++++++------- samples/ControlCatalog/Pages/MenuPage.xaml.cs | 28 +++++++++ 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/samples/ControlCatalog/App.xaml b/samples/ControlCatalog/App.xaml index 43971dec4f..95d515ec60 100644 --- a/samples/ControlCatalog/App.xaml +++ b/samples/ControlCatalog/App.xaml @@ -14,6 +14,11 @@ - + + + - \ No newline at end of file + diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml b/samples/ControlCatalog/Pages/MenuPage.xaml index 296cfa8704..6eeb86a00f 100644 --- a/samples/ControlCatalog/Pages/MenuPage.xaml +++ b/samples/ControlCatalog/Pages/MenuPage.xaml @@ -7,29 +7,44 @@ Margin="0,16,0,0" HorizontalAlignment="Center" Spacing="16"> - - - - - - - + + Defined in XAML + + + + + + + + + + + + + + + + + + - - - - + + - - - - - - - - - - + + + + + Dyanamically generated + + + + + + - \ No newline at end of file + diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml.cs b/samples/ControlCatalog/Pages/MenuPage.xaml.cs index d637c172e1..880d4bc59a 100644 --- a/samples/ControlCatalog/Pages/MenuPage.xaml.cs +++ b/samples/ControlCatalog/Pages/MenuPage.xaml.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Avalonia.Controls; using Avalonia.Markup.Xaml; @@ -8,6 +9,27 @@ namespace ControlCatalog.Pages public MenuPage() { this.InitializeComponent(); + DataContext = new[] + { + new MenuItemViewModel + { + Header = "_File", + Items = + { + new MenuItemViewModel { Header = "_Open..." }, + new MenuItemViewModel { Header = "Save" }, + } + }, + new MenuItemViewModel + { + Header = "_Edit", + Items = + { + new MenuItemViewModel { Header = "_Copy" }, + new MenuItemViewModel { Header = "_Paste" }, + } + } + }; } private void InitializeComponent() @@ -15,4 +37,10 @@ namespace ControlCatalog.Pages AvaloniaXamlLoader.Load(this); } } + + public class MenuItemViewModel + { + public string Header { get; set; } + public IList Items { get; } = new List(); + } } From b44900395800eec65d3fc1b7b6bcef8152638a43 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 12 Sep 2018 15:21:14 +0200 Subject: [PATCH 2/2] Allow MenuItems to be separators. If `MenuItem.Header == "-"` then apply the `:separator` pseudoclass to the `MenuItem` and display it as a separator. --- samples/ControlCatalog/Pages/MenuPage.xaml.cs | 16 ++++++++++++--- src/Avalonia.Controls/MenuItem.cs | 20 +++++++++++++++---- src/Avalonia.Themes.Default/MenuItem.xaml | 12 ++++++++++- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml.cs b/samples/ControlCatalog/Pages/MenuPage.xaml.cs index 880d4bc59a..01add3e76e 100644 --- a/samples/ControlCatalog/Pages/MenuPage.xaml.cs +++ b/samples/ControlCatalog/Pages/MenuPage.xaml.cs @@ -14,16 +14,26 @@ namespace ControlCatalog.Pages new MenuItemViewModel { Header = "_File", - Items = + Items = new[] { new MenuItemViewModel { Header = "_Open..." }, new MenuItemViewModel { Header = "Save" }, + new MenuItemViewModel { Header = "-" }, + new MenuItemViewModel + { + Header = "Recent", + Items = new[] + { + new MenuItemViewModel { Header = "File1.txt" }, + new MenuItemViewModel { Header = "File2.txt" }, + } + }, } }, new MenuItemViewModel { Header = "_Edit", - Items = + Items = new[] { new MenuItemViewModel { Header = "_Copy" }, new MenuItemViewModel { Header = "_Paste" }, @@ -41,6 +51,6 @@ namespace ControlCatalog.Pages public class MenuItemViewModel { public string Header { get; set; } - public IList Items { get; } = new List(); + public IList Items { get; set; } } } diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs index 7b57783c5a..03a43b5164 100644 --- a/src/Avalonia.Controls/MenuItem.cs +++ b/src/Avalonia.Controls/MenuItem.cs @@ -105,6 +105,7 @@ namespace Avalonia.Controls ClickEvent.AddClassHandler(x => x.OnClick); SubmenuOpenedEvent.AddClassHandler(x => x.OnSubmenuOpened); IsSubMenuOpenProperty.Changed.AddClassHandler(x => x.SubMenuOpenChanged); + PseudoClass(HeaderProperty, x => x as string == "-", ":separator"); } public MenuItem() @@ -357,10 +358,21 @@ namespace Avalonia.Controls { base.OnTemplateApplied(e); - _popup = e.NameScope.Get("PART_Popup"); - _popup.DependencyResolver = DependencyResolver.Instance; - _popup.Opened += PopupOpened; - _popup.Closed += PopupClosed; + if (_popup != null) + { + _popup.Opened -= PopupOpened; + _popup.Closed -= PopupClosed; + _popup.DependencyResolver = null; + } + + _popup = e.NameScope.Find("PART_Popup"); + + if (_popup != null) + { + _popup.DependencyResolver = DependencyResolver.Instance; + _popup.Opened += PopupOpened; + _popup.Closed += PopupClosed; + } } /// diff --git a/src/Avalonia.Themes.Default/MenuItem.xaml b/src/Avalonia.Themes.Default/MenuItem.xaml index 8a2ed2a802..07faf7a632 100644 --- a/src/Avalonia.Themes.Default/MenuItem.xaml +++ b/src/Avalonia.Themes.Default/MenuItem.xaml @@ -73,7 +73,17 @@ - + + +