CommunityToolkit / WindowsCommunityToolkit

The Windows Community Toolkit is a collection of helpers, extensions, and custom controls. It simplifies and demonstrates common developer tasks building .NET apps with UWP and the Windows App SDK / WinUI 3 for Windows 10 and Windows 11. The toolkit is part of the .NET Foundation.
https://docs.microsoft.com/windows/communitytoolkit/
Other
5.88k stars 1.38k forks source link

ListDetailsView: Can report incorrect SelectedIndex if two items are the same object. #4245

Open Rosuavio opened 3 years ago

Rosuavio commented 3 years ago

Describe the bug

Because we bind the SelectedItem in the ListView to the SelectedItem prop in the ListDetailsView when a user clicks an item it raises the OnSelectedItemChanged method and it does not directly raise the OnSelectedIndexChanged method. https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/5dfc5754a44bb5619fa083a4be4b5c240462e982/Microsoft.Toolkit.Uwp.UI.Controls.Layout/ListDetailsView/ListDetailsView.xaml#L156-L165

This means the the index of the clicked item in the ListView is lost and then we incorrectly attempt to recover it and use it to update the SelectedIndex prop. We get the index of the first reference to the object selected from Items but that is not necessarily the index item in the list the user clicked.

https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/5dfc5754a44bb5619fa083a4be4b5c240462e982/Microsoft.Toolkit.Uwp.UI.Controls.Layout/ListDetailsView/ListDetailsView.cs#L148-L166

An example list where this could occur would look like.

var a = "Example";
var items = new ObservableCollection<int?>{ a, a };
var listDetailsView = new ListDetailsView{ ItemsSource = items, };

TODO: Build real example.

A clear and concise description of what the bug is.

Steps to Reproduce

Steps to reproduce the behavior:

  1. Given the following environment (Sample App w/ XAML, Project with Isolated setup, etc...)
  2. Go to '...'
  3. Click on '....'
  4. Scroll down to '....'
  5. See error

Expected behavior

Screenshots

Environment

NuGet Package(s):

Package Version(s):

Windows 10 Build Number:

App min and target version:

Device form factor:

Visual Studio version:

Additional context

michael-hawker commented 3 years ago

Does that even work in ListView, it's usually odd for a collection to contain two copies of the same object?

In either case, if we need the index, we probably don't want to use Items.IndexOf(Item) and instead use IndexFromContainer(ContainerFromItem(Item)) that may also handle this edge case?

Rosuavio commented 3 years ago

Does that even work in ListView, it's usually odd for a collection to contain two copies of the same object?

I still have to make a sample to test this.

In either case, if we need the index, we probably don't want to use Items.IndexOf(Item) and instead use IndexFromContainer(ContainerFromItem(Item)) that may also handle this edge case?

I think it would be even better if we simply bound to the SelectedIndex of the list rather than the SelectedItem then we would lose no information of what the user clicked on.