关于Listview(100分)

  • 主题发起人 主题发起人 HuangSkar
  • 开始时间 开始时间
H

HuangSkar

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要使用ListView来显示数据库中的记录,ListView的表头要动态创建,
ListView的显示类型为Report类型,在使用中发现,当数据量比较大时,
Listview的显示速度很慢,记录大约有30000条,不知哪位大虾有高招赐教,
最好给一段代码。
注:我在程序中已经使用了begin update和End update语句.

 
用了begin update和End update语句,只是解决大量输入数据时屏幕不刷新,对于整体性能
来说,提高不大!你记住我这句话:要想从根本上解决添加海量数据时的效率问题,最关键
的是不能一次性的将数据全都装入,其他边边角角的小优化都不起决定性的作用!
下面是我的一段代码,实际上就是做了一个Windows资源管理器右边的文件列表,最主要的
部分如下:
void __fastcall TFrmMain::LvwFileListData(TObject *Sender, TListItem *Item)
{
ItemStruct* OneItem;
if( Item->Index < FileList->Count )
{
OneItem = GetItem(Item->Index);
Item->Caption = OneItem->strName; //文件名
Item->ImageIndex = OneItem->ImageIndex; //图标索引
Item->SubItems->Add( OneItem->strNote ); //注释 //??
Item->SubItems->Add( FormatFloat("#,###0' KB'", OneItem->size/1024) ); //大小
Item->SubItems->Add( OneItem->strType ); //类型
Item->SubItems->Add( FileDateToDateTime(OneItem->time) ); //时间
}
}
//---------------------------------------------------------------------------

void __fastcall TFrmMain::LvwFileListDataHint(TObject *Sender,
int StartIndex, int EndIndex)
{
if( (StartIndex < FileList->Count) &amp;&amp; (EndIndex < FileList->Count) )
HardJob(StartIndex, EndIndex);
}
//---------------------------------------------------------------------------
void __fastcall TFrmMain::FormCreate(TObject *Sender)
{
//。。。。。。。。。。。。。。。。。。。。
/*----------取得文件关联图标的列表,并指向TListView控件----------*/
SHFILEINFO FileInfo;
THandle ImageListHandle;
ImageListHandle = SHGetFileInfo("", 0, &amp;FileInfo, sizeof(FileInfo),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
SendMessage(LvwFileList->Handle, LVM_SETIMAGELIST, LVSIL_SMALL, ImageListHandle);
}
//---------------------------------------------------------------------------
void __fastcall TFrmMain::GotoPath(AnsiString CurrentPath)
{
//在设置路径的开始,就进行数据库的相关查找,此时还没到文件搜索的时候

TCursor SaveCursor;
ItemStruct* OneItem;
TSearchRec sr;
int iFound;

SaveCursor = Screen->Cursor;
LvwFileList->Items->BeginUpdate();
try
{
Screen->Cursor = crHourGlass;
ClearFileList();
iFound = FindFirst(CurrentPath + "*.*", faAnyFile, sr);
while( iFound == 0 )
{
if( (sr.Name != ".") &amp;&amp; (sr.Name != "..") &amp;&amp; ((sr.Attr &amp; faDirectory) != faDirectory) )
{
OneItem = new ItemStruct;
OneItem->strName = sr.Name; //文件名
OneItem->size = sr.Size; //大小
OneItem->time = sr.Time; //日期
FileList->Add(OneItem);
}
iFound = FindNext(sr);
}
FindClose(sr);
LvwFileList->Items->Count = FileList->Count;
// LvwFileList->Repaint();
}
__finally
{
Screen->Cursor = SaveCursor;
LvwFileList->Items->EndUpdate();
}
}
//---------------------------------------------------------------------------
void __fastcall TFrmMain::HardJob(int StartIndex, int EndIndex)
{ //只有在需要的时候,本函数才会被调用,这极大的提升了填充文件列表的速度
AnsiString FileWholeName = "";
TSHFileInfo FileInfo;
int i;
for(i=StartIndex; i<=EndIndex; i++)
{
//此处加入注释
for(int j=0; j<NoteFileList->Count; j++)
{
if(CompareText(NoteFileList->Strings[j], GetItem(i)->strName) == 0)
{
GetItem(i)->strNote = NoteList->Strings[j];
break;
}
}
// FileWholeName = CurrentPath + GetItem(i)->strName;
FileWholeName = CurrentPath + GetItem(i)->strName;
SHGetFileInfo(FileWholeName.c_str(), 0, &amp;FileInfo, sizeof(FileInfo),
SHGFI_TYPENAME | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
GetItem(i)->strType = FileInfo.szTypeName; //文件类型
GetItem(i)->ImageIndex = FileInfo.iIcon; //文件图标索引
}
}
//---------------------------------------------------------------------------


你要想用好ListView,就要仔细研究一下Delphi或C++Builder自带的VirtualListView例子
 
能否写出你的代码来?
 
HD_Copy,
Sorry,我不会用C++Builder,所以看了你可例子云里雾里。
我现在正在研究Delphi自带的VirtualListView的例子,搞不明白例子中申明
的一个记录类型:
_SHITEMID = record
cb: Word; { Size of the ID (including cb itself) }
abID: array[0..0] of Byte; { The item ID (variable length) }
end;
到底记录的是什麽东西,如何操纵它?
望大虾指教。



 
接受答案了.
 
和HuangSkar提出的使用Listview显示海量数据的情况相同,给Item赋值的过程极耗时间.
(1).如果置ListView1.OwnerData := true,赋值过程很快,可以接受.但是,此时ListView
不能排序,即写完OnCompare事件后,在OnColumnClick事件中调用AlphabetSort函数,该函
数的返回值总是false,为什么?
(2).如果OwnerData为true,如何才能使用ListView自带的排序功能呢?
(3).如果自己写排序算法,对于50000-150000条LogRec这样的纪录,怎么写才能最快?
type
LogRec = record
name : string[10];
Id : integer;
Detail: string[200];
end;
(4).如果第一次没有把全部数据分别赋值给Item.caption和SubItems,怎么保证排序
是基于全部数据的结果呢?
以上问题,让我焦头烂额了好一阵子.各位高手哥哥,如果有事例代码,非常希望你能邮往
wenthent@sohu.com,小生潦倒(200块),亦比倾囊致谢也!
 
后退
顶部