microsoft / microsoft/microsoft-ui-xaml
TabView unloads currently selected tabitem when other tabs are removed
- Dominant language
- C++
- Stars
- 8.4k
- Forks
- 942
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 105
Description
### Describe the bug
When removing non-selected items from a TabView the currently selected TabViewItem recieves an Unloaded event once for each removed tab.
### Steps to reproduce the bug
1. Bind the TabItemsSource of a TabView to an ObservableCollection with some items in it.
2. Trigger a method that removes items from the collection that are not currently selected.
3. The selected tab is unloaded multiple times.
Example code (not full):
```
public class MainWindowViewModel : INotifyPropertyChanged
{
public ObservableCollection Items { get; } = [];
public ObservableCollection TabItems { get; } = [];
public ItemViewModel? CurrentTabItem { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public void AddTabs()
{
CurrentTabItem = null;
TabItems.Clear();
TabItems.Add(new ItemViewModel { Name = "ViewModel A" });
TabItems.Add(new ItemViewModel { Name = "ViewModel B" });
TabItems.Add(new ItemViewModel { Name = "ViewModel C" });
TabItems.Add(new ItemViewModel { Name = "ViewModel D" });
CurrentTabItem = TabItems[0];
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentTabItem)));
Items.Clear();
foreach (var item in TabItems) {
Items.Add(item);
}
}
public void RemoveAllButCurrent()
{
foreach (var item in TabItems.ToList())
{
if (item != CurrentTabItem)
{
TabItems.Remove(item);
}
}
}
}
```
```
public class ItemViewModel : INotifyPropertyChanged
{
public required string Name { get; set; }
public int Loaded { get; private set; }
public int Unloaded { get; private set; }
public void Load()
{
Loaded++;
OnPropertyChanged(nameof(Loaded));
}
public void Unload()
{
Unloaded++;
OnPropertyChanged(nameof(Unloaded));
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
```
```
```
### Expected behavior
_No response_
### Screenshots

Initial state. Note that the selected tab has been unloaded one time, does not seem correct to me.

After selecting each tab once.

After removing all non-selected tabs. Note that ViewModel D reports 3 extra unloaded events. It has also been loaded once again. But the loaded event comes first, and the three unloaded events come afterwards.
### NuGet package version
WinUI 3 - Windows App SDK 1.5.5: 1.5.240627000
### Windows version
Windows 11 (22H2): Build 22621
### Additional context
_No response_
Contributor guide
Research direction
Start by running the supplied WinUI TabView reproduction with TabItemsSource bound to an ObservableCollection and observe Loaded/Unloaded counts while removing non-selected items. Trace the TabView item-removal and selection handling; done means the selected TabViewItem does not receive extra Unloaded events when other tabs are removed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, csharp
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100