Arn*_*176 7 c# virtual datagridview list
之前我问过一个关于我的dataGridView性能的问题,因为它显示了大量基于传入流添加的行.给出了多种解决方案,其中一种解决方案支持虚拟模式 MSDN有一篇关于这个主题的文章,但它感觉比我需要的更复杂,因为它使用数据库和可编辑字段.我的DataGridView仅用于显示,我显示的数据放在List中.
在我接受答案后,我收到了这个链接:http://www.codeproject.com/Articles/23937/PagingANN-with havenGridView-in-VirtualMode.即使使用数据库示例,它也更适合我需要的东西.包含我要显示的数据的My List声明如下:
List<ResultRow> captureResults = new List<ResultRow>();
Run Code Online (Sandbox Code Playgroud)
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 (<the values>) //In actuallity a KeyValuePair
{
//field gets set here
}
public UInt64 Third
{
get { return third; }
set { third = value; }
}
/* etc. */
Run Code Online (Sandbox Code Playgroud)
}
按照上面提到的文章,我创建了一个ResultRowCache.对象如下:
/* Page size set to 100. */
ResultRowCache _cache = new ResultRowCache(PAGE_SIZE, captureResults);
Run Code Online (Sandbox Code Playgroud)
在我的表单上加载事件我执行以下操作(与此问题相关.我还添加了一个事件处理程序,尽管这是使用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;
Run Code Online (Sandbox Code Playgroud)
我想知道的一件事是如何在这里初始化RowCount.它可能是0(由于ResultRowCache的构造函数调用(见下文))但它似乎永远不会再次更改.这项任务是否算作参考?它如何改变自己?
无论如何,继续我所拥有的,ResultRowCache定义如下:
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 );
/* Page already loaded */
if( lastRowIndex == _lastRowIndex ) return;
/* New page */
_lastRowIndex = lastRowIndex;
/* Create a new cashes data object */
if( CachedData == null ) CachedData = new List<ResultRow>();
/* 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我对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 */
}
}
Run Code Online (Sandbox Code Playgroud)
问题:即使"captureResults"列表被填满,我的数据网格仍然是空的.这是我到目前为止所尝试的:
以上都没有改变任何东西.网格仍然是空的.我想我错过了一些非常明显的东西.有什么建议?
-edit-添加了我试图让它工作的东西.
我觉得使用 Cache 会使这个过程变得有些复杂(尽管在向您发送了以这种方式实现的 msdn 链接后,我确实感到有责任)。
我建议作为起点的是:
丢弃缓存(如果您遇到内存问题,这可能会很有用,但现在让您的数据网格填充)
将您的存储List<ResultsRow>在实例变量中。
确保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..
}
}
Run Code Online (Sandbox Code Playgroud)注意:您需要在 DataObject 中公开一些额外的公共属性,以便可以将它们设置为方法中的值。
看看你的进展如何。如果您在 CellValueNeeded 方法中设置一些断点,这应该有助于调试任何进一步的意外行为。祝你好运。
| 归档时间: |
|
| 查看次数: |
12334 次 |
| 最近记录: |