У меня есть таблица SQL, содержащая в настоящее время 1 миллион строк, которые со временем будут расти.
Существует конкретное требование пользователя представить сортируемую сетку, которая отображает все строки без подкачки. Пользователь ожидает, что сможет очень быстро перейти от строки к строке и сверху вниз с помощью полосы прокрутки.
Я знаком с сетями виртуального режима, которые представляют только видимое подмножество общих данных. Они могут обеспечить отличную производительность пользовательского интерфейса и минимальные требования к памяти (я даже реализовал приложение, использующее этот метод много лет назад).
В Windows Forms DataGridView предусмотрен виртуальный режим, который выглядит как ответ. Однако, в отличие от других виртуальных режимов, с которыми я столкнулся, он по-прежнему выделяет память для каждой строки (подтвержденной в ProcessExplorer). Очевидно, что это приводит к необратимому увеличению общего использования памяти, и, выделяя эти строки, наблюдается заметная задержка. Производительность прокрутки также страдает от 1 миллиона + строк.
Для реального виртуального режима не нужно выделять какую-либо память для строк, которые не отображаются. Вы просто даете ему общее количество строк (например, 1 000 000), и вся сетка действительно масштабирует полосу прокрутки соответственно. Когда он отображается первым, сетка просто запрашивает данные только первые n (скажем, 30) видимых строк, мгновенное отображение.
Когда пользователь прокручивает сетку, предоставляется простое смещение строки и количество видимых строк и могут использоваться для извлечения данных из хранилища данных.
Вот пример кода DataGridView, который я использую в настоящее время:
public void AddVirtualRows(int rowCount)
{
dataGridList.ColumnCount = 4;
dataGridList.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridList.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
dataGridList.VirtualMode = true;
dataGridList.RowCount = rowCount;
dataGridList.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridList_CellValueNeeded);
}
void dataGridList_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
e.Value = e.RowIndex;
}
Мне что-то не хватает, или виртуальный режим DataGridView вообще не виртуальный?
[Обновление]
Похоже, что старый добрый ListView реализует именно тот виртуальный режим, который я ищу. Но, к сожалению, ListView не имеет возможности форматирования ячеек DataGridView, поэтому я не могу его использовать.
Для других, которые могли бы это сделать, я протестировал его с помощью четырех столбца ListView (в подробном режиме), VirtualMode = True и VirtualListSize = 100 000 000 строк.
Список отображается немедленно, когда первые 30 строк видны. Затем я могу быстро прокручиваться до нижней части списка без задержки. Использование памяти постоянно 10 МБ.