Я хочу отобразить «много тяжелых данных» внутри сетки данных в виртуальном режиме.
Я использую буфер, в котором я храню n (2) страниц данных, изначально 2 первые страницы хранятся в буфере. Когда просмотр сетки прокручивается до строки, которая не существует в буфере, я загружаю текущую новую страницу и заменяю ее старой страницей.
Чтобы имитировать загрузку тяжелых данных из базы данных в буфер, я добавил эту строку:
System.Threading.Thread.Sleep (3000);
в результате, при обновлении самого буфера сетка замораживается на этот период времени.
Теперь, как я понимаю, добавление потока здесь не поможет, потому что есть только 1 операция, которая происходит только тогда, когда прокрутка достигает небуферизованной строки.
private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
e.Value = theBuffer.ReturnFromBuffer(e.RowIndex, e.ColumnIndex);
//I check there if row index is in buffer and if not i update the buffer with new page and return the value
}
Поэтому я подумываю добавить анимацию «вращающегося колеса» над гирдом, когда это произойдет.
Я пытался отправить событие в форму, чтобы показать / скрыть изображение в методе, который обновляет буфер:
if (ProgressEvent != null)
ProgressEvent(true);
System.Threading.Thread.Sleep(3000);
if (ProgressEvent != null)
ProgressEvent(false);
и обработчик события формы установил свойство visible изображения, но результат был не таким, как ожидалось, я думаю, что сон произошел до обработки события, поэтому изображение не появилось до сна.
Сом Я думаю, что протектор все еще нужен. Но не могу понять, когда это началось и что он должен делать?
Обновление:
Я устал предложенный фоновый работник:
Внутри метода, вызываемого событием CellValueNeeded, я проверяю, буферизована ли запрошенная строка, если нет, то запускаю backgroundworker.
if (!bgWorker.IsBusy) //otherwise worker will be started for every column of the row
{
bgWorker.DoWork += (sender, e) =>
{
UpdateBuffer(rowIndex);
};
bgWorker.RunWorkerAsync();
}
return "null";
И это:
bgWorker.RunWorkerCompleted += (sender, e) =>
{
if (IvalidateEvent != null)
IvalidateEvent(); //send event to form, where invalidate the gridview dataGridView1.Invalidate();
};
это работает, но есть несколько проблем с этим:
1) Я получил много фиктивных результатов в своей сетке, даже если это ненадолго - мне это не очень нравится.
2) даже если я оставлю все как есть, это займет больше времени, вероятно, потому что backgroundworker потребляет некоторое время и потому что я фактически аннулирую сетку и вызываю событие CellValueNeeded 2 раза (первый запускает backgroundworkerm второй раз, когда он завершает свою работу)!