-
Вариант типа:
[CODE]
for ii := -1 + Items.Count downto 0 do
begin
if Selected[ii] then begin Items.Delete(ii);
end;
[/CODE]
не устраивает. Потому что на моих списках 100.000 и выше программа долго обрабатывает задачу в цикле.
Появился вариант записывать в массив номер записи при выделении и затем пускать цикл на удаление нужных записей, где учитывать смещение при удалении. Целесообразно ли так делать?
-
> Появился вариант записывать в массив номер записи при выделении
> и затем пускать цикл на удаление нужных записей, где учитывать
> смещение при удалении. Целесообразно ли так делать?
Как вариант - конечно.
Плюс к этому использовать метод DisableControls.
> Потому что на моих списках 100.000 и выше программа долго
> обрабатывает задачу в цикле.
А нужно ли тебе столько записей в TListBox? - ведь пользователю наверняка неудобно с таким объёмом работать.
Я бы использовал вариант с TDrawGrid - немного сложнее, но и работает несравнимо по скорости.
-
> Потому что на моих списках 100.000 и выше программа долго
> обрабатывает задачу в цикле.
Представляю муки человека, которому надо просмотреть 100500 записей в листбоксе..
-
Внимание! Здесь обсуждаются вопросы, связанные с разработкой компонентов, редакторов свойств, редакторов компонентов и экспертов IDE.
Вопросы по поиску и использованию готовых компонентов, редакторов или экспертов являются нарушением тематики и могут быть удалены.
-
> Появился вариант записывать в массив номер записи при выделении
> и затем пускать цикл на удаление нужных записей, где учитывать
> смещение при удалении. Целесообразно ли так делать?
Да, это было бы более масштабируемо.
Только лучше немного иначе сделать: если считать, что пользователь не будет выделять много записей, то можно хранить в массиве индексы выделенных записей. Тогда перед удалением достаточно отсортировать массив индексов по убыванию и тогда можно удалить нужные записи в одном простом цикле по этому массиву
-
Items.BeginUpdate;
try
for i := Items.Count - 1 downto 0 do
Items.Delete(i);
finally
Items.EndUpdate;
end;
-
Dimka Maslov © (13.01.12 10:52) [5]
Если все удаляются, лучше какой-нибудь Clear использовать - намного быстрее будет.
Тут ему надо что-то типа
Items.BeginUpdate;
try
for i := SelectedItems.length - 1 downto 0 do
Items.Delete(SelectedItems[i]);
finally
Items.EndUpdate;
end;
причем SelectedItems - массив, упорядоченный по возрастанию (если уж downto в этом цикле используем)
-
> Потому что на моих списках 100.000 и выше программа долго
> обрабатывает задачу в цикле.
Если не забывать BeginUpdate и EndUpdate, то на списке в 100.000 отрабатывает за 125 мс. Это при том, что выделенные элементы - в начале.
-
Другой вопрос, нафига в Win32-контроле 100.000 и выше элементов хранить, это же мазохизм?
-
> Компромисс © (13.01.12 10:59) [6]
Смысл тут именно в BeginUpdate..EndUpdate, ибо причина тормоза в их неприсутствии. Остальное – на совести автора.
-
имхо, имеет смысл завести аля дин.массив len = len списка
из [0,1], который бы и казал, удалена строка или нет
а на onIdle физически удалять
-
> имхо, имеет смысл завести аля дин.массив len = len списка
Имеет смысл взять VirtualStringTree от SoftJems, чуть-чуть в нём поразбираться и не иметь после никаких проблем. Хоть миллион элементов вставляй.
-
> лучше какой-нибудь Clear использовать - намного быстрее
> будет
Конечно быстрее, но никто не просил очищать весь ListBox