Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Use VirtualizedTreeView in Dev Tools to display hierarchy

Open BAndysc opened this issue 1 year ago • 7 comments

What does the pull request do?

This PR introduces an internal control called VirtualizedTreeView, which is built upon the ListBox to use virtualization for tree structures. It allows displaying the tree children without impacting the visual tree's depth.

The old TreeView in the dev tools used to display the logical/visual tree has been replaced with the new VirtualizedTreeView.

Thanks to styling, visually the VirtualizedTreeView is almost indistinguishable from the old TreeView:

https://github.com/AvaloniaUI/Avalonia/assets/5689666/fe5575fa-3194-454d-9a6d-327298bf0097

~~HOWEVER there is a small bug related to BringToView in VirtualizedStackPanel. Unfortunately despite providing correct bounds in BringToView, VirtualizedStackPanel sometimes doesn't scroll properly when currently displayed elements are shorter than the row that has just been brought to view. This is a virtualization bug, not in this implementation. See: https://github.com/AvaloniaUI/Avalonia/issues/14418~~

What is the current behavior?

The current Dev Tools use a regular TreeView, where each TreeNodeItem visually displays its children nodes as actual visual children. This design leads to a quick increase in the depth of the TreeView's visual tree. According to my tests, Avalonia 11 can handle approximately 400-450 nested controls (tested on Windows and Mac).

Despite being a downgrade compared to Avalonia 0.10 (~1000 nested controls in my tests), the new limit remains reasonable, however, the challenge arises when attempting to display a hierarchy of 400 nested controls, causing the TreeView to require about four times more depth. Consequently, I am experiencing crashes in the Dev Tools when working with just around 130 nested controls, which is not that much in more advanced scenarios.

What is the updated/expected behavior with this PR?

With this PR, Dev Tools will no longer crash when displaying deep logical/visual trees, because VirtualizedTreeView, unlike TreeView, does not suffer from depth-related issues.

How was the solution implemented

As expected, the VirtualizedTreeView flattens the tree structure into a list and presents the flattened list within a ListBox. To ensure optimal performance, the tree is differentially flattened, avoiding regeneration each time the tree structure undergoes changes. The FlatTree class observes for changes to the IsExpanded property and children collection, applying the necessary adjustments to the flat list.

Differential flattening can be error prone, therefore I have included unit tests for the FlatTree class, even though Avalonia.Diagnostics at the moment doesn't have any tests (I had to create a test project). If you think the FlatTree class should be in a different project, please let me know.

Checklist

  • [x] Added unit tests (if possible)?
  • [x] Added XML documentation to any related classes?

Breaking changes

n/a

Obsoletions / Deprecations

n/a

Fixed issues

Fixes #14382 (doesn't fix this issue per se, but with this change all supported visual trees can be displayed in the dev tools)

BAndysc avatar Jan 31 '24 00:01 BAndysc

You can test this PR using the following package version. 11.1.999-cibuild0044181-beta. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

avaloniaui-bot avatar Jan 31 '24 00:01 avaloniaui-bot

After I have rebased the change onto Binding System refactor commit, I had to change ContentPresenter to ContentControl in one place:

Change ContentPresenter to ContentControl after Binding System refactor

I have hard time learning when to use ContentPresenter and ContentControl. Was ContentPresenter usage in this place incorrect? Anyway, it worked before the Binding System refactor. Tagging @grokys as some user applications can suffer similar problem.

BAndysc avatar Jan 31 '24 02:01 BAndysc

You can test this PR using the following package version. 11.1.999-cibuild0044189-beta. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

avaloniaui-bot avatar Jan 31 '24 02:01 avaloniaui-bot

You can test this PR using the following package version. 11.1.999-cibuild0044195-beta. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

avaloniaui-bot avatar Jan 31 '24 04:01 avaloniaui-bot

ContentPresenter and friends are only allowed inside ControlTemplates nowhere else. That's by design, but we need better warning here. Max was working on it recently afaik.

timunie avatar Jan 31 '24 06:01 timunie

ContentPresenter and friends are only allowed inside ControlTemplates nowhere else. That's by design, but we need better warning here. Max was working on it recently afaik.

I see, however, since this used to work before (at least in scenario like in the PR), I feel like some user applications might suffer similar problems, which might be difficult to pinpoint, so if it is possible to add a warning, or even better - an error, that would be great.

BAndysc avatar Jan 31 '24 12:01 BAndysc

You can test this PR using the following package version. 11.1.999-cibuild0044232-beta. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

avaloniaui-bot avatar Feb 01 '24 00:02 avaloniaui-bot