microsoft / microsoft/microsoft-ui-xaml
ListView crashes when ISelectionInfo is used with Extended selection
- Dominant language
- C++
- Stars
- 8.4k
- Forks
- 942
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 105
Description
### Describe the bug
An ArgumentOutOfRangeException is thrown when using ListView extended selection with ISelectionInfo.
I originally listed this under #8684 but it would seem to be a separate bug (or reportably separately) since it does not involve a collection changed notification. I guess the root cause could be the same.
### Steps to reproduce the bug
1. Download the WinUI 3 Gallery and compile the WinUiGallery solution.
2. In ControlPages / ListViewPage.xaml.cs, add "using Microsoft.UI.Xaml.Data;" at the top of the file and add the following collection class at the bottom of the namespace. This is an ObservableCollection implementing ISelectionInfo (not completely, but sufficiently for the demonstration).
```
public class ObservableCollectionSelector<T> : ObservableCollection<T>, ISelectionInfo
{
public ObservableCollectionSelector(IEnumerable<T> source) : base(source) { }
private IList Selection = new List();
public void SelectRange(ItemIndexRange itemIndexRange)
{
//Debug.WriteLine($"Select {itemIndexRange.FirstIndex}:{itemIndexRange.LastIndex}");
if (this.Selection.Any(iir => iir.FirstIndex <= itemIndexRange.LastIndex + 1 && iir.LastIndex >= itemIndexRange.FirstIndex - 1)) { throw new NotSupportedException("failed select"); }
this.Selection.Add(itemIndexRange);
}
public void DeselectRange(ItemIndexRange itemIndexRange)
{
//Debug.WriteLine($"Deselect {itemIndexRange.FirstIndex}:{itemIndexRange.LastIndex}");
if (!this.Selection.Any(iir => iir.FirstIndex == itemIndexRange.FirstIndex && iir.LastIndex == itemIndexRange.LastIndex)) { throw new NotSupportedException("failed deselect"); }
this.Selection.Remove(itemIndexRange);
}
public bool IsSelected(int index)
{
return this.Selection.Any(iir => iir.FirstIndex <= index && iir.LastIndex >= index);
}
public IReadOnlyList GetSelectedRanges()
{
//Debug.Assert(!this.Selection.Any((iir, i) => i > 0 && iir.FirstIndex <= this.Selection[i - 1].FirstIndex + 1));
return this.Selection.AsReadOnly();
}
}
```
3. Around line 59, change `Control2.ItemsSource = await Contact.GetContactsAsync();` so that it says `Control2.ItemsSource = new ObservableCollectionSelector<Contact>( await Contact.GetContactsAsync());`
4. Run the app, select Collections on the left and then ListView. Scroll down to the second ListView ("ListView with Selection Support") and select Extended as the selection type. Click on the first entry ("Kendal Collins") and then CTRL-Click on the third entry ("Vance DeLeon"). Then release the control key and click on the 5th entry ("Amber Rodriguez").
### Expected behavior
Expected: the two previously selected items should be deselected and the new one should be selected. Actual: no change in visual state, and a crash with an ArgumentOutOfRange exception in WinRT.Runtime.dll. If you uncomment the WriteLine statements, it shows that index 0 is deselected then the crash occurs.
The details of the exception are:
Exception thrown: 'System.ArgumentOutOfRangeException' in WinRT.Runtime.dll
Exception thrown at 0x00007FFFC0F6B699 (KernelBase.dll) in WinUIGallery.exe: WinRT originate error - 0x8000000B : 'This collection cannot work with indices larger than Int32.MaxValue - 1 (0x7FFFFFFF - 1). (Parameter 'index')'.
Microsoft.ui.xaml.dll!00007FFF23716C7D: 8000000B - E_BOUNDS
### Screenshots
_No response_
### NuGet package version
None
### Windows version
_No response_
### Additional context
WindowsAppSDK 1.6.240829007 and I happen to be using Windows 10, 22H2 build 19045.4894
Contributor guide
Research direction
Reproduce the crash in the WinUI 3 Gallery using ControlPages/ListViewPage.xaml.cs and the provided ObservableCollectionSelector implementation. Start by tracing the ListView with Selection Support when ISelectionInfo handles Extended selection, then verify that deselecting the earlier items and selecting the fifth item updates visual state without an ArgumentOutOfRangeException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, csharp
- Domain
- desktop-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100