DataGridView虚拟模式以简单列表作为源
之前我问过一个关于我的dataGridView性能的问题,因为它显示了大量的行,这些行是根据传入的流添加的。 给出了多个解决方案,其中一个解决方案启用虚拟模式 MSDN有一篇关于这个主题的文章,但它比我使用数据库和可编辑字段所需要的更复杂。 我的DataGridView仅用于显示,我显示的数据放在List中。
在我接受答案后,我收到了这个链接: http : //www.codeproject.com/Articles/23937/PagingANN-with havenGridView-in-VirtualMode 。 即使它使用数据库示例,它也更适合我需要的东西。 包含我要显示的数据的My List声明如下:
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);
在我的表单上加载事件我执行以下操作(与此问题相关。我还添加了一个事件处理程序,尽管这是使用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) { CachedData = FullData.GetRange(lastRowIndex, ((lastRowIndex + PageSize) - 1) - FullData.Count); } /* Full page */ else { CachedData = FullData.GetRange(lastRowIndex, PageSize); } } TotalCount = CachedData.Count; } } }
最后,我对datagrid的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”列表被填满,我的数据网格仍然是空的。 这是我到目前为止所尝试的:
以上都没有改变任何东西。 网格仍然是空的。 我想我错过了一些非常明显的东西。 有什么建议?
-edit-添加了我试图让它工作的东西。
我觉得使用Cache会使这个过程有些复杂化(虽然在向你发送以这种方式实现的msdn链接之后我确实感到有责任)。
我建议作为一个起点是:
-
丢弃缓存(如果你遇到内存问题,这可能会很有用,但是现在让你的数据网格填充)
-
将
List
存储在实例变量中。 -
确保
dataGrid.VirtualMode = true;
(或等同) -
实现CellValueNeeded如下:
private void gridContacts_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { ResultRow dataObject = resultRows[e.RowIndex]; switch(e.ColumnIndex) { case 0: e.Value = dataObject.First; break; case 1 : e.Value = dataObject.Second; break; //etc.. } }
注意:您需要在DataObject中公开一些额外的公共属性,以便可以将它们设置为方法中的值。
看看你如何继续下去。 如果在CellValueNeeded方法中设置了一些断点,这些断点应该有助于调试任何进一步的意外行为。 祝好运。
上述就是C#学习教程:DataGridView虚拟模式以简单列表作为源分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/986941.html