Browse Source

Merge pull request #5848 from MarchingCube/menuitem-staysopen

Implement MenuItem.StaysOpenOnClick.
Dariusz Komosiński 4 years ago
parent
commit
0ff3337c68

+ 1 - 0
samples/ControlCatalog/Pages/ContextMenuPage.xaml

@@ -31,6 +31,7 @@
                                 <CheckBox BorderThickness="0" IsHitTestVisible="False" IsChecked="True"/>
                             </MenuItem.Icon>
                         </MenuItem>
+                        <MenuItem Header="Menu Item that won't close on click" StaysOpenOnClick="True" />
                     </ContextMenu>
                 </Border.ContextMenu>
                 <TextBlock Text="Defined in XAML"/>

+ 4 - 1
src/Avalonia.Controls/ApiCompatBaseline.txt

@@ -1,4 +1,7 @@
 Compat issues with assembly Avalonia.Controls:
+InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Controls.IMenuItem.StaysOpenOnClick' is present in the implementation but not in the contract.
+InterfacesShouldHaveSameMembers : Interface member 'public System.Boolean Avalonia.Controls.IMenuItem.StaysOpenOnClick.get()' is present in the implementation but not in the contract.
+InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.IMenuItem.StaysOpenOnClick.set(System.Boolean)' is present in the implementation but not in the contract.
 InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.INativeMenuExporterEventsImplBridge.RaiseClosed()' is present in the implementation but not in the contract.
 InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Controls.INativeMenuExporterEventsImplBridge.RaiseOpening()' is present in the implementation but not in the contract.
 MembersMustExist : Member 'public void Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract.
@@ -7,4 +10,4 @@ EnumValuesMustMatch : Enum value 'Avalonia.Platform.ExtendClientAreaChromeHints
 InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.ICursorImpl)' is present in the implementation but not in the contract.
 InterfacesShouldHaveSameMembers : Interface member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' is present in the contract but not in the implementation.
 MembersMustExist : Member 'public void Avalonia.Platform.ITopLevelImpl.SetCursor(Avalonia.Platform.IPlatformHandle)' does not exist in the implementation but it does exist in the contract.
-Total Issues: 7
+Total Issues: 11

+ 6 - 0
src/Avalonia.Controls/IMenuItem.cs

@@ -23,6 +23,12 @@ namespace Avalonia.Controls
         /// </summary>
         bool IsSubMenuOpen { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value that indicates the submenu that this <see cref="MenuItem"/> is
+        /// within should not close when this item is clicked.
+        /// </summary>
+        bool StaysOpenOnClick { get; set; }
+
         /// <summary>
         /// Gets a value that indicates whether the <see cref="MenuItem"/> is a top-level main menu item.
         /// </summary>

+ 16 - 0
src/Avalonia.Controls/MenuItem.cs

@@ -69,6 +69,12 @@ namespace Avalonia.Controls
         public static readonly StyledProperty<bool> IsSubMenuOpenProperty =
             AvaloniaProperty.Register<MenuItem, bool>(nameof(IsSubMenuOpen));
 
+        /// <summary>
+        /// Defines the <see cref="StaysOpenOnClick"/> property.
+        /// </summary>
+        public static readonly StyledProperty<bool> StaysOpenOnClickProperty =
+            AvaloniaProperty.Register<MenuItem, bool>(nameof(StaysOpenOnClick));
+
         /// <summary>
         /// Defines the <see cref="Click"/> event.
         /// </summary>
@@ -265,6 +271,16 @@ namespace Avalonia.Controls
             set { SetValue(IsSubMenuOpenProperty, value); }
         }
 
+        /// <summary>
+        /// Gets or sets a value that indicates the submenu that this <see cref="MenuItem"/> is
+        /// within should not close when this item is clicked.
+        /// </summary>
+        public bool StaysOpenOnClick
+        {
+            get { return GetValue(StaysOpenOnClickProperty); }
+            set { SetValue(StaysOpenOnClickProperty, value); }
+        }
+
         /// <summary>
         /// Gets or sets a value that indicates whether the <see cref="MenuItem"/> has a submenu.
         /// </summary>

+ 5 - 1
src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

@@ -449,7 +449,11 @@ namespace Avalonia.Controls.Platform
         protected void Click(IMenuItem item)
         {
             item.RaiseClick();
-            CloseMenu(item);
+
+            if (!item.StaysOpenOnClick)
+            {
+                CloseMenu(item);
+            }
         }
 
         protected void CloseMenu(IMenuItem item)