diff --git a/dev/MenuBar/MenuBar.cpp b/dev/MenuBar/MenuBar.cpp index 65b889095a..40d90b2dab 100644 --- a/dev/MenuBar/MenuBar.cpp +++ b/dev/MenuBar/MenuBar.cpp @@ -26,11 +26,6 @@ winrt::AutomationPeer MenuBar::OnCreateAutomationPeer() void MenuBar::OnApplyTemplate() { SetUpTemplateParts(); - - for (auto const& menuBarItem : Items()) - { - winrt::get_self(menuBarItem)->AddPassThroughElement(m_layoutRoot.get()); - } } void MenuBar::SetUpTemplateParts() @@ -54,6 +49,12 @@ void MenuBar::SetUpTemplateParts() } } +void MenuBar::RequestPassThroughElement(const winrt::Microsoft::UI::Xaml::Controls::MenuBarItem& menuBarItem) +{ + // To enable switching flyout on hover, every menubar item needs the MenuBar root to include it for hit detection with flyouts open + winrt::get_self(menuBarItem)->AddPassThroughElement(m_layoutRoot.get()); +} + void MenuBar::IsFlyoutOpen(bool state) { m_isFlyoutOpen = state; diff --git a/dev/MenuBar/MenuBar.h b/dev/MenuBar/MenuBar.h index 0443105ea5..6937bebfe9 100644 --- a/dev/MenuBar/MenuBar.h +++ b/dev/MenuBar/MenuBar.h @@ -18,6 +18,8 @@ class MenuBar : bool IsFlyoutOpen() { return m_isFlyoutOpen; }; void IsFlyoutOpen(bool state); + void RequestPassThroughElement(const winrt::Microsoft::UI::Xaml::Controls::MenuBarItem& menuBarItem); + public: // IUIElement / IUIElementOverridesHelper winrt::AutomationPeer OnCreateAutomationPeer(); diff --git a/dev/MenuBar/MenuBarItem.cpp b/dev/MenuBar/MenuBarItem.cpp index 2b5de81e03..6479bd183f 100644 --- a/dev/MenuBar/MenuBarItem.cpp +++ b/dev/MenuBar/MenuBarItem.cpp @@ -36,15 +36,17 @@ void MenuBarItem::OnApplyTemplate() { m_button.set(GetTemplateChildT(L"ContentButton", *this)); - PopulateContent(); - DetachEventHandlers(); - AttachEventHandlers(); - auto menuBar = SharedHelpers::GetAncestorOfType(winrt::VisualTreeHelper::GetParent(*this)); if (menuBar) { m_menuBar = winrt::make_weak(menuBar); + // Ask parent MenuBar for its root to enable pass through + winrt::get_self(menuBar)->RequestPassThroughElement(*this); } + + PopulateContent(); + DetachEventHandlers(); + AttachEventHandlers(); } void MenuBarItem::PopulateContent() diff --git a/dev/MenuBar/MenuBar_InteractionTests/MenuBarTests.cs b/dev/MenuBar/MenuBar_InteractionTests/MenuBarTests.cs index 3eac105f27..3c20da119f 100644 --- a/dev/MenuBar/MenuBar_InteractionTests/MenuBarTests.cs +++ b/dev/MenuBar/MenuBar_InteractionTests/MenuBarTests.cs @@ -307,6 +307,49 @@ public void MenuBarHeightTest() } } + [TestMethod] + public void HoveringBehaviorTest() + { + // Overlay pass through element is only available from IFlyoutBase3 forward + // On OS versions below RS5 test is unreliable/not working. + // Tracked by https://github.com/Microsoft/microsoft-ui-xaml/issues/115 + if (PlatformConfiguration.IsDevice(DeviceType.Phone) + || !ApiInformation.IsTypePresent("Windows.UI.Xaml.Controls.Primitives.IFlyoutBase3") + || PlatformConfiguration.IsOSVersionLessThan(OSVersion.Redstone4)) + { + Log.Comment("Skipping tests on phone, because menubar is not supported."); + return; + } + using (var setup = new TestSetupHelper("MenuBar Tests")) + { + var menuBar = FindElement.ById("SizedMenuBar"); + var addButton = FindElement.ByName("AddItemsToEmptyMenuBar"); + + addButton.Click(); + addButton.Click(); + addButton.Click(); + + var help0 = FindElement.ByName