Виртуальный режим Datagridview с большой загрузкой данных - PullRequest
1 голос
/ 21 апреля 2011

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

Я использую буфер, в котором я храню 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 второй раз, когда он завершает свою работу)!

1 Ответ

2 голосов
/ 21 апреля 2011

когда вы достигнете небуферизованной строки, вызовите свой код, чтобы получить необходимые данные во 2-м потоке (новый поток, пул потоков, фоновый работник ... выберите один)

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

(здесь вы, вероятно, захотите отключить части вашего пользовательского интерфейса до завершения операции)

на данный момент возвращает пустую строку или какое-либо другое фиктивное значение...

ваша асинхронная операция должна получить нужные данные и затем вызвать другой метод потока пользовательского интерфейса (вызовите Invoke (...) для объекта вашей формы)

вызов invoke необходим, чтобы избежатьмежпотоковое взаимодействие с пользовательским интерфейсом

в вызываемом методе вы должны использовать извлеченные данные, чтобы заполнить ваш буфер, скрыть элемент управления «loading ...», сделать недействительными соответствующие строки или ячейки (у datagridview есть методы для этого) и, наконец, при необходимости включите ваш пользовательский интерфейс

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