Add OpenMenu() method to MenuBar for dropdown list support

Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-11-22 01:39:11 +00:00
parent adb5a3167b
commit 40e777acc1
2 changed files with 100 additions and 0 deletions

View File

@@ -225,6 +225,30 @@ public class MenuBar : Menu, IDesignable
/// <exception cref="NotImplementedException"></exception>
public bool IsOpen () { return SubViews.OfType<MenuBarItem> ().Count (sv => sv is { PopoverMenuOpen: true }) > 0; }
/// <summary>
/// Opens the first menu item with a <see cref="PopoverMenu"/>. This is useful for programmatically opening
/// the menu, for example when using the MenuBar as a dropdown list.
/// </summary>
/// <returns><see langword="true"/> if a menu was opened; <see langword="false"/> otherwise.</returns>
/// <remarks>
/// <para>
/// This method activates the MenuBar and shows the first MenuBarItem that has a PopoverMenu.
/// The first menu item in the PopoverMenu will be selected and focused.
/// </para>
/// </remarks>
public bool OpenMenu ()
{
if (SubViews.OfType<MenuBarItem> ().FirstOrDefault (mbi => mbi.PopoverMenu is { }) is { } first)
{
Active = true;
ShowItem (first);
return true;
}
return false;
}
private bool _active;
/// <summary>

View File

@@ -718,4 +718,80 @@ public class MenuBarTests ()
Application.End (rs);
top.Dispose ();
}
[Fact]
[AutoInitShutdown]
public void OpenMenu_Opens_First_MenuBarItem ()
{
// Arrange
var top = new Toplevel ()
{
App = ApplicationImpl.Instance
};
var menuBar = new MenuBar () { Id = "menuBar" };
top.Add (menuBar);
var menuItem1 = new MenuItem { Id = "menuItem1", Title = "Item _1" };
var menuItem2 = new MenuItem { Id = "menuItem2", Title = "Item _2" };
var menu = new Menu ([menuItem1, menuItem2]) { Id = "menu" };
var menuBarItem = new MenuBarItem { Id = "menuBarItem", Title = "_File" };
var menuBarItemPopover = new PopoverMenu ();
menuBar.Add (menuBarItem);
menuBarItem.PopoverMenu = menuBarItemPopover;
menuBarItemPopover.Root = menu;
SessionToken rs = Application.Begin (top);
Assert.False (menuBar.Active);
Assert.False (menuBar.IsOpen ());
// Act
bool result = menuBar.OpenMenu ();
// Assert
Assert.True (result);
Assert.True (menuBar.Active);
Assert.True (menuBar.IsOpen ());
Assert.True (menuBar.CanFocus);
Assert.True (menuBarItem.PopoverMenu.Visible);
Assert.True (menuBarItem.PopoverMenu.HasFocus);
Assert.Equal (menuItem1, menu.SelectedMenuItem);
Application.End (rs);
top.Dispose ();
}
[Fact]
[AutoInitShutdown]
public void OpenMenu_Returns_False_When_No_MenuBarItem_With_PopoverMenu ()
{
// Arrange
var top = new Toplevel ()
{
App = ApplicationImpl.Instance
};
var menuBar = new MenuBar () { Id = "menuBar" };
top.Add (menuBar);
var menuBarItem = new MenuBarItem { Id = "menuBarItem", Title = "_File" };
menuBar.Add (menuBarItem);
// Note: No PopoverMenu set
SessionToken rs = Application.Begin (top);
Assert.False (menuBar.Active);
Assert.False (menuBar.IsOpen ());
// Act
bool result = menuBar.OpenMenu ();
// Assert
Assert.False (result);
Assert.False (menuBar.Active);
Assert.False (menuBar.IsOpen ());
Application.End (rs);
top.Dispose ();
}
}