• CMFCListCtrl控件排序(转)


    项目开发工具为VS2010,对于用惯了VC6的我来说,有些新特性摸起来真有些费神。这两天为了一个数据显示列表弄得云里雾里的。

    背景是这样的:

    1、要在界面中显示数据库中数据(表格形式),每列要有标题名。

    2、数据库中的一个字段可能要拆分称两列进行显示。

    3、显示的数据要能任意列进行排序,每列的数据可能有重复值。

    因此,我使用了“列表”控件。后来听说VS2010中有个CMFCListCtrl的类用起来要比CListCtrl方便。就使用了CMFCListCtrl去关联该控件。然后为了排序,重载了CMFCListCtrl的OnCompareItems()函数,在该函数中添加了同列两项值的大小比较算法,并根据比较结果返回(1/0/-1)。当我惊叹于MFC的进化时,麻烦开始了。发现排序对于有重复值的列并不是准确的,总是在排了几次后就打乱了顺序。并且由此导致,两列(某一列中有重复值)交替排序不正确。

    通过不懈努力,终于在坛子里搜到了答案:

    要点一:添加一项的时候要使用SetItemData(i,i)绑定一个序号,该序号要唯一。

      CString str;
      str.Format(_T("%d"), i);
      m_ListDB_sblx.InsertItem(i, str);
      m_ListDB_sblx.SetItemData(i, (DWORD)i);    // 一般就设置一个唯一的值.不唯一排序可能有点乱,


    要点二:重载比较函数时,要通过下面的方法才能保证正确的取出要比较的字段。


    //重载的排序比较函数:用于比较两个项的大小关系
    int CMFCListCtrlEx::OnCompareItems(LPARAM lParam1, LPARAM lParam2, int iColumn) 
    {
        // 取出两个比较项内容
        CString strItem1,strItem2;
        LVFINDINFO lvfi;
        lvfi.flags=LVFI_PARAM;
        lvfi.lParam=lParam1;
        strItem1 = GetItemText(FindItem(&lvfi,-1),iColumn);
        lvfi.lParam=lParam2;
        strItem2 = GetItemText(FindItem(&lvfi,-1),iColumn); 

        //第0列按整数排序
       if (iColumn == 0 )
       {
            int nItem1 = _ttoi(strItem1);
            int nItem2 = _ttoi(strItem2);

            if (nItem1 == nItem2)  
           {  
                return 0;  
           }
           else
                return(nItem1 < nItem2 ? -1 : 1);
        }
        else
        {
              //比较字符串
             int iSort = _tcsicmp(strItem1, strItem2);
             return(iSort);
        }
    }

    在注意了以上两点之后,控件置为"Report"类型,把控件的"Sort"属性置为"None",再设置其他属性。即可得到正确的排序结果。

  • 相关阅读:
    git 学习
    C语言 do while 语句
    C语言 计算班级平均成绩以及不及格的人数
    C语言 加减算法
    C语言 两个日期间的天数计算
    C语言 梯形面积
    C语言 while语句
    C语言 分段函数if else语句
    C语言 乘法运算
    C语言学习,for循环
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/2036359.html
Copyright © 2020-2023  润新知