Thanks for the suggestion, this has now been implemented: https://feedback.objo.dev/feature/1125
For ListBox:
ListBox.RefreshRow(row As Integer)
ListBox.RefreshRows(rows As Array(Of Integer))
For TreeView:
TreeView.RefreshNode(node As TreeViewNode)
TreeView.RefreshNodes(nodes As Array(Of TreeViewNode))
I used Refresh rather than Redraw to remain consistent with the existing Control.Refresh() method. TreeView accepts node objects because visible row indexes change as nodes are expanded or collapsed.
These methods repaint only the requested rows or nodes that are currently visible. They do not scroll the control, recalculate its layout, or materialise off-screen items. The plural methods batch the repaint and ignore duplicates.
The existing Refresh() method remains available when the entire control needs repainting, including ListBox headers and the empty area below its rows.