I tried to <Virtualize>
a list of a thousand items showing several per row, with display: inline-block
. The result in Blazor kinda works, but as the user scrolls, it seems to remove items from the DOM at the beginning and add them at the end in an arbitrary amount, causing the displayed items to change in position unexpectedly, giving the user a bad experience: the items are "reflowed", and an item that used to be in the third position in its row might now be in the first, second, or fourth position in its new row. The result is that the user scrolls and when a "update" of the items happen, the user loses track of the items that should still be shown in the viewport.
I am indeed using @key
on the child content of the Virtualize component, and specifying an explicit ItemSize
on the Virtualize component doesn't seem to help either.
Demo: Scroll down slowly and note the items by their six-character hex ID. After scrolling down a bit but before the first reflow, you'll see the gap for the last item.:
Then, after scrolling down just a little bit more, the reflow happens.
Expected behavior: The user should see the same items that were previously near the bottom of the viewport now near the top, in the same horizontal position, with new items following them.
Actual Behavior: The user sees some of the same items from before, but in different horizontal locations. Other items are unexpectedly above the viewport. Thus the user loses perceptual context of where they just scrolled from.
Also, note in the example first screenshot above that the last row before reflow is only partial till it is fully scrolled into view and triggers a rerender/reflow, as if it can't tell that there is room for a few more items. I suspect this symptom is closely related.
Any ideas on how to coax the Virtualize component into allowing multiple items per row with consistency as scrolling? I can't believe this is really the designed behavior. I previously thought I fixed a similar issue here, but now I realize that this earlier issue was only part of the problem.
Ideally in a vertical list, it would only add or remove items in the DOM in multiples of the max count of items that fit in a horizontal line. There is no way to tell the Virtualize component this number--only the component could figure it out.
I beleive the issue you are facing is due to variable height of the rows like others mentioned already into commends. I am facing the same issue in my application where I am listing tables and fields in a master detail view where every table has different set of fields.
The issue of scrolling is also discussed here https://github.com/dotnet/aspnetcore/issues/25058 where there are already some ideas to have a property for specifying the item height if you can precalculated this so the virtualization knows each element size, instead of fixed size for all elements.