Виртуальный режим DataGridView с простым списком в качестве источника

Ранее я задавал вопрос о производительности моего dataGridView из-за того, что он должен отображать большое количество строк, которые добавляются на основе входящего потока. Было предложено несколько решений, одно из которых включает виртуальный режим. В MSDN есть статья на эту тему, но она кажется более сложной, чем мне нужно, поскольку использует базу данных и редактируемое поле. Мой DataGridView предназначен только для отображения, а данные, которые я отображаю, помещаются в список.

После того, как я принял ответ, я получил эту ссылку: http://www.codeproject.com/Articles/23937/Paging-Data-with-DataGridView-in-VirtualMode. Несмотря на то, что в этом примере используется база данных, он лучше подходит для того, что мне нужно. Мой список, который будет содержать данные, которые я хочу отобразить, объявляется следующим образом:

List captureResults = new List();

Объект ResultRow определяется следующим образом:

/* Simplified */
public class ResultRow
{
    private int first = 0;
    private string second = "";
    private UInt64 third = 0;
    private IPAddress fourth = null;
    /* etc */

    public ResultRow()
    {
    }

    public void Set () //In actuallity a KeyValuePair
    {
        //field gets set here
    }

    public UInt64 Third
    {
        get { return third; }
        set { third = value; }
    }

    /* etc. */

}

Следуя упомянутой выше статье, я создал ResultRowCache. Объект создается следующим образом:

/* Page size set to 100. */
ResultRowCache _cache   = new ResultRowCache(PAGE_SIZE, captureResults);

В моей форме Load event я делаю следующее (связанное с этой проблемой. Я также добавил обработчик событий, хотя это делается с помощью IDE, поэтому в этом коде это напрямую не показано. Определение ниже!)) :

dataGrid.VirtualMode = true;

_cache = new ResultRowCache(PAGE_SIZE, captureResults);

dataGrid.Columns.Add("FirstColumn"  , "First column header");
dataGrid.Columns.Add("Second Column", "Second column header");
/* Etc. Adding all columns. (Every member or ResultRow has it's own column. */

dataGrid.RowCount = (int)_cache.TotalCount;

Мне интересно, как здесь инициализируется RowCount. Вероятно, он равен 0 (из-за вызова конструктора ResultRowCache (см. ниже)), но, похоже, он больше никогда не меняется.Это задание считается рекомендацией? Как он обновляется?

Во всяком случае, дальше с тем, что у меня есть, ResultRowCache определяется следующим образом:

public class ResultRowCache
{
    public int  PageSize    = 100;
    public long TotalCount;
    public List CachedData = null;
    private List FullData;

    int _lastRowIndex = -1;

    public ResultRowCache (int pageSize, List total)
    {
        PageSize = pageSize;
        FullData = total;

        LoadPage( 0 );
    }

    public void LoadPage (int rowIndex)
    {
         int lastRowIndex = rowIndex - ( rowIndex % PageSize );

         /* Page already loaded */
         if( lastRowIndex == _lastRowIndex ) return;

         /* New page */
         _lastRowIndex = lastRowIndex;

         /* Create a new cashes data object */
         if( CachedData == null ) CachedData = new List();

         /* If cached data already existed, clear */
         CachedData.Clear();

         /* The index is valid (there is data */
         if (lastRowIndex < FullData.Count)
         {
             /* Not a full page */
             if (lastRowIndex + PageSize > FullData.Count)
             {
                 CachedData = FullData.GetRange(lastRowIndex, ((lastRowIndex + PageSize) - 1) - FullData.Count);

             }
            /* Full page */
            else
            {
                CachedData = FullData.GetRange(lastRowIndex, PageSize);
            }
        }

        TotalCount = CachedData.Count;
    }
    }
}

Наконец, мое событие CellValueNeeded для сетки данных определяется следующим образом:

void DataGridCellValueNeededEvent(object sender, DataGridViewCellValueEventArgs e)
{
    _cache.LoadPage(e.RowIndex);

    int rowIndex = e.RowIndex % _cache.PageSize;

    switch (dataGrid.Columns[e.ColumnIndex].Name)
    {
        /* Not actual names, example */
    case "FirstColumn":   e.Value = _cache.CachedData[rowIndex].First;  break;
        case "SecondColumn":  e.Value = _cache.CachedData[rowIndex].Second; break;
        /* Rest of the possibly columns/ResultRow values */
    }
}

Проблема: Моя сетка данных остается пустой, хотя "captureResults" список заполняется. Вот что я пробовал до сих пор:

  • Обновить элемент RowCount сетки данных после переключения в событии.
  • Объявите список с общим количеством результатов в кеше, чтобы обеспечить его постоянную актуальность. (Я боялся, что «внешние модификации» не попадут в список, который я передал в кэшированном конструкторе, даже если это была ссылка. (Довольно новое в C#))
  • Установите для RowCount сетки данных значение 100 (жесткое значение ) в событии загрузки формы.
  • Добавлен вызов «Update()» для сетки данных после добавления чего-либо в список CaptureResults. (это происходит из специального потока, который вызывает функцию, добавляющую что-то в список)

Ничего из вышеперечисленного ничего не изменило. Сетка остается пустой. Я думаю, что мне не хватает чего-то совершенно очевидного здесь. Какие-либо предложения?

-edit- Добавил кое-что, что я пытался заставить работать.

7
задан Arnold4107176 9 May 2012 в 09:14
поделиться