ListCtrl点击表头排序的总结

要使用CListCtrl点击表头进行排序的功能:

    对ListCtrl排序的总结;

    记得还要添加Sort属性(在资源里)

    要实现这个功能,首先要调用c_lstRcdData.SetItemData(i,i);遍历每一个元素,
    然后就是点击表头的消息处理了,注意:这里非常关键,因为有两个消息都可以响
应表头被点击的的操作,一个标准的是void UCFVDataSel::OnColumnclickListRcddata(NMHDR *pNMHDR, LRESULT *pResult);
但是在排序里面不要用这个,因为它传的第一个参数老是出问题,所有用另一个:
void UCFVDataSel::OnItemclickListRcddata(NMHDR *pNMHDR, LRESULT *pResult);这个虽然看起来不像
点击表头触发的消息,但是它确实是啊,贴一段我完整的关于这个消息处理的函数:
void UCFVDataSel::OnItemclickListRcddata(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMHEADER pNMLV = reinterpret_cast<LPNMHEADER>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
static int sSortColumn = 0;


//让它不显示上下三角
HDITEM hdrItem;
c_lstRcdData.GetHeaderCtrl()->GetItem(sSortColumn, &hdrItem);
hdrItem.mask = HDI_FORMAT;
hdrItem.fmt &= ~(HDF_SORTDOWN | HDF_SORTUP);
c_lstRcdData.GetHeaderCtrl()->SetItem(sSortColumn, &hdrItem);


//点击相同列,排序方式变反。
//点击不同列,升序排列
static int nAsc = 1;
if(sSortColumn == pNMLV->iItem)
{
nAsc = - nAsc;
}
else
{
sSortColumn = pNMLV->iItem;
nAsc = 1;
}


//显示上三角或下三角
c_lstRcdData.GetHeaderCtrl()->GetItem(sSortColumn, &hdrItem);
hdrItem.mask = HDI_FORMAT;
if(nAsc == 1)
{
hdrItem.fmt |= HDF_SORTUP;
hdrItem.fmt &= ~HDF_SORTDOWN;
}
else
{
hdrItem.fmt |= HDF_SORTDOWN;
hdrItem.fmt &= ~HDF_SORTUP;
}
c_lstRcdData.GetHeaderCtrl()->SetItem(sSortColumn, &hdrItem);


PSORTDATA pSortData = new SORTDATA;
pSortData->nAsc = nAsc;
pSortData->pList = &c_lstRcdData;
pSortData->nSubItem = sSortColumn;
c_lstRcdData.SortItems(SortFunc,(DWORD_PTR)pSortData);


*pResult = 0;
}
其它的注释已经很清楚了,大家运行一下就知道是什么了,需要注意看的是倒数第二句代码
c_lstRcdData.SortItems(SortFunc,(DWORD_PTR)pSortData);这就是API,第一个是回调函数,第二个参数是
回调函数的参数,我把完整的回调函数也贴出来了
///
/// \brief
///  自定义排序函数
/// 
/// \param lParam1
///  第一行数据
///
/// \param lParam2
///  第二行数据
///
/// \param lParamSort
///  自定义数据结构SortData类型变量,SortItems()函数的第二个参数
///
/// \return 
///  第一个数据大于第二个数据返回正数,否则返回负数
int CALLBACK SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
PSORTDATA pSortData = (PSORTDATA) lParamSort;
CListCtrl *pList = pSortData->pList;
int nSubItem = pSortData->nSubItem;
int nAsc = pSortData->nAsc;


//find item index
LVFINDINFO  findInfo;
findInfo.flags = LVFI_PARAM;
findInfo.lParam = lParam1;
//1st index
int nPrevIndex = pList->FindItem(&findInfo, -1);
findInfo.lParam = lParam2;
//2nd index
int nNextIndex = pList->FindItem(&findInfo, -1);


//get item string
CString strPrev = pList->GetItemText(nPrevIndex, nSubItem);
CString strNext = pList->GetItemText(nNextIndex, nSubItem);


int prev = 0, next = 0;
switch ( nSubItem )
{
case  0:
prev = _ttol(strPrev);
next = _ttol(strNext);
if (prev > next)
return nAsc;
else
return -nAsc;
case  1:
strPrev.Replace( _TEXT("/"),_TEXT("") );
strNext.Replace( _TEXT("/"),_TEXT("") );
strPrev.Replace( _TEXT(":"),_TEXT("") );
strNext.Replace( _TEXT(":"),_TEXT("") );
strPrev.Replace( _TEXT(" "),_TEXT("") );
strNext.Replace( _TEXT(" "),_TEXT("") );
prev = _ttol(strPrev);
next = _ttol(strNext);
if (prev > next)
return nAsc;
else
return -nAsc;
default:
return _tcscmp(strPrev, strNext) * nAsc;
}
}
只需几步,我们的功能就实现了,哦对了,还有这个结构
/// ListCtrl排序用的结构
typedef struct SortData
{
int nAsc; //1或-1
CListCtrl *pList;
int nSubItem;
} SORTDATA, * PSORTDATA;

完整的代码在我的资源里面,资源名字叫《ListCtrl分页》,因为同时实现了分页显示和排序的功能

注意!!!!!!

      排序有一个问题就是ListCtrl会屏蔽掉内容相同的项,一定要注意这个问题

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值