microsoft / microsoft/microsoft-ui-xaml

TabView TearOutTabs: Implementation seems to assume tabs can be moved in between windows at will

Open
#10,207 0 comments 0 reactions 0 assignees View on GitHub
area-TabView bug team-Controls
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

It may be possible to move tabs containing a very simple ui to a new window, but if the tab contains a menu flyout it fails because the menu flyout's XamlRoot will be different to that of it's new parent window. The following exception will be thrown when the menu is subsequently opened:

`Exception thrown at 0x00007FFC1293837A (KernelBase.dll) in TearOutTabs.exe: WinRT originate error - 0x80070057 :
'This element is already associated with a XamlRoot, it cannot be associated with a different one until it is removed from the previous XamlRoot.'.`

I'm not aware of a way to associate it with a different one, or if it's possible. Attempting to update the XamlRoot in code, apart from being impractical, results in another exception:

`Exception thrown at 0x00007FFC1293837A (KernelBase.dll) in TearOutTabs.exe: WinRT originate error - 0x8000FFFF :
'Catastrophic failure Cannot change XamlRoot when it is already set'.`

One work around for this issue is to use the same solution used for the existing drag and drop function, namely adding a copy constructor for the tab view item and then adding the copy to the new tear out window. This works well if the new tear out window is dropped onto the desktop.

Unfortunately if the tear out window is moved over the tab view headers of another window, the drag operation is abnormally terminated immediately, even if the user continues to drag the tab.

### Steps to reproduce the bug

To reproduce the XamlRoot already associated exception:

1. Build and run the attached solution
2. Click on the split buttons drop down in "Tab 0" to open the menu flyout
3. Tear out "Tab 0" and drop the tear out window on to the desktop
4. Repeat step 2

The exception is thrown when you click on the drop down.

To reproduce the drag terminated problem when using the work around:

1. In the attached solution edit MainWindow.xaml.cs, uncommenting the `#define DUPLICATE_TABS` at line 0
2. Build and run it
3. Tear out "Tab 0" and drop the new tear out window on to the desktop
4. Click the add tab button in the new window
5. Tear out "Tab 4" and drag the tear out window over the original windows tab strip header

The drag will then be terminated when "Tab 4" is added to the original window even if you are still dragging.

[TearOutTabs.zip](https://github.com/user-attachments/files/17968956/TearOutTabs.zip)

### Expected behavior

The tab list in the event args for the tear out tabs feature should be read/write allowing for different tab instances to be created during the tear out process.

### Screenshots

_No response_

### NuGet package version

WinUI 3 - Windows App SDK 1.6.3: 1.6.241114003

### Windows version

Windows 11 (24H2): Build 26100

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Build and run the attached TearOutTabs solution, then reproduce both failures described in MainWindow.xaml.cs: the menu flyout XamlRoot exception and the drag termination after enabling DUPLICATE_TABS. Read the tear-out tabs event flow and verify that tabs can be recreated for the destination window without breaking continued dragging or menu flyouts.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.