Что-то подсказывает мне, что когда вы говорите «каждый NodeHeight был изменен», вы действительно хотите сказать, что вы присваивали новые значения непосредственно полю NodeHeight
каждой записи узла.Прежде всего, не делай этого.Если вам необходимо назначить высоты узлам, присвойте их через свойство NodeHeight
дерева.То есть вместо этого:
{*} Node.NodeHeight := x;
Сделайте это:
Tree.NodeHeight[Node] := x;
Это автоматически отрегулирует высоту кэширования всех предков узла, что определяет диапазон полосы прокрутки.
А еще лучше, вообще не назначать высоты узлам.Вместо этого обработайте событие дерева OnMeasureItem
, в котором дерево спросит вас, какова высота каждого узла.Это событие вызывается, когда у вас установлена опция toVariableNodeHeight
.
Если вы действительно настаиваете на том, чтобы пропустить управление высотой узла дерева, то вам необходимо убедиться, что вы обработали all необходимыеЗадачи самостоятельно.Это включает в себя обновление не только поля NodeHeight
, но также поля TotalHeight
узла, его родителя, его деда и т. Д. До тех пор, пока вы не установите общую высоту скрытого корневого узла.Смотрите TBaseVirtualTree.AdjustTotalHeight
для деталей.Он имеет частную видимость, поэтому вы не можете вызывать его самостоятельно.
OnMeasureItem
будет вызываться только один раз для узла.Если вам нужно, чтобы он вызывался снова, потому что содержимое узла изменилось, и вам нужно дерево для повторного измерения высоты, тогда вызовите ReinitNode
.Если вы используете TCustomVirtualStringTree
, вы также можете позвонить InvalidateNode
.