Перечисление ListView.SelectedIndices идет медленно на огромном ListView - PullRequest
1 голос
/ 17 сентября 2010

У меня есть ListView с VirtualMode = true и огромным количеством элементов (на данный момент ~ 800 000).

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

Проблема в том, что перечисление всех выбранных элементов занимает много времени, когда выбрано огромное количество элементов. например, для перечисления 800 000 выбранных элементов требуется 1 секунда. Это означает, что для каждого отдельного изменения выбора пользователь должен ждать 1 целую секунду, прежде чем графический интерфейс снова будет реагировать, и это раздражает.

Я не могу понять, почему перечисление выбранных элементов происходит так медленно, перечисление одинакового количества элементов в простом массиве ничего не требует.

Как я могу ускорить процесс перечисления выбранных элементов в ListView?

Ответы [ 3 ]

1 голос
/ 17 сентября 2010

Одна из проблем с WinForms ListView заключается в том, что он построен поверх Win32Control, поэтому каждый запрос ListView должен переходить от управляемого к беспилотному коду и обратно.

var myArray = new int[myListView.SelectedIndices.Count];
myListView.SelectedIndices.CopyTo(myArray) 

может быть быстрее, стоит попробовать

В противном случае вы рассматривали возможность использования WPF? Вы можете написать один элемент управления WPF для списка, а затем разместить его в форме WinForm.

0 голосов
/ 11 октября 2010

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

Вы можете сделать процесс перечисления примерно в два раза быстрее, отправив сообщения непосредственно в элемент управления:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

private void button1_Click(object sender, EventArgs e)
{
    Stopwatch sw = new Stopwatch();

    sw.Start();
    IntPtr h = this.listView1.Handle;
    int j = 0;
    int i = SendMessage(h, 0x100C, -1, 2);
    while (i > -1) {
        j++;
        i = SendMessage(h, 0x100C, i, 2);
    }

    sw.Stop();
    this.toolStripStatusLabel1.Text = String.Format("Timed: {0} items in {1}ms",
        j, sw.ElapsedMilliseconds);
}

На моей машине это вдвое сократило время, необходимое для итерации выбранных элементов.Но этот процесс никогда не будет мгновенным.

0 голосов
/ 17 сентября 2010

Это зависит от того, как вы это делаете, и вы, возможно, захотите немного поработать с некоторым кодом, но вы не можете сохранить промежуточный итог, поскольку каждый элемент выбран, а не просматривается весь список каждый раз при выборесделано?

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