Skip to content

Fix TabView tear-out sample: close empty windows and clear stale refs#2159

Open
niels9001 wants to merge 2 commits intomainfrom
fix/tabview-tearout-empty-window-cleanup-2078
Open

Fix TabView tear-out sample: close empty windows and clear stale refs#2159
niels9001 wants to merge 2 commits intomainfrom
fix/tabview-tearout-empty-window-cleanup-2078

Conversation

@niels9001
Copy link
Copy Markdown
Collaborator

Description

Note

This PR was generated with the assistance of GitHub Copilot (AI). All changes should be reviewed carefully.

Fixes #2078

The TabView windowing sample (TabViewWindowingSamplePage.xaml.cs) has issues where empty windows are left open after tab tear-out/drop-back operations, and stale window references can cause unexpected behavior across multiple tear-out sequences.

Root Cause Analysis

Issue #2078 reports three problems:

  1. Screen flickers to black when clicking tabs — this is a WinUI framework behavior where TabTearOutWindowRequested fires on mouse-down rather than on drag gesture. This is not fixable in the sample code (framework-level issue).
  2. App crashes after repeated tab switching — partially caused by accumulated empty windows and stale tabTearOutWindow references.
  3. No cleanup for empty windows after tabs are dropped back — the sample only closed windows via the tab close button, not when all tabs were torn out or dropped into another window.

Changes (1 file)

TabViewWindowingSamplePage.xaml.cs

Change Why
Added CloseWindowIfEmpty(TabView) helper Walks the visual tree from a TabView to find its parent Page, then closes the containing Window when the TabView is empty. Consolidates the pattern used across multiple handlers.
Close source window in Tabs_TabTearOutRequested When all tabs are torn out to a new window, the source window was left open and empty. Now it closes automatically.
Close source window in Tabs_ExternalTornOutTabsDropped When all tabs are dragged back into another window, the now-empty source window was left open. Now it closes automatically.
Clear tabTearOutWindow after tear-out completes Prevents stale reference when multiple tear-outs happen in sequence. Each TabTearOutWindowRequested sets the field, but it was never cleared — so Tabs_TabTearOutRequested could reference a wrong window.
Refactored Tabs_TabCloseRequested Now uses the same CloseWindowIfEmpty helper for consistency.
Removed unused DataIdentifier constant Dead code cleanup.

What this does NOT fix

The screen flicker on tab click (issue point #1) is caused by TabTearOutWindowRequested firing on mouse-down rather than on an actual drag gesture. This is a WinUI framework behavior, not a sample code issue. A fix would need to come from the microsoft-ui-xaml repo.

How to validate

  1. Build: dotnet build WinUIGallery\WinUIGallery.csproj /p:Platform=x64 — 0 errors ✅
  2. Manual testing (requires running the app):
    • Open the TabView page → click "Click here to launch the sample"
    • Test tear-out cleanup: Drag all tabs from the main sample window to a new window → verify the source window closes automatically
    • Test drop-back cleanup: Tear out a tab to a new window → drag it back to the original window → verify the now-empty window closes automatically
    • Test close button: Close all tabs via the X button → verify the window closes (existing behavior preserved)
    • Test multiple tear-outs: Tear out tabs multiple times in sequence → verify each operation creates a proper new window without interference from previous tear-outs

niels9001 and others added 2 commits April 11, 2026 22:54
…#1474)

Refactor the Axe accessibility test infrastructure to use targeted per-page
rule exclusions instead of globally disabling 10 rules for all pages.

Changes:
- AxeHelper: Accept optional per-page rule exclusions parameter. Only 4
  framework-level rules (NameIsInformative, NameExcludesControlType,
  NameExcludesLocalizedControlType, SiblingUniqueAndFocusable) remain
  globally excluded. Improve error messages with element name, automation
  ID, and rule ID for easier debugging.
- AxeScanAllTests: Add PageRuleExclusions dictionary mapping specific
  pages (WebView2, Icons, MapControl) to their known rule exclusions.
  Move WebView2, Icons, MapControl from full exclusion list to per-page
  rule exclusions so they are now scanned with most rules enabled.
- MapControlPage: Add AutomationProperties.Name to PasswordBox and
  MapControl. Mark decorative Image with AccessibilityView=Raw.
- StoragePickersPage: Add AutomationProperties.Name to icon-only button.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…#2078)

Fix issues in the TabView windowing sample where empty windows were left
open after all tabs were torn out or dropped back into another window,
and the tabTearOutWindow field held stale references across multiple
tear-out operations.

Changes:
- Add CloseWindowIfEmpty helper that walks the visual tree from a TabView
  to find its parent Page and close the containing window when empty.
- Close source window in Tabs_TabTearOutRequested when all tabs are torn
  out to a new window.
- Close source window in Tabs_ExternalTornOutTabsDropped when all tabs
  are dropped into a different window.
- Clear tabTearOutWindow after tear-out completes to prevent stale
  references when multiple tear-outs happen in sequence.
- Consolidate empty-window check in Tabs_TabCloseRequested to reuse the
  same CloseWindowIfEmpty helper.
- Remove unused DataIdentifier constant.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TabView tab tear out example

1 participant