From 1eb62cf4dc2c065a75ac12708c0d932b06f92d8f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 5 Jun 2015 01:04:18 +0200 Subject: [PATCH] Implement click on MenuItem. --- Perspex.Application/Application.cs | 2 + Perspex.Controls/IMenu.cs | 2 + Perspex.Controls/Menu.cs | 8 ++++ Perspex.Controls/MenuItem.cs | 61 ++++++++++++++++++++++++++---- TestApplication/Program.cs | 4 ++ 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/Perspex.Application/Application.cs b/Perspex.Application/Application.cs index 2639a17455..681f4abb64 100644 --- a/Perspex.Application/Application.cs +++ b/Perspex.Application/Application.cs @@ -42,6 +42,8 @@ namespace Perspex /// private Styler styler = new Styler(); + private ICloseable mainWindow; + /// /// Initializes a new instance of the class. /// diff --git a/Perspex.Controls/IMenu.cs b/Perspex.Controls/IMenu.cs index 47fde58012..5ccc53902b 100644 --- a/Perspex.Controls/IMenu.cs +++ b/Perspex.Controls/IMenu.cs @@ -11,5 +11,7 @@ namespace Perspex.Controls void ChildPointerEnter(MenuItem item); void ChildSubMenuOpened(MenuItem item); + + void CloseMenu(); } } diff --git a/Perspex.Controls/Menu.cs b/Perspex.Controls/Menu.cs index a040598f15..ca0538640d 100644 --- a/Perspex.Controls/Menu.cs +++ b/Perspex.Controls/Menu.cs @@ -46,6 +46,14 @@ namespace Perspex.Controls } } + void IMenu.CloseMenu() + { + foreach (MenuItem i in this.GetLogicalChildren()) + { + i.IsSubMenuOpen = false; + } + } + protected override void OnAttachedToVisualTree(IRenderRoot root) { base.OnAttachedToVisualTree(root); diff --git a/Perspex.Controls/MenuItem.cs b/Perspex.Controls/MenuItem.cs index fb67c40d68..a56f535f30 100644 --- a/Perspex.Controls/MenuItem.cs +++ b/Perspex.Controls/MenuItem.cs @@ -13,6 +13,7 @@ namespace Perspex.Controls using Perspex.Input; using Perspex.LogicalTree; using Perspex.VisualTree; + using Perspex.Interactivity; public class MenuItem : HeaderedItemsControl, IMenu { @@ -28,11 +29,21 @@ namespace Perspex.Controls public static readonly PerspexProperty IsSubMenuOpenProperty = PerspexProperty.Register("IsSubMenuOpen"); + public static readonly RoutedEvent ClickEvent = + RoutedEvent.Register("Click", RoutingStrategies.Bubble); + static MenuItem() { + ClickEvent.AddClassHandler(x => x.OnClick); IsSubMenuOpenProperty.Changed.Subscribe(SubMenuOpenChanged); } + public event EventHandler Click + { + add { this.AddHandler(ClickEvent, value); } + remove { this.RemoveHandler(ClickEvent, value); } + } + public ICommand Command { get { return this.GetValue(CommandProperty); } @@ -69,6 +80,20 @@ namespace Perspex.Controls } } + void IMenu.CloseMenu() + { + this.IsSubMenuOpen = false; + this.GetParentMenu().CloseMenu(); + } + + protected virtual void OnClick(RoutedEventArgs e) + { + if (this.Command != null) + { + this.Command.Execute(this.CommandParameter); + } + } + protected override void OnPointerEnter(PointerEventArgs e) { base.OnPointerEnter(e); @@ -79,12 +104,38 @@ namespace Perspex.Controls { base.OnPointerPressed(e); - if (!this.Classes.Contains(":empty")) + if (this.Classes.Contains(":empty")) + { + RoutedEventArgs click = new RoutedEventArgs + { + RoutedEvent = ClickEvent, + }; + + this.RaiseEvent(click); + this.GetParentMenu().CloseMenu(); + } + else { this.IsSubMenuOpen = !this.IsSubMenuOpen; } } + private IMenu GetParentMenu() + { + var parent = this.GetLogicalParent(); + + if (parent != null) + { + return parent; + } + else + { + var popupRoot = this.GetVisualAncestors().OfType().FirstOrDefault(); + var parentItem = ((ILogical)popupRoot).GetLogicalParent().TemplatedParent; + return (IMenu)parentItem; + } + } + private void OnSubMenuOpenChanged(bool open) { if (!open && this.Items != null) @@ -96,13 +147,7 @@ namespace Perspex.Controls } else if (open) { - var root = this.GetVisualAncestors().OfType().FirstOrDefault(); - - if (root != null) - { - var parentItem = ((ILogical)root).GetLogicalParent().TemplatedParent; - (parentItem as IMenu)?.ChildSubMenuOpened(this); - } + this.GetParentMenu().ChildSubMenuOpened(this); } } diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs index 048579d6b6..4146c6a7a3 100644 --- a/TestApplication/Program.cs +++ b/TestApplication/Program.cs @@ -117,6 +117,9 @@ namespace TestApplication TextBlock fps; + var testCommand = ReactiveCommand.Create(); + testCommand.Subscribe(_ => System.Diagnostics.Debug.WriteLine("Test command executed.")); + Window window = new Window { Title = "Perspex Test Application", @@ -181,6 +184,7 @@ namespace TestApplication new MenuItem { Header = "Exit", + Command = testCommand, }, } },