gpt4 book ai didi

c# - 以简单列表为源的 DataGridView 虚拟模式

转载 作者:太空狗 更新时间:2023-10-29 20:37:17 25 4
gpt4 key购买 nike

之前我问过一个关于我的 dataGridView 性能的问题,因为它必须显示大量根据传入流添加的行。给出了多种解决方案,其中一种启用虚拟模式。 MSDN 上有一篇关于这个主题的文章,但感觉比我需要的更复杂,因为它使用了数据库和可编辑字段。我的DataGridView只是用来显示的,我显示的数据放在一个List中。

在我接受答案后,我收到了这个链接:http://www.codeproject.com/Articles/23937/Paging-Data-with-DataGridView-in-VirtualMode .尽管它使用了一个数据库示例,但它更适合我的需要。包含我要显示的数据的我的列表声明如下:

List<ResultRow> captureResults = new List<ResultRow>();

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. */

按照上面提到的文章,我创建了一个 ResultRowCache。对象制作如下:

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

在我的表单 Load 事件上,我执行以下操作(与此问题相关。我还添加了一个事件处理程序,尽管这是使用 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 的构造函数调用(见下文))但它似乎再也没有改变过。这个作业算作引用吗?它如何 self 更新?

无论如何,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;
}
}
}

最后,我的数据网格 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(硬值)。
  • 在将某些内容添加到 captureResults 列表后,添加了对数据网格的“Update()”调用。 (这是从一个特殊线程发生的,该线程调用了一个向列表添加内容的函数)

以上都没有改变任何东西。网格仍然是空的。我想我在这里遗漏了一些非常明显的东西。有什么建议吗?

-edit- 添加了一些我试图让它工作的东西。

最佳答案

我觉得缓存的使用使过程有些复杂化(尽管在向您发送以这种方式实现的 msdn 链接后我确实感到有责任)。

我推荐的起点是:

  1. 丢弃缓存(如果您以后遇到内存问题,这可能会有用,但现在让我们只填充您的数据网格)

  2. 存储您的 List<ResultsRow>在实例变量中。

  3. 确保dataGrid.VirtualMode = true; (或等同的)

  4. 按如下方式实现 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 中公开一些额外的公共(public)属性,以便它们可以在方法中设置为值。

看看你是怎么做到的。如果您在 CellValueNeeded 方法中设置一些断点,应该有助于调试任何进一步的意外行为。祝你好运。

关于c# - 以简单列表为源的 DataGridView 虚拟模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10512981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com