I used to ask a question about my dataGridView performance due to the fact that it displayed a large number of rows that are added based on the input stream. Several solutions were provided, one of which allows the use of virtual mode. MSDN has an article on this, but it seems more complex than what I need, as it uses a database and an editable field. My DataGridView is for display only, and the displayed data is put into a list.
After I accepted the answer, I got this link: http://www.codeproject.com/Articles/23937/Paging-Data-with-DataGridView-in-VirtualMode . Although this uses a sample database, it is better suited for what I need. My list, which will contain the data that I want to display, is declared as follows:
List<ResultRow> captureResults = new List<ResultRow>();
A ResultRow object is defined as follows:
public class ResultRow { private int first = 0; private string second = ""; private UInt64 third = 0; private IPAddress fourth = null; public ResultRow() { } public void Set (<the values>)
}
Following the above article, I created ResultRowCache. The object is made as follows:
ResultRowCache _cache = new ResultRowCache(PAGE_SIZE, captureResults);
In my form, Download an event I do the following (related to this problem. I also added an event handler, although this is done using the IDE, so it is not directly shown in this code. Definition below!)):
dataGrid.VirtualMode = true; _cache = new ResultRowCache(PAGE_SIZE, captureResults); dataGrid.Columns.Add("FirstColumn" , "First column header"); dataGrid.Columns.Add("Second Column", "Second column header"); dataGrid.RowCount = (int)_cache.TotalCount;
I am wondering how the RowCount is initialized here. This is probably 0 (due to a call to the ResultRowCache constructor (see below)), but it never changes. Does this designation as a reference? How does this happen?
In any case, starting with what I have, ResultRowCache is defined as follows:
public class ResultRowCache { public int PageSize = 100; public long TotalCount; public List<ResultRow> CachedData = null; private List<ResultRow> FullData; int _lastRowIndex = -1; public ResultRowCache (int pageSize, List<ResultRow> total) { PageSize = pageSize; FullData = total; LoadPage( 0 ); } public void LoadPage (int rowIndex) { int lastRowIndex = rowIndex - ( rowIndex % PageSize ); if( lastRowIndex == _lastRowIndex ) return; _lastRowIndex = lastRowIndex; if( CachedData == null ) CachedData = new List<ResultRow>(); CachedData.Clear(); if (lastRowIndex < FullData.Count) { if (lastRowIndex + PageSize > FullData.Count) { CachedData = FullData.GetRange(lastRowIndex, ((lastRowIndex + PageSize) - 1) - FullData.Count); } else { CachedData = FullData.GetRange(lastRowIndex, PageSize); } } TotalCount = CachedData.Count; } } }
Finally, my CellValueNeeded event for a datagrid is defined as follows:
void DataGridCellValueNeededEvent(object sender, DataGridViewCellValueEventArgs e) { _cache.LoadPage(e.RowIndex); int rowIndex = e.RowIndex % _cache.PageSize; switch (dataGrid.Columns[e.ColumnIndex].Name) { case "FirstColumn": e.Value = _cache.CachedData[rowIndex].First; break; case "SecondColumn": e.Value = _cache.CachedData[rowIndex].Second; break; } }
Problem: my datagrid remains empty even if the captureResults list is populated. Here is what I have tried so far:
- Update the RowCount member of the datagrid after switching in the event.
- Declare a list with the total number of results in the cache so that it is always updated. (I was afraid that the "external changes" would not go into List i, which is passed in the cached constructor, even if it was a link. (Too new version of C #))
- Set the RowCount parameter of the datagrid to 100 (hard value) in the form load event.
- Added a call to "Update ()" in the datagrid after adding something to the captureResults list. (this comes from a special thread that calls a function that adds something to the list)
None of the above has changed anything. The grid remains empty. I think I'm missing something completely obvious here. Any suggestions?
-edit- Added something that I was trying to make it work.