Translate

2009/08/19

[轉載]加快你ADD Items的速度!virtual list、vector for TListview教學

寫這篇文章的人真的是佛心來的耶!超厲害的啦!
希望我有一天也能夠寫出這樣的作品 ^___^
轉載自:300分求解决listview大量数据添加慢的方法



主  题: 讨论ListView里显示十万级以上记录时,象SQL Server里的返回所有行的方式显示记录,怎么实现?

作  者: cmsoft (韦小宝是我的老乡)

等  级:

信 誉 值: 100

所属论坛: C++ Builder 基础类

问题点数: 99

回复次数: 38

发表时间: 2002-12-31 9:57:02

回复人: bigwhiteshark(大白鲨) ( )

信誉:被封杀

哈哈正中本人下怀

如何用TListView来处理大量数据

采用常规方法处理ListView,在数据量大时无论是还是用了BeginUpdata和EndUpdata()

还是处理WM_EraseBkgnd信息都不会得到理想的效果,那答案是什么呢?嗯,

采用所谓Virtual ListView技术。说起来很神秘,其实点通了很简单。

通常ListView中的所有数据都是由ListView自己来管理的,它负责这些数据空间的分配和释放,

当你把ListView->OwnerData设为true时,ListView就把数据的管理权交给了你,而它只负责显示。

这时你需要自己来为数据分配和释放空间,至于你怎样来管理这些数据完全有你自己来定,

ListView完全不关心,当ListView需要显示某条数据时,它就调用OnData事件,

你只要在这个事件的处理函数里指定ListView即将显示的Item的内容就可以了。

这就是所谓的Virtual ListView技术。

由于ListView对数据管理的功能强大,随之而来的却是效率低下,

如果你采用更高效的数据管理方式就会极大的改变效率。

而且Virtual ListView只在数据需要显示时才调用OnData事件载入数据,所以速度很快。
  下面的例子中,假设ListView中需要显示4列数据,所有的数据被保存在vector里。

/*Unit1.h*/
//---------------------------------------------------------------------------
#ifndef Unit1H

#define Unit1H

//---------------------------------------------------------------------------
#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ComCtrls.hpp>

#include <vector.h>

using namespace std;

//---------------------------------------------------------------------------

struct ListViewData //用於存儲一條資料的結構體

{

AnsiString Caption;

AnsiString SubItems1;

AnsiString SubItems2;

AnsiString SubItems3;

};

class TForm1 : public TForm

{

__published: // IDE-managed Components

TListView *ListView1;

void __fastcall ListView1Data(TObject *Sender, TListItem *Item);

private: // User declarations

vector<ListViewData*> m_lvDataVector; //用於存儲所以資料的向量

public: // User declarations

__fastcall TForm1(TComponent* Owner);

__fastcall ~TForm1();

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

/*unit1.cpp*/

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop
#include "Unit1.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

ListView1->OwnerData = true;

const int iListViewCount = 5000;

ListView1->Items->Count = iListViewCount; //必須指定,以使ListView知道其虛擬資料量

//保存資料

for(int i = 0; i < iListViewCount; ++i) {

ListViewData *plvData = new ListViewData;

plvData->Caption = "Caption" + AnsiString(i);

plvData->SubItems1 = "SubItems1" + AnsiString(i);

plvData->SubItems2 = "SubItems2" + AnsiString(i);

plvData->SubItems3 = "SubItems3" + AnsiString(i);

m_lvDataVector.push_back(plvData); //向vector中添加一項

}

}

__fastcall TForm1::~TForm1()

{

int iCount = ListView1->Items->Count;

for(int i = 0; i < iCount; ++i) {

ListViewData *plvData = m_lvDataVector[i];

delete plvData; //釋放資料佔用的資源

}

m_lvDataVector.clear(); //清空vector中所有條目

}

//---------------------------------------------------------------------------

//ListView在要顯示某條資料時會調用這個函數

void __fastcall TForm1::ListView1Data(TObject *Sender, TListItem *Item)

{

if(Item->Index > m_lvDataVector.size())

return;

ListViewData *plvData = m_lvDataVector[Item->Index];

//指定要顯示的條目的資料

Item->Caption = plvData->Caption;

Item->SubItems->Add(plvData->SubItems1);

Item->SubItems->Add(plvData->SubItems2);

Item->SubItems->Add(plvData->SubItems3);

}

//---------------------------------------------------------------------------


速度很快,5000条数据只要1秒左右.

在使用Virtual ListView方式时,如果要对数据排序,只需对你保存的内部数据(这里时vector对象)排序,然后ListView->Refresh()即可。这时你在ListView中看到的数据就是排好序的数据了。

沒有留言:

張貼留言

DataSnap REST API Authorization with PHP

About Authentication with DataSet REST JavaScript client. In connection.js: function setCredentials(user, password) { connectionInf...