diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue34038.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue34038.cs new file mode 100644 index 000000000000..07dc7fe3c46c --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue34038.cs @@ -0,0 +1,129 @@ +namespace Controls.TestCases.HostApp.Issues; + +[Issue(IssueTracker.Github, 34038, "[macOS] IsEnabled property false not working on MenuBarItem", PlatformAffected.macOS | PlatformAffected.UWP)] +public class Issue34038 : Shell +{ + public Issue34038() + { + // Disable flyout to hide hamburger menu + FlyoutBehavior = FlyoutBehavior.Disabled; + + // Register routes + Routing.RegisterRoute("testpage", typeof(Issue34038TestPage)); + + // Landing page with navigation button + var navigateButton = new Button + { + Text = "Go to Issue34038 Test", + AutomationId = "Issue34038NavigateButton" + }; + + navigateButton.Clicked += async (sender, e) => + { + await Shell.Current.GoToAsync("testpage", animate: false); + }; + + var landingPage = new ContentPage + { + Title = "Issue34038", + Content = new VerticalStackLayout + { + Padding = new Thickness(20), + Spacing = 12, + Children = + { + new Label { Text = "MenuBarItem IsEnabled Test" }, + navigateButton + } + } + }; + + // Add the landing page to the Shell structure directly + var shellItem = new ShellItem(); + var shellSection = new ShellSection(); + var shellContent = new ShellContent + { + Content = landingPage, + Title = "Main", + Route = "Main" + }; + + shellSection.Items.Add(shellContent); + shellItem.Items.Add(shellSection); + Items.Add(shellItem); + } +} + +// Test page with MenuBarItem IsEnabled functionality +public class Issue34038TestPage : ContentPage +{ + const string InitialStatus = "Failure"; + + MenuBarItem _menuBarItem; + Label _statusLabel; + + public Issue34038TestPage() + { + Title = "MenuBarItem IsEnabled Test"; + + // MenuBarItem IsEnabled test setup + _menuBarItem = new MenuBarItem + { + Text = "Issue34038MenuBarItem", + AutomationId = "Issue34038MenuBarItem", + IsEnabled = false + }; + + var flyoutItem = new MenuFlyoutItem + { + Text = "Issue34038MenuFlyoutItem", + AutomationId = "Issue34038MenuFlyoutItem" + }; + + flyoutItem.Clicked += (_, _) => _statusLabel.Text = "Success"; + _menuBarItem.Add(flyoutItem); + MenuBarItems.Add(_menuBarItem); + + _statusLabel = new Label + { + AutomationId = "Issue34038StatusLabel", + Text = InitialStatus + }; + + var isEnabledSwitch = new Switch + { + AutomationId = "Issue34038MenuEnabledSwitch", + IsToggled = false + }; + + _menuBarItem.IsEnabled = isEnabledSwitch.IsToggled; + isEnabledSwitch.Toggled += (_, e) => _menuBarItem.IsEnabled = e.Value; + + var instructions = new Label + { + Text = "Toggle the switch off and verify the menu bar item cannot be opened.", + LineBreakMode = LineBreakMode.WordWrap + }; + + Content = new VerticalStackLayout + { + Padding = new Thickness(20), + Spacing = 12, + Children = + { + new Label { Text = "MenuBarItem IsEnabled regression test" }, + instructions, + new HorizontalStackLayout + { + Spacing = 10, + Children = + { + new Label { Text = "MenuBarItem IsEnabled" }, + isEnabledSwitch + } + }, + _statusLabel + } + }; + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34038.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34038.cs new file mode 100644 index 000000000000..f160e2f945f3 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34038.cs @@ -0,0 +1,55 @@ +#if MACCATALYST || WINDOWS //MenuBarItem is only supported on macOS and UWP +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue34038 : _IssuesUITest +{ + const string MenuEnabledSwitch = "Issue34038MenuEnabledSwitch"; + const string MenuBarItemText = "Issue34038MenuBarItem"; + const string MenuFlyoutItemText = "Issue34038MenuFlyoutItem"; + const string StatusLabel = "Issue34038StatusLabel"; + + public Issue34038(TestDevice device) : base(device) + { + } + + public override string Issue => "[macOS] IsEnabled property false not working on MenuBarItem"; + + [Test] + [Category(UITestCategories.Shell)] + public void DisabledMenuBarItemCannotBeOpenedOrExecuted() + { + // Navigate to test page + App.WaitForElement("Issue34038NavigateButton"); + App.Tap("Issue34038NavigateButton"); + +#if WINDOWS + Assert.That(App.WaitForElement(StatusLabel).GetText(), Is.EqualTo("Failure")); + App.Click(MenuBarItemText); + App.WaitForNoElement(MenuFlyoutItemText); + Assert.That(App.WaitForElement(StatusLabel).GetText(), Is.EqualTo("Failure")); + App.WaitForElement(MenuEnabledSwitch); + App.Tap(MenuEnabledSwitch); + App.Click(MenuBarItemText); + App.Click(MenuFlyoutItemText); +#else + App.WaitForElement(MenuBarItemText); + App.Tap(MenuBarItemText); + App.WaitForElement(MenuFlyoutItemText); + App.Tap(MenuFlyoutItemText); + Assert.That(App.WaitForElement(StatusLabel).GetText(), Is.EqualTo("Failure")); + App.Tap(MenuBarItemText); + App.WaitForElement(MenuEnabledSwitch); + App.Tap(MenuEnabledSwitch); + App.WaitForElement(MenuBarItemText); + App.Tap(MenuBarItemText); + App.WaitForElement(MenuFlyoutItemText); + App.Tap(MenuFlyoutItemText); +#endif + Assert.That(App.WaitForElement(StatusLabel).GetText(), Is.EqualTo("Success")); + } +} +#endif \ No newline at end of file diff --git a/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs b/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs index 66d0c75e0f0b..9fcf477b7eb3 100644 --- a/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs +++ b/src/Core/src/Platform/iOS/MauiUIApplicationDelegate.Menu.cs @@ -94,6 +94,32 @@ public override bool CanPerform(Selector action, NSObject? withSender) return base.CanPerform(action, withSender); } + [SupportedOSPlatform("ios13.0")] + public override void ValidateCommand(UICommand command) + { + if (command.PropertyList is NSString nsString && + int.TryParse(nsString.ToString(), out int index) && + MenuFlyoutItemHandler.menus.TryGetValue(index, out var menuElement)) + { + bool isEnabled = menuElement.IsEnabled; + + // Check if the parent MenuBarItem is disabled + if (isEnabled && menuElement is IElement element) + { + var parent = element.Parent; + if (parent is IMenuBarItem menuBarItem && !menuBarItem.IsEnabled) + isEnabled = false; + } + + command.Attributes = isEnabled + ? (UIMenuElementAttributes)0 + : UIMenuElementAttributes.Disabled; + return; + } + + base.ValidateCommand(command); + } + [SupportedOSPlatform("ios13.0")] [Export(KeyboardAcceleratorExtensions.MenuItemSelectedSelector)] #pragma warning disable CA1822 // Selectors can't be static, or else it won't be found diff --git a/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt index 5c1566d8921d..1fa860393666 100644 --- a/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt +++ b/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt @@ -3,6 +3,7 @@ override Microsoft.Maui.Handlers.LabelHandler.GetDesiredSize(double widthConstra override Microsoft.Maui.Handlers.ProgressBarHandler.NeedsContainer.get -> bool override Microsoft.Maui.Handlers.ShapeViewHandler.GetDesiredSize(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size override Microsoft.Maui.Handlers.StepperHandler.GetDesiredSize(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +override Microsoft.Maui.MauiUIApplicationDelegate.ValidateCommand(UIKit.UICommand! command) -> void override Microsoft.Maui.Platform.MauiTextField.LayoutSubviews() -> void override Microsoft.Maui.Platform.NoCaretField.LayoutSubviews() -> void override Microsoft.Maui.Platform.MauiTextView.TextAlignment.get -> UIKit.UITextAlignment diff --git a/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt index 613bfa9ea3a9..3b0af94c6312 100644 --- a/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt +++ b/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt @@ -3,6 +3,7 @@ override Microsoft.Maui.Handlers.LabelHandler.GetDesiredSize(double widthConstra override Microsoft.Maui.Handlers.ProgressBarHandler.NeedsContainer.get -> bool override Microsoft.Maui.Handlers.ShapeViewHandler.GetDesiredSize(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size override Microsoft.Maui.Handlers.StepperHandler.GetDesiredSize(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +override Microsoft.Maui.MauiUIApplicationDelegate.ValidateCommand(UIKit.UICommand! command) -> void override Microsoft.Maui.Platform.MauiTextView.TextAlignment.get -> UIKit.UITextAlignment override Microsoft.Maui.Platform.MauiTextView.TextAlignment.set -> void override Microsoft.Maui.Platform.MauiView.DidUpdateFocus(UIKit.UIFocusUpdateContext! context, UIKit.UIFocusAnimationCoordinator! coordinator) -> void