寫這篇文章的人真的是佛心來的耶!超厲害的啦!希望我有一天也能夠寫出這樣的作品 ^___^
轉載內容 
主  题:     讨论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中看到的数据就是排好序的数据了。
沒有留言:
張貼留言