Listview的高级应用

如何用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中看到的数据就是排好序的数据了。

你可能感兴趣的:(数据结构,ide)