Как эффективно отфильтровать большую коллекцию LIstViewItemCollection? - PullRequest
1 голос
/ 04 октября 2008

Итак, у меня есть ListView с верхним пределом около 1000 элементов. Мне нужно иметь возможность фильтровать эти элементы с помощью события TextChanged текстового поля. У меня есть код, который хорошо работает для меньшего количества элементов (~ 400), но когда мне нужно повторно отобразить полный список всех 1000 элементов, это занимает около 4 секунд.

Я не создаю новые элементы ListViewItems каждый раз. Вместо этого я сохраняю список всей коллекции предметов, а затем добавляю из нее. Кажется, что метод .Add занимает много времени независимо. Вот маленький образец:

this.BeginUpdate();
foreach (ListViewItem item in m_cachedItems)
{
    MyListView.Add(item);
}
this.EndUpdate;

Я пробовал только добавлять недостающие элементы (то есть разницу между отображаемыми в данный момент элементами и общим списком элементов), но это тоже не работает. Может возникнуть ситуация, когда в данный момент отображается только один элемент, пользователь очищает текстовое поле, и мне нужно отобразить весь список.

Я не очень опытен в оценке производительности элементов управления .NET с такой большой выборкой, поэтому я не знаю лучшего способа сделать это. Есть ли способ обойти использование метода .Add (), или, если нет, просто лучшее общее решение?

Ответы [ 4 ]

4 голосов
/ 04 октября 2008

Есть лучший способ, вы можете использовать VirtualMode представления списка.

Эта документация должна помочь вам начать. Идея состоит в том, чтобы предоставлять информацию в ListView только по мере необходимости. Такая информация извлекается с использованием событий. Все, что вам нужно сделать, это реализовать эти события и сообщить представлению списка, сколько элементов в нем содержится.

3 голосов
/ 04 октября 2008

AddRange намного быстрее, чем добавить

MyListView.AddRange(items)
2 голосов
/ 04 октября 2008

Для решения этой проблемы есть две вещи:

  1. Отключить сортировку при работе с содержимым списка.
  2. Скрыть список, чтобы он не пытался рисовать.

1-й момент - это самый большой прирост производительности при манипулировании списками из этих двух. Чтобы достичь этого, просто установите для ListViewItemSorter значение null на время модификации и установите его обратно в конце.

Для 2-го варианта я часто рисую список в растровом изображении, а затем показываю это растровое изображение в PictureBox, чтобы пользователь не видел исчезновение списка, а затем просто заново отображаю список, когда я закончу.

0 голосов
/ 04 октября 2008

Также обратите внимание, что вы можете скрывать предметы и делать их невидимыми, не удаляя их. Поэтому добавляйте все свои вещи в первый раз, а потом просто спрячьте те, которые больше не нужны, и покажите те, которые вам нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...