listview内容多的时候 显示很慢 怎么解决?

MBWQ 2006-03-05 07:53:24
用listview现实文件 当一个文件夹里文件很多时 全部显示出就很慢 文件少时 也不快
但是资源管理器就显示很快 它是怎么做的呢?
...全文
312 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
菜牛 2006-03-06
  • 打赏
  • 举报
回复
使用虚拟列表:

虚拟列表控件指具有 LVS_OWNERDATA 样式的列表视图 (ListView) 控件。该样式启用控件来支持项数达到 DWORD(默认的项数只扩展到 int)。然而,该样式的最大便利是可以使内存中一次只有一个数据项子集。这使虚拟列表视图 (ListView) 控件可以将自己借给大型信息数据库使用,而在这类数据库中已存在特定的数据访问方法。

注意 MFC 除了在 CListCtrl 中提供虚拟列表功能外,还在 CListView 类中提供相同的功能。
在开发虚拟列表控件时应注意一些兼容性问题。有关更多信息,请参见 Platform SDK 中“列表-视图控件”主题的“兼容性问题”一节。

处理 LVN_GETDISPINFO 通知
虚拟列表控件维护非常少的项信息。除了项选择和焦点信息,所有项信息都由控件的所有者管理。框架通过 LVN_GETDISPINFO 通知消息来请求信息。若要提供请求的信息,虚拟列表控件的所有者(或控件本身)必须处理该通知。使用“属性”窗口可以很容易地完成此操作(请参见将消息映射到函数)。所得到的代码应类似于下面的示例(其中 CMyListCtrl 是虚拟列表控件对象,控件正在处理通知)。

BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
END_MESSAGE_MAP()
在 LVN_GETDISPINFO 通知消息的处理程序中,必须检查正在请求的信息的类型。可能值是:

LVIF_TEXT 必须填写 pszText 成员。
LVIF_IMAGE 必须填写 iImage 成员。
LVIF_INDENT 必须填写 iIndent 成员。
LVIF_PARAM 必须填写 lParam 成员。
LVIF_STATE 必须填写 state 成员。
然后应将所有请求的信息提供给框架。

下面的示例摘自列表控件 (List Control) 对象的通知处理程序体,它通过为文本缓冲区和项的图像提供信息来说明一种可能的方法:

LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;

int iItemIndx= pItem->iItem;

if (pItem->mask & LVIF_TEXT) //valid text buffer?
{
switch(pItem->iSubItem){
case 0: //fill in main text
lstrcpy(pItem->pszText,
m_Items[iItemIndx].m_strItemText);
break;
case 1: //fill in sub item 1 text
lstrcpy(pItem->pszText,
m_Items[iItemIndx].m_strSubItem1Text);
break;
case 2: //fill in sub item 2 text
lstrcpy(pItem->pszText,
m_Items[iItemIndx].m_strSubItem2Text);
break;
}
}

if pItem->mask & LVIF_IMAGE) //valid image?
pItem->iImage=
m_Items[iItemIndx].m_iImageIndex;
缓存和虚拟列表控件
由于这种类型的列表控件 (List Control) 是提供给大的数据集的,因此建议您缓存请求的项数据以提高检索性能。框架提供缓存提示机制,通过发送 LVN_ODCACHEHINT 通知消息来帮助优化缓存。但是,您必须使用一种稍有不同的方法来处理该通知。使用“属性”窗口,重写列表控件 (List Control) 对象的 OnChildNotify 函数。在该示例的情况下为 CMyListCtrl。

在处理程序体中检查 LVN_ODCACHEHINT 消息,如果找到,则准备缓存。

下面的示例(摘自 OnChildNotify 函数体)执行此检查并调用 CMyListCtrl 类的 PrepCache 成员函数。

NMLVCACHEHINT* pcachehint=NULL;

if (message == WM_NOTIFY)
{
NMHDR* phdr = (NMHDR*)lParam;

switch(phdr->code)
{
case LVN_ODCACHEHINT:
pcachehint= (NMLVCACHEHINT*) phdr;
// Load the cache with the recommended range.
PrepCache(pcachehint->iFrom, pcachehint->iTo);
break;
default:
return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);
}
return FALSE;
}
else
return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);
注意,如果消息类型不是 LVN_ODCACHEHINT,则通知将传递给基类 (CListCtrl)。有关准备和维护缓存的更多信息,请参见 Platform SDK 中的“列表-视图控件”主题的“缓存管理”一节。

查找特定的项
当需要查找特定的列表控件项时,虚拟列表控件发送 LVN_ODFINDITEM 通知消息。列表视图 (ListView) 控件接收快捷键访问或接收 LVM_FINDITEM 消息时发送该通知消息。搜索信息以 LVFINDINFO 结构的格式发送,该结构是 NMLVFINDITEM 结构的成员。通过重写列表控件 (List Control) 对象的 OnChildNotify 函数来处理该消息,并在处理程序体中检查 LVN_ODFINDITEM 消息。如果找到此消息,则执行相应的操作。

您应该准备好搜索与列表视图 (ListView) 控件给定的信息匹配的项。如果成功,则应返回项的索引;如果没有找到匹配项,则返回 -1。

MBWQ 2006-03-06
  • 打赏
  • 举报
回复
好象不行 下面是代码 请指教
void CTreeViewDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult)
{
m_list.DeleteAllItems();
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
TVITEM item = pNMTreeView->itemNew;
if(item.hItem == m_hRoot)
return;
CString str = GetFullPath(item.hItem);
if(str.Right(1) != "\\")
str += "\\";
str += "*.*";
CFileFind file;
BOOL bContinue = file.FindFile(str);
m_list.SetRedraw(FALSE);
while(bContinue)
{
bContinue = file.FindNextFile();
if(!file.IsDirectory() && !file.IsDots())
{
SHFILEINFO info;
CString temp = str;
int index = temp.Find("*.*");
temp.Delete(index,3);
SHGetFileInfo(temp + file.GetFileName(),0,&info,sizeof(&info),SHGFI_DISPLAYNAME | SHGFI_ICON);

int i = m_ImageList.Add(info.hIcon);
m_list.InsertItem(i,info.szDisplayName,i);
}
}
m_list.SetRedraw(true);
m_list.Invalidate();
m_list.UpdateWindow();

*pResult = 0;
}
cnwolf 2006-03-05
  • 打赏
  • 举报
回复
不要每插入一条纪录就重画

SetRedraw(false);

插入数据

SetRedraw(true);
ListView异步加载图片,图片错位问题解决方案 * 问题分析:我们在使用AsyncTask异步下载图片的时候,经常会用到convertView的重用,一般情况下,滑动后第一个可见的元素(我们给它命个名,称为A1)和 * listview的第一个元素(A)是公用一个convertView的(一般情况),此时问题就来了,如果异步下载图片执行的比较慢,第一个元素对应的url * 下载的图片会放到第一个元素上面还是滑动后第一个可见的元素上面呢? * 解决方案:给每个listview的ImageView设置tag,使用findViewWithTag()的方式来得到ImageView,此时图片就不会产生错位了。而且 * 值得注意的是,由于A和A1使用同一个convertView,因此如果A中的ImageView已经有值得话,当A2展示的并且它所对应的图片还未加载完成的时候, * A2会显示A上的图片,这明显是不对的,因此我们这里给它设置一个默认的icon,即mHolder.mImageView.setImageResource(R.drawable.ic_launcher); * 思路简介:一般listview中涉及到图片加载的,为了提高用户体验,一般会使用一个软引用和存文件的方式来实现。不过还见过这样来实现的:即用一个HashMap来存放很小一部分的数据, * 当HashMap中的大小达到一定的值时,清空HashMap,并且将数据放入软应用中。 * 注意操作sdcard权限已经网络访问权限的加入

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧