Почему тормозит TreeView?

184
01 января 2020, 20:00

При большом количестве веток дерева, у меня начинает тормозить TreeView, а точнее, обычная операция присвоения имени ветки:

treeView1.SelectedNode.Text = "hello!";

Тестирую на разных компьютерах. Эта операция может занимать от 100 мс до 1 сек при 35 тыс веток. Если больше, то время пропорционально увеличивается. Можно ли решить эту проблему?

Answer 1

Это известная проблема всех UI элементов. Собственно снижение производительности с увеличением числа элементов, в первую очередь связано с тем, что отрисовка и обработка другой логики всех UI элементов выполняется в одном потоке (по этой же причине не рекомендуется в логике контролов лазить за данными в БД или выполнять тяжелые вычисления). При этом надо учитывать, что одна из самых тяжелых операций, при нормальном использовании контролов, - отрисовка, выполняется даже для тех элементов, которые в данный момент не отображаются (находятся за границами родительского контрола при скроле или, как в случае с TreeView, "свернуты" под "плюсик"). Таким образом, не важно как вы разместите N тысяч UI элементов, в видимой области формы, спрячете за скролом или TreeView - "тормозить" будет абсолютно одинаково - пропорционально их количеству.

Решение тоже известное - виртуализация отображения.

Применительно к TreeView, это можно реализовать например так:

  1. Дерево элементов храним в отдельном объекте.
  2. При первичном отображении TreeView заполняем только видимый уровень элементов.
  3. На событие TreeView.BeforeExpand вешаем обработчик, который будет заполнять дочерние элементы узла до их отображения в видимой области.
  4. На событие TreeView.AfterCollapse вешаем обработчик, который будет удалять дочерние элементы узла после их скрытия из видимой области.

Это конечно увеличит время выполнения разворачивания и сворачивания узлов, но заметно прибавит производительности при большом количестве элементов. Исключительный случай, в котором данный прием не сработает - все узлы на одном уровне. Но это скорее вырожденный случай и потребуется менять способ их отображения.

READ ALSO
Invoke метода из стартового Appdomain

Invoke метода из стартового Appdomain

Создал новый Appdomain,загрузил в него сборкуТеперь нужно вызвать код из метода в в основном Appdomain

129
Как сделать запрос на удаление?

Как сделать запрос на удаление?

Подскажите, как удалить определенные строки в базе данных, если они просрочились на 1 день

148
Некорректная обработка IndexOf или же нет?

Некорректная обработка IndexOf или же нет?

Данный код возвращает 0, хотя по документации должен возвращать -1Я что-то не правильно делаю? Версия

133