MFC CListCtrl 虚拟列表使用详解


一、简介

CListCtrl 是MFC 库的一个列表控件,用于显示数据的。可以通过 InsertItem 快速向列表添加一行数据,并且用 SetItemText 设置其后面列的数据项。

但是本篇文章重点不是介绍 CListCtrl 控件的基本使用方法,而是介绍 CListCtrl 的扩展功能“虚拟列表”。

为什么使用虚拟列表?

使用 InsertItem 方法可以显示少量数据,但是数据量大或者是频繁刷新列表数据时,会出现缓慢甚至卡顿的现象。虚拟列表可以很好的解决该问题。

通过什么方式实现虚拟列表?

1、处理 LVN_GETDISPINFO 消息。

2、使用 SetItemCountEx 方法告诉列表要显示多少条数据。

3、使用 RedrawItems 方法刷新指定区间行的数据。

二、实验环境

开发语言:C++

OS 平台:windows 7

SDK:VS 2015

三、正文

3、1 新建一个基于对话框的MFC 工程。

 3、2 在对话框中添加一个 ClistCtrl 控件,并将 view 的属性改为 Report 类型,Owner Data 的属性改为 true 。

3、3 为 CListCtrl 控件绑定变量 m_list1,并向列表添加数据列(OnInitDialog)。

DWORD dwStyle = m_list1.GetExtendedStyle();
	dwStyle |= LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES|LVS_EX_INFOTIP|LVS_EX_DOUBLEBUFFER;
	m_list1.SetExtendedStyle(dwStyle);
	m_list1.InsertColumn(0, "代码",LVCFMT_LEFT, 80);
	m_list1.InsertColumn(1, "名称",LVCFMT_LEFT, 80);
	m_list1.InsertColumn(2, "日期",LVCFMT_LEFT, 80);

3、4 到了这步后,不能直接向列表 InsertItem 数据。是需要定义自己的数据结构和向量。

// TestListVTableDlg.h

// 数据结构
struct WTSTickStruct{
	char arrCode[20];
	char arrName[20];
	char arrDate[20];
};

// 自定义一个向量数据类型
typedef std::vector<WTSTickStruct>  LST_Tick;

在 CTestListVTableDlg 中定义一个向量 

LST_Tick  m_LstTickData;

3、5 初始化向量数据,并通知列表刷新数据(OnInitDialog)

    WTSTickStruct fd1={0};
	WTSTickStruct fd2={0};
	WTSTickStruct fd3={0};

	strcpy(fd1.arrCode, "10000");
	strcpy(fd1.arrName, "test1");
	strcpy(fd1.arrDate, "2021-01-10");

	strcpy(fd2.arrCode, "10001");
	strcpy(fd2.arrName, "test2");
	strcpy(fd2.arrDate, "2021-01-11");

	strcpy(fd3.arrCode, "10002");
	strcpy(fd3.arrName, "test3");
	strcpy(fd3.arrDate, "2021-01-12");

	m_LstTickData.push_back(fd1);
	m_LstTickData.push_back(fd2);
	m_LstTickData.push_back(fd3);

    int iCount = m_LstTickData.size();
	m_list1.SetItemCountEx(iCount);//告诉列表要显示多少数据	
	m_list1.RedrawItems(0,iCount);// 重绘第0~iCount行的数据

3、5 为  CListCtrl 控件添加 LVN_GETDISPINFO 消息,并在该消息函数中填充列表的数据。

void CTestListVTableDlg::OnLvnGetdispinfoList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	LV_ITEM* pItem = &(pDispInfo)->item;  

	if(pItem==NULL) return;
	CString strCell="";
	int iItemIndx=pItem->iItem;//设置虚拟类表绘制的起始位置
	if (pItem->mask & LVIF_TEXT)
	{
		switch(pItem->iSubItem)//iSubitem指列
		{
		case 0:
			{
				lstrcpy(pItem->pszText,m_LstTickData[iItemIndx].arrCode);
			}
			break;
		case 1:
			{
				strCell.Format("%s",m_LstTickData[iItemIndx].arrName);
				lstrcpy(pItem->pszText,strCell);
			}
			break;
		case 2:
			{
				strCell.Format("%s",m_LstTickData[iItemIndx].arrDate);
				lstrcpy(pItem->pszText,strCell);
			}
            break;
		}
	}

	*pResult = 0;
}

3、6 到这里已经完成了虚拟列表的操作,可以编译运行了。

例子下载链接

四、技能扩展

4、1 为虚拟列表添加排序功能,处理 LVN_COLUMNCLICK 消息。

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值