Работа в виртуальном режиме




DataGridView поддерживает специальный виртуальный режим (Virtual mode) отображения данных. Основная идея такого режима заключена в том, что внутри control-а не хранится никаких данных. Вместо этого DataGridView генерирует события, в обработчиках которых программист может «подсунуть» ему данные, или наоборот, получить данные, введенные пользователем.

«Подсовывать» данные можно только свободным колонкам. Если колонка привязана к источнику данных, то, несмотря на использование виртуального режима, данные для нее будут браться из этого источника.

Колонки для виртуального режима добавляются уже известным нам методом Add коллекции колонок. Со строками все чуть-чуть сложнее. Если grid, находящийся в виртуальном режиме, подключен к источнику данных, то количество строк определяется источником. В противном случае количество строк может быть установлено через свойство RowCount. Строки можно также добавлять с помощью методов Add или Insert коллекции строк. Важно понимать, что метод Add физически не добавляет строк, а всего лишь изменяет значение свойства RowCount. Однако использование Add/Insert имеет некоторый дополнительный смысл, так как при этом, кроме собственно добавления строк, производится некоторая дополнительная работа, связанная с прокруткой, перемещением фокуса ввода и т.д.

Когда grid-у требуется узнать данные ячейки (например, для отрисовки или подбора оптимальной ширины колонки) в виртуальном режиме он генерирует событие CellValueNeeded. Его параметр «e» (типа DataGridViewCellValueEventArgs) имеет три свойства - RowIndex, ColumnIndex и Value. Первые два из них доступны только на чтение и предоставляют целочисленный индекс строки и колонки, соответственно. Свойство Value имеет тип Object и доступно на запись. Собственно, цель обработчика события заключается в том, чтобы на основе индексов колонки и строки вычислить значение ячейки и подставить его в свойство Value. Именно это значение и будет использовать DataGridView в качестве значения ячейки.

Чтобы в виртуальном режиме получить вводимые данные, необходимо реализовать обработчик еще одного события, CellValuePushed. Его параметр «e» имеет тот же тип, что и у события CellValueNeeded, но свойство Value используется не для задания значения ячейки, а наоборот, для считывания значения, введенного пользователем.

Ниже приведен пример примитивной электронной таблицы, данные в которой хранятся в хеш-таблице. Электронная таблица имеет большое количество ячеек. В данном примере это 65 535 строк * 26 (по числу букв английского алфавита) колонок = 1703910. Понятно, что если хранить значения каждой из них займут довольно много памяти. Однако в большинстве случаев в электронной таблице используется очень мало ячеек, которые, тем не менее, могут быть случайным образом разбросаны по всей таблице. Самый эффективный способ хранения в таких условиях – хеш-таблица, ключом которой является сочетание индексов строки и колонки.

Виртуальный режим DataGridView позволяет показывать пользователю всю таблицу (то есть все 1703910 ячеек), но выводит данные только для заполненных ячеек.

using System.Collections.Generic;using System.ComponentModel;using System.Windows.Forms; namespace WindowsApplication1{ public partial class Form1: Form { public Form1() { ((ISupportInitialize)_grid).BeginInit(); _grid.VirtualMode = true; _grid.CellValueNeeded += _dataGridView_CellValueNeeded; _grid.CellValuePushed += _dataGridView_CellValuePushed; _grid.Dock = DockStyle.Fill; // формируем 26 колонок с именами, соответствующими // буквам латинского алфавита for (int i = 0; i < 'Z' - 'A'; i++) { string name = ((char)('A' + i)).ToString(); _grid.Columns.Add(name, name); } _grid.RowCount = ushort.MaxValue; Controls.Add(_grid); ((ISupportInitialize)_grid).EndInit(); } DataGridView _grid = new DataGridView(); // хеш-таблица, хранящая данные заполненных ячеек Dictionary<int, object> _values = new Dictionary<int, object>(); // вычисляет ключ по значениям индексов строки и колонки static int CalcKey(int rowIndex, int columnIndex) { return rowIndex + (columnIndex << 16); } // обработчик события, генерируемого при запросе данных grid-ом private void _dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { object value; if (_values.TryGetValue(CalcKey(e.RowIndex, e.ColumnIndex), out value)) e.Value = value; } // обработчик события, генерируемого при изменении данных ячейки private void _dataGridView_CellValuePushed(object sender, DataGridViewCellValueEventArgs e) { _values[CalcKey(e.RowIndex, e.ColumnIndex)] = e.Value; } }}


Рисунок 16.

Интерес могут представлять также еще несколько событий. Событие NewRowNeeded вызывается, когда grid переходит в режим ввода новой строки. Заметьте, что при этом новая строка еще не создана, и если пользователь сойдет со строки, не введя никаких данных, новая строка создана не будет. Событие CancelRowEdit генерируется, когда пользователь отменяет редактирование или встаку строки. Событие UserDeletingRow генерируется, если пользователь удаляет строку целиком, выделив ее заголовок и нажав клавишу Del.

По ссылке https://msdn2.microsoft.com/en-us/library/2b177d6d(VS.80).aspx можно найти пример реализации работы с большими наборами данных с помощью виртуального режима работы control-а DataGridView. По приведенным там ссылкам можно найти и другие примеры работы с виртуальным режимом. Например, по ссылке https://msdn2.microsoft.com/en-us/library/ms171624.aspx доступен пример, в котором производится динамическая подгрузка данных из большой таблицы БД.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2018-09-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: