Skip to content

[Windows] Fix for Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty#30382

Merged
kubaflo merged 9 commits into
dotnet:inflight/currentfrom
BagavathiPerumal:fix-30254
Apr 13, 2026
Merged

[Windows] Fix for Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty#30382
kubaflo merged 9 commits into
dotnet:inflight/currentfrom
BagavathiPerumal:fix-30254

Conversation

@BagavathiPerumal

@BagavathiPerumal BagavathiPerumal commented Jul 2, 2025

Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Root cause

The root cause of this issue is that the Windows Shell implementation always reserves space for the header area when Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or header content. The NavigationView control allocates a fixed height above the tab bar for the header region without checking if the current page actually needs this space. This results in an unwanted gap between the flyout toggle area and the tab bar when navigating to pages with empty titles, creating visual inconsistency compared to FlyoutBehavior="Disabled" mode where no header space is reserved for empty content.

Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell implementation to remove unwanted space above the tab bar in flyout mode. The implementation introduces three key methods in RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header visibility requirements, IsHeaderContentEmpty() to determine if the toolbar contains no title or title view when in flyout mode, and CollapseEmptyHeader() to properly hide empty headers. The toolbar property setter now calls UpdateHeaderVisibility() when the toolbar changes, and ShellView.cs triggers header visibility updates during tab navigation. This ensures empty headers don't occupy unnecessary space in flyout mode while maintaining normal behavior when headers contain content, resolving the spacing issue above the tab bar when switching between pages in Shell applications on Windows.

Tested the behavior in the following platforms.

  • Windows
  • Mac
  • iOS
  • Android

Issues Fixed

Fixes #30254

Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a title. So, resaved the test snapshot based on the fix.

  1. ShellFlowDirectionUpdate
  2. VerifyFlyoutBackgroundColor
  3. VerifyHamburgerIcon
  4. Issue23834FlyoutMisbehavior

Output

Before Issue Fix After Issue Fix
BeforeFix.Header.mp4
AfterFix.Header.mp4

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Jul 2, 2025
@jsuarezruiz jsuarezruiz added the area-controls-shell Shell Navigation, Routes, Tabs, Flyout label Jul 3, 2025
@BagavathiPerumal BagavathiPerumal marked this pull request as ready for review July 3, 2025 12:49
Copilot AI review requested due to automatic review settings July 3, 2025 12:49
@BagavathiPerumal BagavathiPerumal requested a review from a team as a code owner July 3, 2025 12:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes an issue on Windows where Shell.FlyoutBehavior="Flyout" would always reserve header space above the tab bar even when the page title is empty. It adds logic to detect empty headers and collapse them, and ensures this logic runs on toolbar updates and tab navigation. A new UI test for the empty-title scenario is also included.

  • Introduces UpdateHeaderVisibility, IsHeaderContentEmpty, and CollapseEmptyHeader in RootNavigationView to hide empty headers.
  • Hooks UpdateHeaderVisibility into toolbar changes and tab selection in ShellView.
  • Adds a UITest (Issue30254) and corresponding HostApp page to cover the empty-title behavior.

Reviewed Changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated no comments.

File Description
src/Core/src/Platform/Windows/RootNavigationView.cs Adds header-visibility methods and calls on toolbar change
src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs Calls header-visibility update after tab selection
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30254.cs Adds shared UITest for empty-title header hiding
src/Controls/tests/TestCases.HostApp/Issues/Issue30254.cs Adds HostApp Shell page with empty and non-empty title cases
Comments suppressed due to low confidence (2)

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30254.cs:19

  • The test covers the empty-title scenario but does not verify that the header reappears when navigating to a page with a non-empty title. Consider adding steps (e.g., tapping the second tab) and assertions to confirm the header is shown for the "With Title" case.
		App.WaitForElement("MainPageButton");

src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs:279

  • The method UpdateHeaderVisibility() is not defined in ShellView. You need to call the new method on the RootNavigationView instance (for example, sender.UpdateHeaderVisibility() or using a stored reference to the navigation view), otherwise this will not compile or have no effect.
			UpdateHeaderVisibility();

@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).


[Test]
[Category(UITestCategories.Shell)]
public void ShouldHideHeaderWhenTitleEmpty()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending snapshots on Mac and Windows.
Already available in the latest build.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsuarezruiz, I have successfully added snapshots for Mac and Windows.

@Deus-nsf

Copy link
Copy Markdown

Oh waw, thanks so much for sharing a solution to this issue, that was surprisingly fast! Hopefully the code has no issues and the pull request will be accepted :)

@jsuarezruiz

Copy link
Copy Markdown
Contributor

/rebase

@github-actions

github-actions Bot commented Dec 10, 2025

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 30382

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 30382"

@Deus-nsf

Copy link
Copy Markdown

Coming back to this after 6 months, hopefully there can be progress and attention on this issue, as iterating frontend design is much faster on Windows (due to build times), and having to account for the space offset when designing a page is not very intuitive.

@sheiksyedm

Copy link
Copy Markdown
Contributor

/rebase

@Deus-nsf

Copy link
Copy Markdown

Noooo the azure unit tests failed!

@MauiBot

MauiBot commented Mar 21, 2026

Copy link
Copy Markdown
Collaborator

🤖 AI Summary

📊 Expand Full Reviewd87d994 · fix-30254-Snapshot updated.
🔍 Pre-Flight — Context & Validation

Issue: #30254 - (Windows) Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty
PR: #30382 - [Windows] Fix for Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty
Platforms Affected: Windows (primary); test snapshots also added for iOS, Android, macCatalyst
Files Changed: 2 implementation, 11 test (4 modified snapshots + 6 new/modified snapshots + 2 new test files)

Key Findings

  • The fix adds UpdateHeaderVisibility() to RootNavigationView (59 lines) that evaluates whether header content is empty and collapses it by setting Header = null
  • ShellView.TabSelectionChanged is expanded to also call UpdateHeaderVisibility() on tab switch
  • UpdateHeaderVisibility() uses fragile string-based FindName("menuContent") and FindName("titleIcon") lookups for template parts
  • PaneDisplayModeChanged callback does NOT call UpdateHeaderVisibility() — meaning if FlyoutBehavior changes at runtime, the header state won't update
  • Dynamic page title changes (without tab switch) won't trigger a header update
  • 5 existing test snapshots were modified: ShellFlowDirectionUpdate, VerifyFlyoutBackgroundColor, VerifyHamburgerIcon, Issue23834FlyoutMisbehavior, VerifyFlyoutContentHasNoDefaultCornerRadius — the PR explains these pages had empty titles, so fix removed the extra space
  • Test only verifies the initial empty-title state; does not test switching between tabs with/without titles
  • Test is marked PlatformAffected.UWP but runs on all platforms via the Shell category

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #30382 Collapse header via Header = null + InvalidateMeasure() when title/content empty in LeftMinimal mode ✅ PASSED (Gate) RootNavigationView.cs, ShellView.cs Uses FindName for template part detection

🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix (claude-opus-4.6) Toolbar Self-Managed Visibility — MauiToolbar updates its own Visibility; RootNavigationView reacts via callback ✅ PASS MauiToolbar.xaml.cs, RootNavigationView.cs No ShellView.cs changes needed; encapsulates in MauiToolbar
2 try-fix (claude-sonnet-4.6) Inline check in UpdateToolbarPlacement() — conditional Header = HasNoToolbarContent() ? null : Toolbar; ShellView calls UpdateToolbarPlacement() on tab switch ✅ PASS RootNavigationView.cs, ShellView.cs Same 2 files as PR but different structure; no separate methods
3 try-fix (gpt-5.3-codex) Collapse HeaderContent template part visibility directly when header is empty in LeftMinimal ✅ PASS RootNavigationView.cs, ShellView.cs Manipulates HeaderContent visibility instead of nulling Header
4 try-fix (gpt-5.4) Reactive subscription in MauiNavigationView/MauiToolbar — auto-recomputes Header on PropertyChanged for Title/TitleView ✅ PASS MauiNavigationView.cs, MauiToolbar.xaml.cs, RootNavigationView.cs Most automatic; handles dynamic title changes; most complex
5 try-fix (claude-sonnet-4.6) AlwaysShowHeader = false + conditional Header = null — WinUI native collapse, no InvalidateMeasure() needed ✅ PASS RootNavigationView.cs, ShellView.cs Most idiomatic WinUI approach; simplest fix
PR PR #30382 UpdateHeaderVisibility() with Header = null + InvalidateMeasure(); IsHeaderContentEmpty() uses FindName template detection ✅ PASSED (Gate) RootNavigationView.cs, ShellView.cs Uses FindName string lookups; adds tab-change hook

Cross-Pollination

Model Round New Ideas? Details
claude-sonnet-4.6 1 Yes AlwaysShowHeader = false → became Attempt 5
claude-opus-4.6 2 No NO NEW IDEAS — solution space exhausted

Exhausted: Yes
Selected Fix: Attempt 5 (AlwaysShowHeader = false) — most idiomatic WinUI approach; leverages built-in NavigationView behavior; eliminates InvalidateMeasure() requirement; comparable simplicity to PR but more correct. PR's FindName approach is fragile and relies on implementation details of the WinUI template.


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #30254, Windows Shell flyout header space
Gate ✅ PASSED windows
Try-Fix ✅ COMPLETE 5 attempts, all 5 passing; solution space exhausted
Report ✅ COMPLETE

Summary

PR #30382 fixes a real, verified bug: Windows Shell with FlyoutBehavior="Flyout" reserves header space above the tab bar even when the page title is empty. The fix is functionally correct and passes the gate. However, exploration identified a more idiomatic approach, and the PR code has quality concerns that should be addressed before merge.

Selected Fix: Attempt 5 (AlwaysShowHeader = false) is recommended over the PR's current approach — it leverages a built-in WinUI NavigationView property, eliminating the manual InvalidateMeasure() call and making the fix more robust.

Root Cause

In RootNavigationView, UpdateToolbarPlacement() always assigns Header = Toolbar in LeftMinimal pane mode (Flyout behavior), even when the Toolbar has no visible content. WinUI's NavigationView defaults to AlwaysShowHeader = true, meaning the header row always reserves space even when the content renders invisibly — producing the unwanted gap above the tab bar.

Fix Quality

Issues with the PR's current implementation:

  1. AlwaysShowHeader = false not used — requires unnecessary InvalidateMeasure()
    WinUI's built-in AlwaysShowHeader property, when set to false, natively collapses the header area when Header = null without needing InvalidateMeasure(). The PR uses the default true and compensates with an explicit InvalidateMeasure() call. Attempt 5 confirmed that AlwaysShowHeader = false + Header = null works cleanly without it.

    Suggested fix: Add AlwaysShowHeader = false; to RootNavigationView's constructor and remove the InvalidateMeasure() call from CollapseEmptyHeader().

  2. Fragile FindName string-based template lookups
    HasMenuBarItems() uses FindName("menuContent") and HasTitleIcon() uses FindName("titleIcon"). These rely on internal template part names that could change across WinUI versions and are not part of the public contract.

    Suggested fix: Access toolbar content through typed properties or the existing MauiToolbar API rather than FindName.

  3. PaneDisplayModeChanged does not call UpdateHeaderVisibility()
    When FlyoutBehavior changes at runtime (which triggers a PaneDisplayMode change), UpdateHeaderVisibility() is never called. The header state could be stale after a runtime FlyoutBehavior change.

    Suggested fix: Call UpdateHeaderVisibility() at the end of RootNavigationView.PaneDisplayModeChanged.

  4. Trailing whitespace in RootNavigationView.cs
    The diff shows trailing whitespace on several lines (e.g., after return; on line 261, after CollapseEmptyHeader(); on line 266, after HasTitleIcon(); on line 281). This will fail dotnet format checks.

  5. Test only validates initial state; no tab-switch coverage
    ShouldHideHeaderWhenTitleEmpty() waits for MainPageButton and immediately takes a screenshot — it only verifies the empty-title page on initial load. The core behavior being fixed (switching between tabs with and without titles) is not tested.

    Suggested fix: Add a second test step that taps to the "With Title" tab, verifies the header appears, then switches back and verifies the header disappears.

  6. 5 existing test snapshots resaved without per-test explanation
    ShellFlowDirectionUpdate, VerifyFlyoutBackgroundColor, VerifyHamburgerIcon, Issue23834FlyoutMisbehavior, VerifyFlyoutContentHasNoDefaultCornerRadius were all resaved. The PR explanation ("ContentPage did not have a title") is plausible but should be verified — any snapshot change for a test not directly related to this issue risks hiding regressions.

Suggested Alternative

Add AlwaysShowHeader = false; to RootNavigationView's constructor, remove InvalidateMeasure() from CollapseEmptyHeader(), add the UpdateHeaderVisibility() call in PaneDisplayModeChanged, fix trailing whitespace, and strengthen the test to verify tab-switching behavior.


@MauiBot MauiBot added s/agent-review-incomplete s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Mar 21, 2026

@kubaflo kubaflo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please review the AI's summary?

@BagavathiPerumal

Copy link
Copy Markdown
Contributor Author

Could you please review the AI's summary?

@kubaflo, The agent review for this PR appears to be in an incomplete state. Please find the AI summary for your reference.

AI summary comment: #30382 (comment)

@MauiBot

MauiBot commented Mar 29, 2026

Copy link
Copy Markdown
Collaborator

🚦 Gate - Test Before and After Fix

📊 Expand Full Gated87d994 · fix-30254-Snapshot updated.

Gate Result: ✅ PASSED

Platform: WINDOWS · Base: main · Merge base: 794a9fa6

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue30254 Issue30254 ✅ FAIL — 574s ✅ PASS — 456s
🔴 Without fix — 🖥️ Issue30254: FAIL ✅ · 574s
  Determining projects to restore...
  Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 29.49 sec).
  Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 29.46 sec).
  Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 10.12 sec).
  Restored D:\a\1\s\src\Core\src\Core.csproj (in 15.68 sec).
  Restored D:\a\1\s\src\Core\maps\src\Maps.csproj (in 14.22 sec).
  Restored D:\a\1\s\src\Controls\tests\TestCases.HostApp\Controls.TestCases.HostApp.csproj (in 8.71 sec).
  Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 18 ms).
  Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 42 ms).
  Restored D:\a\1\s\src\Controls\Foldable\src\Controls.Foldable.csproj (in 17 ms).
  Restored D:\a\1\s\src\Controls\Maps\src\Controls.Maps.csproj (in 21 ms).
  Restored D:\a\1\s\src\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 26 ms).
  3 of 14 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
  Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:05:52.18
  Determining projects to restore...
  Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils\VisualTestUtils.csproj (in 717 ms).
  Restored D:\a\1\s\src\TestUtils\src\UITest.NUnit\UITest.NUnit.csproj (in 1.27 sec).
  Restored D:\a\1\s\src\TestUtils\src\UITest.Core\UITest.Core.csproj (in 3 ms).
  Restored D:\a\1\s\src\TestUtils\src\UITest.Appium\UITest.Appium.csproj (in 1.1 sec).
  Restored D:\a\1\s\src\TestUtils\src\UITest.Analyzers\UITest.Analyzers.csproj (in 4.82 sec).
  Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils.MagickNet\VisualTestUtils.MagickNet.csproj (in 17.45 sec).
  Restored D:\a\1\s\src\Controls\tests\CustomAttributes\Controls.CustomAttributes.csproj (in 6 ms).
  Restored D:\a\1\s\src\Controls\tests\TestCases.WinUI.Tests\Controls.TestCases.WinUI.Tests.csproj (in 9.48 sec).
  7 of 15 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
  Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
  UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
  UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
  UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
  VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
  VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
  UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
  Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/2/2026 10:44:37 PM FixtureSetup for Issue30254(Windows)
>>>>> 4/2/2026 10:44:51 PM ShouldHideHeaderWhenTitleEmpty Start
>>>>> 4/2/2026 10:44:53 PM ShouldHideHeaderWhenTitleEmpty Stop
>>>>> 4/2/2026 10:44:53 PM Log types: 
  Failed ShouldHideHeaderWhenTitleEmpty [3 s]
  Error Message:
   VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: ShouldHideHeaderWhenTitleEmpty.png (2.22% difference)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow

  Stack Trace:
     at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 477
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance, Boolean includeTitleBar) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 309
   at Microsoft.Maui.TestCases.Tests.Issues.Issue30254.ShouldHideHeaderWhenTitleEmpty() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30254.cs:line 20
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.11]   Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.35]   Discovered:  Controls.TestCases.WinUI.Tests

Total tests: 1
     Failed: 1
Test Run Failed.
 Total time: 36.7622 Seconds

🟢 With fix — 🖥️ Issue30254: PASS ✅ · 456s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
  Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
  Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:05:36.20
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
  Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
  Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.60-ci+azdo.13730064
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
  VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
  VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
  UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
  UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
  UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
  UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
  Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/2/2026 10:52:18 PM FixtureSetup for Issue30254(Windows)
>>>>> 4/2/2026 10:52:29 PM ShouldHideHeaderWhenTitleEmpty Start
>>>>> 4/2/2026 10:52:31 PM ShouldHideHeaderWhenTitleEmpty Stop
  Passed ShouldHideHeaderWhenTitleEmpty [1 s]
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.12]   Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.39]   Discovered:  Controls.TestCases.WinUI.Tests

Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 28.1946 Seconds

📁 Fix files reverted (3 files)
  • eng/pipelines/ci-copilot.yml
  • src/Controls/src/Core/Handlers/Shell/Windows/ShellView.cs
  • src/Core/src/Platform/Windows/RootNavigationView.cs

@Deus-nsf

Copy link
Copy Markdown

Apparently according to Claude Opus 4.6, just having
Shell.NavBarIsVisible="False"
is a sufficient workaround to avoid this!
It's probably not a real fix but until then, I guess it will do, at least for me.

@BagavathiPerumal

Copy link
Copy Markdown
Contributor Author

Could you please resolve conflicts?

@kubaflo, I have resolved the merge conflict on this PR.

@kubaflo kubaflo merged commit 0d4b2cb into dotnet:inflight/current Apr 13, 2026
9 of 17 checks passed
PureWeen pushed a commit that referenced this pull request Apr 14, 2026
…ht space above the tab bar even if the page title is empty (#30382)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The root cause of this issue is that the Windows Shell implementation
always reserves space for the header area when
Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or
header content. The NavigationView control allocates a fixed height
above the tab bar for the header region without checking if the current
page actually needs this space. This results in an unwanted gap between
the flyout toggle area and the tab bar when navigating to pages with
empty titles, creating visual inconsistency compared to
FlyoutBehavior="Disabled" mode where no header space is reserved for
empty content.

### Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell
implementation to remove unwanted space above the tab bar in flyout
mode. The implementation introduces three key methods in
RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header
visibility requirements, IsHeaderContentEmpty() to determine if the
toolbar contains no title or title view when in flyout mode, and
CollapseEmptyHeader() to properly hide empty headers. The toolbar
property setter now calls UpdateHeaderVisibility() when the toolbar
changes, and ShellView.cs triggers header visibility updates during tab
navigation. This ensures empty headers don't occupy unnecessary space in
flyout mode while maintaining normal behavior when headers contain
content, resolving the spacing issue above the tab bar when switching
between pages in Shell applications on Windows.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [x] iOS
- [x] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #30254

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a
title. So, resaved the test snapshot based on the fix.

1. ShellFlowDirectionUpdate
2. VerifyFlyoutBackgroundColor
3. VerifyHamburgerIcon
4. Issue23834FlyoutMisbehavior

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ca496f96-2500-429f-8720-a8adb7925fce">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/1f0dedd2-4808-46bf-98cf-843ca70294ef">
|
kubaflo pushed a commit that referenced this pull request Apr 20, 2026
…ent property in MauiToolbar (#35040)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Details

PR #30382 introduced a call to Toolbar?.HasMenuBarContent was introduced
inside RootNavigationView.IsHeaderContentEmpty(), but
the HasMenuBarContentproperty was not defined in MauiToolbar, which
caused a CS1061 build error on Windows.

**Error Details:** error CS1061: 'MauiToolbar' does not contain a
definition for 'HasMenuBarContent' and no accessible extension method
'HasMenuBarContent' accepting a first argument of type 'MauiToolbar'
could be found (are you missing a using directive or an assembly
reference?)

### Description of Change

Implemented the missing internal bool HasMenuBarContent property
in MauiToolbar.xaml.cs. This property returns true when the toolbar has
a non-null MenuBar containing at least one item, ensuring consistency
with the existing visibility logic used in SetMenuBar().

### Fixes

Fixes build error introduced by PR #30382 on Windows
devanathan-vaithiyanathan pushed a commit to Tamilarasan-Paranthaman/maui that referenced this pull request Apr 21, 2026
…ht space above the tab bar even if the page title is empty (dotnet#30382)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The root cause of this issue is that the Windows Shell implementation
always reserves space for the header area when
Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or
header content. The NavigationView control allocates a fixed height
above the tab bar for the header region without checking if the current
page actually needs this space. This results in an unwanted gap between
the flyout toggle area and the tab bar when navigating to pages with
empty titles, creating visual inconsistency compared to
FlyoutBehavior="Disabled" mode where no header space is reserved for
empty content.

### Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell
implementation to remove unwanted space above the tab bar in flyout
mode. The implementation introduces three key methods in
RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header
visibility requirements, IsHeaderContentEmpty() to determine if the
toolbar contains no title or title view when in flyout mode, and
CollapseEmptyHeader() to properly hide empty headers. The toolbar
property setter now calls UpdateHeaderVisibility() when the toolbar
changes, and ShellView.cs triggers header visibility updates during tab
navigation. This ensures empty headers don't occupy unnecessary space in
flyout mode while maintaining normal behavior when headers contain
content, resolving the spacing issue above the tab bar when switching
between pages in Shell applications on Windows.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [x] iOS
- [x] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes dotnet#30254

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a
title. So, resaved the test snapshot based on the fix.

1. ShellFlowDirectionUpdate
2. VerifyFlyoutBackgroundColor
3. VerifyHamburgerIcon
4. Issue23834FlyoutMisbehavior

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ca496f96-2500-429f-8720-a8adb7925fce">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/1f0dedd2-4808-46bf-98cf-843ca70294ef">
|
PureWeen pushed a commit that referenced this pull request Apr 22, 2026
…ht space above the tab bar even if the page title is empty (#30382)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The root cause of this issue is that the Windows Shell implementation
always reserves space for the header area when
Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or
header content. The NavigationView control allocates a fixed height
above the tab bar for the header region without checking if the current
page actually needs this space. This results in an unwanted gap between
the flyout toggle area and the tab bar when navigating to pages with
empty titles, creating visual inconsistency compared to
FlyoutBehavior="Disabled" mode where no header space is reserved for
empty content.

### Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell
implementation to remove unwanted space above the tab bar in flyout
mode. The implementation introduces three key methods in
RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header
visibility requirements, IsHeaderContentEmpty() to determine if the
toolbar contains no title or title view when in flyout mode, and
CollapseEmptyHeader() to properly hide empty headers. The toolbar
property setter now calls UpdateHeaderVisibility() when the toolbar
changes, and ShellView.cs triggers header visibility updates during tab
navigation. This ensures empty headers don't occupy unnecessary space in
flyout mode while maintaining normal behavior when headers contain
content, resolving the spacing issue above the tab bar when switching
between pages in Shell applications on Windows.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [x] iOS
- [x] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #30254

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a
title. So, resaved the test snapshot based on the fix.

1. ShellFlowDirectionUpdate
2. VerifyFlyoutBackgroundColor
3. VerifyHamburgerIcon
4. Issue23834FlyoutMisbehavior

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ca496f96-2500-429f-8720-a8adb7925fce">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/1f0dedd2-4808-46bf-98cf-843ca70294ef">
|
PureWeen pushed a commit that referenced this pull request Apr 22, 2026
…ent property in MauiToolbar (#35040)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Details

PR #30382 introduced a call to Toolbar?.HasMenuBarContent was introduced
inside RootNavigationView.IsHeaderContentEmpty(), but
the HasMenuBarContentproperty was not defined in MauiToolbar, which
caused a CS1061 build error on Windows.

**Error Details:** error CS1061: 'MauiToolbar' does not contain a
definition for 'HasMenuBarContent' and no accessible extension method
'HasMenuBarContent' accepting a first argument of type 'MauiToolbar'
could be found (are you missing a using directive or an assembly
reference?)

### Description of Change

Implemented the missing internal bool HasMenuBarContent property
in MauiToolbar.xaml.cs. This property returns true when the toolbar has
a non-null MenuBar containing at least one item, ensuring consistency
with the existing visibility logic used in SetMenuBar().

### Fixes

Fixes build error introduced by PR #30382 on Windows
PureWeen pushed a commit that referenced this pull request Apr 28, 2026
…ht space above the tab bar even if the page title is empty (#30382)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The root cause of this issue is that the Windows Shell implementation
always reserves space for the header area when
Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or
header content. The NavigationView control allocates a fixed height
above the tab bar for the header region without checking if the current
page actually needs this space. This results in an unwanted gap between
the flyout toggle area and the tab bar when navigating to pages with
empty titles, creating visual inconsistency compared to
FlyoutBehavior="Disabled" mode where no header space is reserved for
empty content.

### Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell
implementation to remove unwanted space above the tab bar in flyout
mode. The implementation introduces three key methods in
RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header
visibility requirements, IsHeaderContentEmpty() to determine if the
toolbar contains no title or title view when in flyout mode, and
CollapseEmptyHeader() to properly hide empty headers. The toolbar
property setter now calls UpdateHeaderVisibility() when the toolbar
changes, and ShellView.cs triggers header visibility updates during tab
navigation. This ensures empty headers don't occupy unnecessary space in
flyout mode while maintaining normal behavior when headers contain
content, resolving the spacing issue above the tab bar when switching
between pages in Shell applications on Windows.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [x] iOS
- [x] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #30254

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a
title. So, resaved the test snapshot based on the fix.

1. ShellFlowDirectionUpdate
2. VerifyFlyoutBackgroundColor
3. VerifyHamburgerIcon
4. Issue23834FlyoutMisbehavior

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ca496f96-2500-429f-8720-a8adb7925fce">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/1f0dedd2-4808-46bf-98cf-843ca70294ef">
|
PureWeen pushed a commit that referenced this pull request Apr 28, 2026
…ent property in MauiToolbar (#35040)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Details

PR #30382 introduced a call to Toolbar?.HasMenuBarContent was introduced
inside RootNavigationView.IsHeaderContentEmpty(), but
the HasMenuBarContentproperty was not defined in MauiToolbar, which
caused a CS1061 build error on Windows.

**Error Details:** error CS1061: 'MauiToolbar' does not contain a
definition for 'HasMenuBarContent' and no accessible extension method
'HasMenuBarContent' accepting a first argument of type 'MauiToolbar'
could be found (are you missing a using directive or an assembly
reference?)

### Description of Change

Implemented the missing internal bool HasMenuBarContent property
in MauiToolbar.xaml.cs. This property returns true when the toolbar has
a non-null MenuBar containing at least one item, ensuring consistency
with the existing visibility logic used in SetMenuBar().

### Fixes

Fixes build error introduced by PR #30382 on Windows
PureWeen pushed a commit that referenced this pull request Apr 29, 2026
…ht space above the tab bar even if the page title is empty (#30382)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The root cause of this issue is that the Windows Shell implementation
always reserves space for the header area when
Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or
header content. The NavigationView control allocates a fixed height
above the tab bar for the header region without checking if the current
page actually needs this space. This results in an unwanted gap between
the flyout toggle area and the tab bar when navigating to pages with
empty titles, creating visual inconsistency compared to
FlyoutBehavior="Disabled" mode where no header space is reserved for
empty content.

### Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell
implementation to remove unwanted space above the tab bar in flyout
mode. The implementation introduces three key methods in
RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header
visibility requirements, IsHeaderContentEmpty() to determine if the
toolbar contains no title or title view when in flyout mode, and
CollapseEmptyHeader() to properly hide empty headers. The toolbar
property setter now calls UpdateHeaderVisibility() when the toolbar
changes, and ShellView.cs triggers header visibility updates during tab
navigation. This ensures empty headers don't occupy unnecessary space in
flyout mode while maintaining normal behavior when headers contain
content, resolving the spacing issue above the tab bar when switching
between pages in Shell applications on Windows.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [x] iOS
- [x] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #30254

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a
title. So, resaved the test snapshot based on the fix.

1. ShellFlowDirectionUpdate
2. VerifyFlyoutBackgroundColor
3. VerifyHamburgerIcon
4. Issue23834FlyoutMisbehavior

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ca496f96-2500-429f-8720-a8adb7925fce">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/1f0dedd2-4808-46bf-98cf-843ca70294ef">
|
PureWeen pushed a commit that referenced this pull request Apr 29, 2026
…ent property in MauiToolbar (#35040)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Details

PR #30382 introduced a call to Toolbar?.HasMenuBarContent was introduced
inside RootNavigationView.IsHeaderContentEmpty(), but
the HasMenuBarContentproperty was not defined in MauiToolbar, which
caused a CS1061 build error on Windows.

**Error Details:** error CS1061: 'MauiToolbar' does not contain a
definition for 'HasMenuBarContent' and no accessible extension method
'HasMenuBarContent' accepting a first argument of type 'MauiToolbar'
could be found (are you missing a using directive or an assembly
reference?)

### Description of Change

Implemented the missing internal bool HasMenuBarContent property
in MauiToolbar.xaml.cs. This property returns true when the toolbar has
a non-null MenuBar containing at least one item, ensuring consistency
with the existing visibility logic used in SetMenuBar().

### Fixes

Fixes build error introduced by PR #30382 on Windows
github-actions Bot pushed a commit that referenced this pull request May 6, 2026
…ht space above the tab bar even if the page title is empty (#30382)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

The root cause of this issue is that the Windows Shell implementation
always reserves space for the header area when
Shell.FlyoutBehavior="Flyout" is set, even when pages have no title or
header content. The NavigationView control allocates a fixed height
above the tab bar for the header region without checking if the current
page actually needs this space. This results in an unwanted gap between
the flyout toggle area and the tab bar when navigating to pages with
empty titles, creating visual inconsistency compared to
FlyoutBehavior="Disabled" mode where no header space is reserved for
empty content.

### Description of Issue Fix

The fix involves adding header visibility logic to the Windows Shell
implementation to remove unwanted space above the tab bar in flyout
mode. The implementation introduces three key methods in
RootNavigationView.cs: UpdateHeaderVisibility() to evaluate header
visibility requirements, IsHeaderContentEmpty() to determine if the
toolbar contains no title or title view when in flyout mode, and
CollapseEmptyHeader() to properly hide empty headers. The toolbar
property setter now calls UpdateHeaderVisibility() when the toolbar
changes, and ShellView.cs triggers header visibility updates during tab
navigation. This ensures empty headers don't occupy unnecessary space in
flyout mode while maintaining normal behavior when headers contain
content, resolving the spacing issue above the tab bar when switching
between pages in Shell applications on Windows.

Tested the behavior in the following platforms.
 
- [x] Windows
- [x] Mac
- [x] iOS
- [x] Android

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #30254

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Resaved Test snapshots

Resaved the below test snapshot because the ContentPage did not have a
title. So, resaved the test snapshot based on the fix.

1. ShellFlowDirectionUpdate
2. VerifyFlyoutBackgroundColor
3. VerifyHamburgerIcon
4. Issue23834FlyoutMisbehavior

### Output

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/ca496f96-2500-429f-8720-a8adb7925fce">
| <video width="270" height="600"
src="https://github.com/user-attachments/assets/1f0dedd2-4808-46bf-98cf-843ca70294ef">
|
github-actions Bot pushed a commit that referenced this pull request May 6, 2026
…ent property in MauiToolbar (#35040)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Details

PR #30382 introduced a call to Toolbar?.HasMenuBarContent was introduced
inside RootNavigationView.IsHeaderContentEmpty(), but
the HasMenuBarContentproperty was not defined in MauiToolbar, which
caused a CS1061 build error on Windows.

**Error Details:** error CS1061: 'MauiToolbar' does not contain a
definition for 'HasMenuBarContent' and no accessible extension method
'HasMenuBarContent' accepting a first argument of type 'MauiToolbar'
could be found (are you missing a using directive or an assembly
reference?)

### Description of Change

Implemented the missing internal bool HasMenuBarContent property
in MauiToolbar.xaml.cs. This property returns true when the toolbar has
a non-null MenuBar containing at least one item, ensuring consistency
with the existing visibility logic used in SetMenuBar().

### Fixes

Fixes build error introduced by PR #30382 on Windows
kubaflo pushed a commit that referenced this pull request May 7, 2026
…I test failures on candidate branch (#35312)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Root cause

PR #30382 introduced AlwaysShowHeader
= false in the RootNavigationView constructor to fix Issue
#30254 (blank header space in the
Shell flyout). However, this was applied unconditionally across all
NavigationView display modes.
 
In the scenario from Issue2740 (FlyoutPage with FlyoutBehavior.Locked),
the PaneDisplayMode is Left, not LeftMinimal. Because AlwaysShowHeader
was set to false, WinUI’s NavigationView collapsed the header whenever
the Header became temporarily null during page transitions. As a result,
toolbar items (e.g., the Switch button) were removed from the UI
Automation tree, causing the test to fail.


### Description of Change
 
The fix updates AlwaysShowHeader dynamically based on the current
PaneDisplayMode within the PaneDisplayModeChangedhandler:
 
AlwaysShowHeader = PaneDisplayMode !=
NavigationViewPaneDisplayMode.LeftMinimal;
This ensures:
• AlwaysShowHeader = false only for LeftMinimal mode (Shell Flyout),
preserving the fix for Issue #30254.
• AlwaysShowHeader = true for all other modes (e.g., Left /
FlyoutBehavior.Locked), ensuring the header remains visible and toolbar
items stay accessible in the UI Automation tree.

Also added the updated snapshot for the
#30382.


### Issues Fixed

- Regression introduced by PR #30382

### Resaved Test snapshots

The below-mentioned test case was resaved because the ContentPage did
not have a title. Based on the fix, the currently generated image is the
expected image, so the test snapshot has been resaved accordingly,
similar to [#30382](#30382).

-  ModalPageBackgroundShouldBeTransparent

**Added snapshots:**

Additionally, the updated snapshot for
[#30382](#30382) has also been added
for the Mac and Windows platforms.

- ShouldHideHeaderWhenTitleEmpty
- ShouldShowHeaderWhenTitleNotEmpty

### Failure test cases

- 	VerifyFlyoutVerticalScrollModeDisabled
- 	VerifyFlyoutPageToolbarItemsRender
- 	ShouldFlyoutBeVisibleAfterMaximizingWindow
- 	FlyoutItemTextShouldDisplayProperly
- 	VerifyShellMenuItemsAlignedInRTL
- 	TestB43527UpdateTitle
- 	TitleUpdatesAfterShowingNonFlyoutPage
- 	WhenFlyoutIsLockedButtonsAreStillVisible 
- 	Issue2740Test
- 	NavigationPageTitle
- 	DoNotAccessDisposedCollectionView
kubaflo added a commit that referenced this pull request May 7, 2026
…I test failures on candidate branch (#35340)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

Recreates #35312, which was accidentally merged into
`inflight/candidate` instead of `inflight/current`. The candidate-side
merge was reverted by #35339; this PR re-targets the same fix to
`inflight/current`.

Original author: @BagavathiPerumal

---

### Root cause

PR #30382 introduced AlwaysShowHeader
= false in the RootNavigationView constructor to fix Issue
#30254 (blank header space in the
Shell flyout). However, this was applied unconditionally across all
NavigationView display modes.

In the scenario from Issue2740 (FlyoutPage with FlyoutBehavior.Locked),
the PaneDisplayMode is Left, not LeftMinimal. Because AlwaysShowHeader
was set to false, WinUI's NavigationView collapsed the header whenever
the Header became temporarily null during page transitions. As a result,
toolbar items (e.g., the Switch button) were removed from the UI
Automation tree, causing the test to fail.


### Description of Change

The fix updates AlwaysShowHeader dynamically based on the current
PaneDisplayMode within the PaneDisplayModeChanged handler:

AlwaysShowHeader = PaneDisplayMode !=
NavigationViewPaneDisplayMode.LeftMinimal;

This ensures:
- AlwaysShowHeader = false only for LeftMinimal mode (Shell Flyout),
preserving the fix for Issue #30254.
- AlwaysShowHeader = true for all other modes (e.g., Left /
FlyoutBehavior.Locked), ensuring the header remains visible and toolbar
items stay accessible in the UI Automation tree.

Also added the updated snapshot for the
#30382.


### Issues Fixed

- Regression introduced by PR #30382

### Resaved Test snapshots

The below-mentioned test case was resaved because the ContentPage did
not have a title. Based on the fix, the currently generated image is the
expected image, so the test snapshot has been resaved accordingly,
similar to [#30382](#30382).

-  ModalPageBackgroundShouldBeTransparent

**Added snapshots:**

Additionally, the updated snapshot for
[#30382](#30382) has also been added
for the Mac and Windows platforms.

- ShouldHideHeaderWhenTitleEmpty
- ShouldShowHeaderWhenTitleNotEmpty

### Failure test cases

- VerifyFlyoutVerticalScrollModeDisabled
- VerifyFlyoutPageToolbarItemsRender
- ShouldFlyoutBeVisibleAfterMaximizingWindow
- FlyoutItemTextShouldDisplayProperly
- VerifyShellMenuItemsAlignedInRTL
- TestB43527UpdateTitle
- TitleUpdatesAfterShowingNonFlyoutPage
- WhenFlyoutIsLockedButtonsAreStillVisible 
- Issue2740Test
- NavigationPageTitle
- DoNotAccessDisposedCollectionView

Co-authored-by: BagavathiPerumal <93652794+BagavathiPerumal@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators May 14, 2026
@kubaflo kubaflo added the s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) label May 20, 2026
@PureWeen PureWeen added this to the .NET 10 SR8 milestone Jun 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-shell Shell Navigation, Routes, Tabs, Flyout community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-implemented PR author implemented the agent suggested fix s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(Windows) Shell.FlyoutBehavior="Flyout" forces the title height space above the tab bar even if the page title is empty