Я хочу отобразить «много тяжелых данных» внутри datagridview в виртуальном режиме.Виртуальный режим Datagridview с тяжелой нагрузкой
Я использую буфер, в котором храню n (2) страниц данных, изначально 2 первых страницы хранятся в буфере. Когда gridview прокручивается до строки, которая не существует в буфере, я загружаю текущую новую страницу и меняю ее на старую страницу.
Чтобы имитировать загрузку тяжелых данных из базы данных в буфер, я добавил эту строку: 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);
и обработчик события формы установить видимое свойство изображения, но результат был не так, как ожидалось, я предполагаю, что Сон произошел до того, как было обработано событие, поэтому изображение не появилось перед сном.
Сом, я думаю, что протектора по-прежнему необходимо. Но не может понять, когда он начался и что он должен делать?
Update:
Я устал предложенный фон работник:
Внутри метода, который вызывается неоспоримым 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) это даже занимает больше времени, если я просто оставил его как есть, возможно, потому, что работник фокуса потребляет некоторое время, и потому что я фактически недействителен сетью и вызываю событие CellValueNeeded 2 раза (сначала он снова запускает backgroundworkerm во второй раз, когда он заканчивает работу)!
аннулирование всей сетки немного напоминает «перебор» ... это также перекрасит все ячейки, которые имеют правильные значения, а не только те, у которых есть соски. другой подход, чтобы избежать фиктивных значений при прокрутке через сетку, заключался бы в том, чтобы реагировать на прокрутку. попробуйте получить строки, близкие к отображаемым строкам, прежде чем они будут запрошены, в этом случае значения, вероятно, будут там до того, как CellNeedsValue запросит их – DarkSquirrel42
@ DarkSquirrel42, CellNeedsValue буферизует не только нужную строку, но и ряд строк вперед. единственная проблема, когда мне нужно загружать новые строки. Я не против замораживания сетки, но анимация должна появляться так, как бывает. без фиктивных значений –
, когда datagridview поднимает cellvalueneeded, вы можете указать значение, которое будет отображаться в ячейке. если у вас нет этого значения, вы не можете его указать. поэтому у вас есть 2 варианта: 1) либо предоставить «загрузку» -сообщения, либо ничего (пустую строку), заполнить свой буфер в асинхронной операции и когда данные будут готовы к обновлению ячейки. или вариант 2) синхронно заполнять буфер и возвращать требуемое значение. конечно, вариант 2 блокирует поток пользовательского интерфейса, поэтому никакая загрузка анимации, перерисовка формы или взаимодействие с пользователем не будут доступны (если вы не делаете плохие вещи, такие как Application.DoEvents - это будет больно отлаживать) – DarkSquirrel42