Как наполнить просмотр списка большим количеством информации без блокировки?

2

Я создаю массив ListViewItems в фоновом потоке, а затем я заполняю свой список с ним в потоке ui. Проблема в том, что если массив слишком велик, блокируются, когда список обновляется.

Есть ли способ заполнить список с небольшим воздействием на ui?

  • 0
    Winforms или WPF?
Теги:
user-interface
listview
controls

3 ответа

8

Если у вас много данных, которые вы собираетесь использовать, вы можете использовать его в виртуальном режиме, установив свойство VirtualMode элемент управления ListView - true. Это означает, что ListView не будет заполнен в традиционном смысле, но вы подключите обработчики событий, где вы доставляете информацию в виде списка небольшими кусками по мере отображения элементов.

Очень простой пример:

private List<string> _listViewData = new List<string>();
private void toolStripButton1_Click(object sender, EventArgs e)
{
    _listViewData = GetData(); // fetch the data that will show in the list view
    listView1.VirtualListSize = _listViewData.Count; // set the list size
}
// event handler for the RetrieveVirtualItem event
private void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
    if (e.ItemIndex >= 0 && e.ItemIndex < _listViewData.Count)
    {
        e.Item = new ListViewItem(_listViewData[e.ItemIndex]);
    }
}

Вы также должны изучить CacheVirtualItems событие.

0

Мои комментарии заняли довольно много времени, поэтому я решил сделать это отдельным сообщением.

Во-первых, +1 для Фредрика Мёрка, используя VirtualMode, это путь. Однако вы теряете некоторые функциональные возможности, например. автозагрузка столбцов, а сортировка проще обрабатывается самостоятельно.

Если это проблема, заселение из рабочего потока может звучать соблазнительно. Тем не менее, население будет по-прежнему проходить в потоке, которому принадлежит элемент управления списком (т.е. Практически всегда основной поток)..NET делает это видимым, принуждая вас использовать (Begin)Invoke. Кроме того, переключатели контекста значительно увеличивают общее время, необходимое для заполнения всех элементов, если вы заполняете один за другим, поэтому вы хотите заполнить куски (например, 50 пунктов за раз или даже лучше заполнить столько, сколько сможете в 20 миллисекунды). Добавьте к этому дополнительную синхронизацию, необходимую при изменении содержимого, у вас есть довольно сложное решение для не столь звездного результата.

0

Вы также можете использовать методы BeginUpdate и EndUPdate

   listView1.BeginUpdate();
   //Add Values
   listView1.EndUpdate();

Ещё вопросы

Сообщество Overcoder
Наверх
Меню