Skip to content

Winforms Tree widget#4235

Open
Oliver-Leigh wants to merge 14 commits intobeeware:mainfrom
Oliver-Leigh:winforms-tree-widget
Open

Winforms Tree widget#4235
Oliver-Leigh wants to merge 14 commits intobeeware:mainfrom
Oliver-Leigh:winforms-tree-widget

Conversation

@Oliver-Leigh
Copy link
Contributor

@Oliver-Leigh Oliver-Leigh commented Mar 12, 2026

Welcome to the Tree widget for the Windows platform!

How it works:

The Tree widget is based on the Table widget, except with some extra structure:

  • The display data is managed by a new class called StateTree which is a wrapper for the TreeSource. It keeps track of which nodes are expanded/collapsed and then makes/modifies a display list which is sent to the UI
  • The nodes are expanded/contracted by clicking a state-change arrow on the left of the row. The state-change arrow also highlights when the cursor is hovering over it. These functionalities are achieved through mouse event actions and a hit-test which determines whether the event has occurred in an appropriate area.
  • The non-leaf nodes are custom painted by handling the NM_CUSTOMDRAW message using the subclass method from Icon support for all columns in Winforms Table #4164.

Notes on Styling:

The styling is based on that of ListView groups, with some modifications. Unfortunately the combination of virtual mode and groups is not supported in WinForms, and is undocumented for Win32. Also, looking at the expansion arrow in the picture on the left below, I don't think that this style is being actively updated.
lv_groups_1 lv_groups_2

The solution is to simply custom draw the row. Here is the current iteration of the Tree widget:
widget_1 widget_2

  • I've put the state-change arrows on the left to align with the macOS and GTK implementations.
  • The colors used by the native ListView groups are undocumented (as far as I know) so I've used the system color hotlight which is a close match.
  • Since the whole row is custom painted, any of the styling can be changed!

Notes for testing:

One of the hardest parts was to get the selection to play nicely with the state-change clicks. The interactions between the clicks-hit-tests and selection is somewhat complicated. Make note of any weirdness you observe in this area!

Changes to the Table widget

I've made some minor changes to the WinForms Table widget code. This is mainly tidying things up a little, but also I've modified some methods so they can be more easily shared with the Tree widget.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

Copy link
Member

@freakboy3742 freakboy3742 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome - thanks! I've flagged a couple of minor style things; but on the whole, the implementation looks really solid (to the extent that I understand win32 stuff), and it definitely works in all my testing.

The one issue of substance that I noticed is around the style of the Tree, and the "blue line" rendering of tree nodes. One detail that isn't exercised in the tree example app is that tree nodes can have data. In the tree example app, you could give a title to each decade:

Screenshot 2026-03-13 at 10 07 51 am

The app is currently using an empty string for each "non column 1" field. That's probably a change we should make to the example, so that it's obvious - but with that change, in the Windows rendering, as soon as a leaf becomes a node, we lose the text for the rest of the node.

You've mentioned that the row style is customisable - is that sort of change in the realm of the possible? I'm guessing that might mean we lose the blue bar - I'm not sure if that's a "dealer's choice" thing from you, or if it's idiomatic on Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants