dotnet / dotnet/wpf

ScrollIntoView sometimes fails to scroll the item into view

Open
#7,672 0 comments 4 reactions 1 assignee Claimed by @dipeshmsft View on GitHub
area-VirtualizingStackPanel Investigate
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

I recently ported my app from .NET 4.8 to .NET 7.0 and everything went well, except this one bug. Sometimes ScrollIntoView on a `System.Windows.Controls.DataGrid` silently fails to do what it is asked, resulting in random vertical scroll position that is not showing the selected item.

### Reproduction Steps

- git clone https://github.com/MoneyTools/MyMoney.Net
- git checkout clovett/scrollintoview
- open Source\Wpf\MyMoney.sln
- press F5 in the debug/any cpu configuration
- click create to create temp database
- click Help/Add Sample Data, and request 30 years of data
- open AMEX account and hit "ctrl-space" on the last couple pages of transactions (about 20 should do it). This marks them as "unaccepted" transactions.
- select one of those "unaccepted" transactions near the top of your list of unaccepted transactions.
- Click the filter dropdown at the top of the grid to filter the list to show only unaccepted transactions. notice the selection is preserved
- Click the folder dropdown and select "all" to go back to the full view.
- look at the debug output output

OnItemsChanged: Reset
Delayed ScrollIntoView Transaction: Amazon.com on 7/31/2022 for -9.9
OnItemsChanged: Reset
Delayed ScrollIntoView Transaction: Amazon.com on 7/31/2022 for -9.9
OnItemsChanged: Add
Delayed ScrollIntoView Transaction: Amazon.com on 7/31/2022 for -9.9
ScrollIntoView Transaction: Amazon.com on 7/31/2022 for -9.9
ScrollIntoView Transaction: Amazon.com on 7/31/2022 for -9.9
Row is visible as position 33

The row position reported here is wrong, it is the position of the row BEFORE the ItemsSource was completely changed - and I think this is why ScrollIntoView is failing.

I've added retry logic in the "CheckVisibility" function and sometimes you will see the errors:

- Dangorang, the container is not available yet, try again.
- Dangorang, the silly thing is still offscreen!

These are also indications that ScrollIntoView failed, but this retry also makes it appear to work, so comment out the call to CheckVisibility to reproduce the failure for your debugging. I should need to do any delayed actions around ScrollIntoView, I want to be able to set the ItemsSource, set the selected item, and call ScrollIntoView all synchronously and it should just work, no matter how long the list is.

### Expected behavior

ScrollIntoView needs to be reliable.

### Actual behavior

ScrollIntoView silently fails sometimes, mostly when the ItemsSource is changed from a short list to a long list where the selected item is the both lists and is moved much further down in the second longer list.

When it fails you will see one of the following debug outputs:
> Dangorang, the container is not available yet, try again...
> Dangorang, the silly thing is still offscreen!

### Regression?

Yes, this did not happen in .NET 4.8.

### Known Workarounds

I'm trying lots of delayed retries and so forth with no luck because the actual bounds reported by the DataGridRow are stale.

### Impact

Heavily used navigation feature of the app is broken as a result (F12, and F8).

### Configuration

Debug, Any CPU but a bit easier to repro in Release, Any CPU.

### Other information

See [Demo View](https://www.youtube.com/watch?v=u6BVF2x9FBA) showing how to use the app.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.