使用mfc久了,發現虛擬列表真的很好用,尤其是刷新大量數據時或對時間要求比較嚴格的地方時,但在使用CheckBox時,虛擬列表和ListCtrl默認一行只能在行首加入CheckBox,無法在其他列加入。遇到這種情況,網上的解決方案一般分兩種:1.使用自繪,自己繪製CheckBox。2.使用一些開源的代碼,如XListCtrl等。3.在虛擬列表中下加入圖片(圖片爲勾選和不勾選的兩種ico圖片),當點擊圖片時,進行切換到另一張圖片。在網上搜了一些代碼,可以實現預期的功能,但在數據刷新時出了問題,網上的代碼基本都不實用虛擬列表,採用默認的方式添加數據,這種方式耗時較長,影響了數據的刷新,所以放棄了。最後採用第三種方案。
首先進行初始化,在類中定義CImageList m_IconList;切記該變量不能在初始化時定義成局部變量!下圖爲初始化代碼,其中IDI_ICON_UnCheck和IDI_ICON_Check爲ico圖標,可以自己截屏或到網上找,然後轉換爲ico格式。
m_list_Ctrl.ModifyStyle(WS_VSCROLL,0,0);
//創建ImageList,其中前3個參數分別爲x,y,位圖顏色*/
//如果圖像出來的顏色不對可以試着改下第3項
m_IconList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 10, 4);//ILC_COLOR32 | ILC_MASKILC_COLORDDB
//向ImageList添加圖片
m_IconList.Add(AfxGetApp()->LoadIcon(IDI_ICON_UnCheck));
m_IconList.Add(AfxGetApp()->LoadIcon(IDI_ICON_Check));
//將ImageList設置到ListCtrl中
m_list_Ctrl.SetImageList(&m_IconList, LVSIL_SMALL);
//m_IconList
m_list_Ctrl.GetClientRect(&rect); // 獲取編程語言列表視圖控件的位置和大小
// 爲列表視圖控件添加全行選中和柵格風格
m_list_Ctrl.InsertColumn(0, _T("XXX"), LVCFMT_CENTER, 2*rect.Width()/Total_num, 0);
for(int i = 1;i <= 32;i++)
{
m_list_BmsBalanceCtrl.InsertColumn(i, int2CString(i), LVCFMT_CENTER, 1*rect.Width()/Total_num, i);
}
m_list_Ctrl.SetExtendedStyle(LVS_EX_DOUBLEBUFFER| LVS_EX_GRIDLINES | LVS_EX_LABELTIP|LVIS_SELECTED|
LVIS_FOCUSED|LVS_EX_SUBITEMIMAGES);
然後在Getdispinfo中添加pItem->iImage代碼,我這裏是通過要顯示的數字來判斷是否應該勾選。
void CXXXDlg::OnLvnGetdispinfoListshow(NMHDR *pNMHDR, LRESULT *pResult)
{
//NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
// TODO: 在此添加控件通知處理程序代碼
*pResult = 0;
CString strValue = "",strName = "";
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;
int iItemIndx= pItem->iItem;//獲取行號,會自動根據當前顯示區的行數,更新所有的行
if ((pItem->mask & LVIF_TEXT)||(pItem->mask & LVIF_IMAGE)) //字符串緩衝區有效
{
// then display the appropriate column
UINT8 coloum = getSignalColoum(iItemIndx);
switch(pItem->iSubItem)
{
case 0:
lstrcpy(pItem->pszText,BalanceBMU[iItemIndx]);
break;
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:
case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:
case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:
case 25:case 26:case 27:case 28:case 29:case 30:case 31:case 32:
{
strName = getBalanceSignalValue(iItemIndx,pItem->iSubItem);
lstrcpy(pItem->pszText, (LPCSTR)strName.GetBuffer());
if(pItem->mask & LVIF_IMAGE)
{
if(strName == "1")
{
pItem->iImage=1;
}
else
{
pItem->iImage=0;
}
}
strName.ReleaseBuffer();
}
break;
default:
//ASSERT(0);
break;
}
}
}