list Control应该是使用频率比较高的控件了,其中一种应用就是在单击其中一列的时候需要进行排序,我也曾经遇到过这个问题,后来花了很长时间才搞懂,呵呵,下面就讲讲怎么对其排序的。
1.首先在界面加入list control控件,设置属性
No Sort Header :false
View :report
2.在窗口类中声明控件成员变量:
CListViewCtrl m_lstTest; //在WTL和MFC中,该控件对应的具体类可能有点不一样,但是大致差不多,先以WTL为例
然后绑定到对应的控件ID
忽略。。。。
3.准备工作好后,就开始下面关键的步骤了。
1)添加全局变量
DWORD dwSelColID =0; //选择的列
BOOL bASC = FALSE; //是否升序
2)添加List事件:LVN_COLUMNCLICK
这样在单击list其中一列的时候就会响应函数:
LRESULT OnLvnColumnclickListGpsdevice(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/);
3)对事件作出响应
LRESULT CTestDlg::OnLvnColumnclickListGpsdevice(int idCtrl, LPNMHDR pNMHDR, BOOL& bHandled)
{
LPNMLISTVIEW pNMLV = reinterpret_cast
// TODO: 在此添加控件通知处理程序代码
if(dwSelColID != pNMLV->iSubItem)//选择的不是相同列
{
dwSelColID= pNMLV->iSubItem;//得到新的列号
bASC = TRUE; //第一次选择是升序排列
}
else
{
bASC = !bASC;//改变排序规则
}
m_lstTest.SortItems(CompareFunc,(LPARAM)(&m_lstTest));
return 0;
}
4)对应函数SortItems,原型如下
BOOL SortItems(PFNLVCOMPARE pfnCompare, LPARAM lParamSort)
pfnCompare:表示一个排序比较函数的指针,下面会讲到。
lParamSort:是需要被排序的对象,这里就是lstTest
5)比较函数CompareFunc
static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort)
{
CListViewCtrl* pListCtrl = (CListViewCtrl*) lParamSort;
LVFINDINFO findInfo;
findInfo.flags = LVFI_PARAM;
findInfo.lParam = lParam1;
int iItem1 = pListCtrl->FindItem(&findInfo, -1);
findInfo.lParam = lParam2;
int iItem2 = pListCtrl->FindItem(&findInfo, -1);
CString strItem1, strItem2;
pListCtrl->GetItemText(iItem1, dwSelColID,strItem1);
pListCtrl->GetItemText(iItem2, dwSelColID,strItem2);
if(bASC)//升序
return strcmp(strItem1,strItem2);
return strcmp(strItem2,strItem1);
}
4.注意:向List中插入数据的时候,要调用函数SetItemData,如下:
。。。。。
CString strInfo("aaa");
m_lstTest.InsertItem(nItemIndex, strInfo);
m_lstTest.SetItemData(nItemIndex,nItemIndex);
。。。。。。。
对于MFC下,方法大致差不多的,只是一些函数有细微的区别了,呵呵,另外,其实ListCtrl中排序有很多种,对应不同的列的数据类型(此次默认都为字符类型),我们还可以设计出更多不同的排序法。