question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use ItemsRepeater in ListBox etc

See original GitHub issue

Our current item virtualization code has a few problems:

  1. It doesn’t handle differently sized items very well (#2144)
  2. It assumes that 1 item = one scroll unit, meaning that it can’t handle layouts that display multiple items per line (i.e. a wrapping panel, a grid)
  3. It doesn’t handle smooth scrolling
  4. It doesn’t correctly handle ListBoxItem children (#2936)

One of the main problems with supporting these scenarios is that the materialization of items due to changes in the source collection happens in the CollectionChanged event handler. Beacuse this occurs outside the layout pass, changes made here then trigger a layout pass. When that layout pass occurs, the virtualization algorithm is re-run, possibly with different constraints. This can cause the item that was scrolled to to be scrolled back out of the viewport, causing #2144. This could be worked around by storing temporary state to pass to the coming layout pass, however in some cases that layout pass will not occur meaning that the temporary state will be passed to a subsequent unrelated layout pass, causing other problems.

Another problem with creating the items in the CollectionChanged handler, is that we can potentially be doing much more materialization/dematerialization than required.

Initial attempt to fix this

My initial attempt to fix this involved moving the materialization of items to the layout pass, however the fact that we use a Panel to display the containers made this difficult: you don’t know which containers need to be visible until the measure pass has completed, so I started by removing all Children from the container at the start of the measure pass and adding them back in. This unfortunately broke things because as controls are removed from Children they are also removed from the visual/logical tree, causing the focused element to lose focus among other things.

The solution to this would be to modify virtualizing panels to have a “virtual” list of children for the measure pass, which is then synchronized with the real Children on arrange, or to somehow delay visual/logical tree detachment. To me these solutions seem like a hack to get around the real problem: that Panels aren’t the right solution for virtualization.

And this is just to fix point 1) above.

ItemsRepeater

UWP seem to have come to the same conclusion and have introduced Attached Layouts. This is a really powerful virtualization framework that would handle all points above, plus more, including nesting and grouping. In addition this is all MIT-licenced code with its source on GitHub.

UWP doesn’t use ItemsRepeater for its list boxes, assumedly for back-compat reasons, but we don’t have that problem being pre-1.0, and I think it could be used to implement a new ItemsPresenter or similar in Avalonia.

Unfortunately the code is written in C++/CX and there’s a quite a lot of it, so porting may not be easy.

ItemsRepeater has now been ported to Avalonia; the next step is to rewrite ItemsPresenter to use it.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:15
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
grokyscommented, Aug 23, 2021

Update on this: I’ve given up hoping that the upstream WinUI ItemsRepeater will ever be fixed enough to use it as a core component of our ItemsControls, in particular these issues are blockers:

https://github.com/microsoft/microsoft-ui-xaml/issues/1829 https://github.com/microsoft/microsoft-ui-xaml/issues/1422

I have a proof of concept for a virtualized stack panel which may fix many of our current problems with ListBox, and also allow smooth scrolling without breaking API compatibility, I hope to get more time to work on it in a few months.

Closing this issue for now.

1reaction
grokyscommented, Sep 28, 2019

Now that ItemsRepeater is ported from UWP, I plan to rework ItemsPresenter to be an ItemsRepeater in the 0.10 timeline. Currently #3040 is blocking that though.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ItemsRepeater - Windows apps
Use an ItemsRepeater to create custom collection experiences using a flexible layout system, custom views, and virtualization.
Read more >
ListView in Avalonia UI
I want to display List of custom data model (property A and B etc), and I'm really tempted to just use DataGrid ....
Read more >
ListBoxItem Class - Typedescriptor
A selectable item in a ListBox. On This Page. Overview; Constructors; Fields; Properties; Assemblies; Issues ...
Read more >
ListBox
The ListBox is an ItemsControl which displays items in a multi-line list box ... The items to display in the ListBox are specified...
Read more >
ListBoxControl - How to use UserControl as an item
I would like to display a list with complex items. The complex item has controls like buttons, images, labels, checkboxes etc.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found