Sorting 使用CGridCtrl和多列进行自定义排序

Sorting 使用CGridCtrl和多列进行自定义排序,sorting,visual-c++,mfc,cgridctrl,Sorting,Visual C++,Mfc,Cgridctrl,我现在对我的CGridCtrl进行如下排序: m_gridAssignHist.SortItems(pfnCellCompareDate, DISCUSS_COL_DATE, TRUE); 它使用自定义排序功能: int CALLBACK CChristianLifeMinistryDiscussionsDlg::pfnCellCompareDate(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { auto* pCell1 =

我现在对我的
CGridCtrl
进行如下排序:

m_gridAssignHist.SortItems(pfnCellCompareDate, DISCUSS_COL_DATE, TRUE);
它使用自定义排序功能:

int CALLBACK CChristianLifeMinistryDiscussionsDlg::pfnCellCompareDate(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    auto* pCell1 = (CGridCellBase*)lParam1;
    auto* pCell2 = (CGridCellBase*)lParam2;

    if (!pCell1 || !pCell2) return 0;

    auto lDate1 = static_cast<long>(pCell1->GetData());
    auto lDate2 = static_cast<long>(pCell2->GetData());

    if (lDate1 < lDate2)
        return -1;

    if (lDate1 > lDate2)
        return 1;

    return 0;
}
int回调cchristianlifeministrationdiscussionsdlg::pfnCellCompareDate(lparamlparam1、lparamlparam2、lparamlparamsort)
{
auto*pCell1=(CGridCellBase*)lParam1;
auto*pCell2=(CGridCellBase*)lParam2;
如果(!pCell1 | |!pCell2)返回0;
auto lDate1=静态_cast(pCell1->GetData());
auto lDate2=静态_cast(pCell2->GetData());
如果(lDate1lDate2)
返回1;
返回0;
}
它本身没有问题。如果可能的话,我只想添加第二层排序。目前,数据在列
讨论列\u COL\u DATE
上排序。如果
lDate1
lDate2
相同,则我希望它在
discussion\u COL\u NAME
列中排序。但是我不知道如何建立网格中每个单元格所在的行


在源代码(在CodeProject上找到)中似乎有一个名为
GetCoords
的方法,但它们似乎什么都没做。

我想出了一个简单的解决方案。我突然想到,我正在添加如下项目数据:

m_gridAssignHist.SetItemData(iRow, DISCUSS_COL_DATE, CInPlaceDT::GetLongDate(kv.second.datMeeting));
我太傻了!我只是把它改成:

m_gridAssignHist.SetItemData(iRow, DISCUSS_COL_DATE, (LPARAM)&kv.second);
现在,项数据是指向基础列表中的项的指针

我能够调整排序比较功能,如下所示:

int CALLBACK CChristianLifeMinistryDiscussionsDlg::pfnCellCompareDate(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    auto* pCell1 = (CGridCellBase*)lParam1;
    auto* pCell2 = (CGridCellBase*)lParam2;

    if (!pCell1 || !pCell2) return 0;

    auto* pData1 = (CChristianLifeMinistryDefines::S_DISCUSSION_HIST_ITEM*)pCell1->GetData();
    auto* pData2 = (CChristianLifeMinistryDefines::S_DISCUSSION_HIST_ITEM*)pCell2->GetData();

    if (!pData1 || !pData2) return 0;

    if (pData1->datMeeting < pData2->datMeeting)
        return -1;

    if (pData1->datMeeting > pData2->datMeeting)
        return 1;

    return pData1->strName.CollateNoCase(pData2->strName);
}
int回调cchristianlifeministrationdiscussionsdlg::pfnCellCompareDate(lparamlparam1、lparamlparam2、lparamlparamsort)
{
auto*pCell1=(CGridCellBase*)lParam1;
auto*pCell2=(CGridCellBase*)lParam2;
如果(!pCell1 | |!pCell2)返回0;
auto*pData1=(CChristianLiFeministryDefinites::S_DISCUSSION_HIST_ITEM*)pCell1->GetData();
auto*pData2=(CChristianLifeMinistryDefines::S_DISCUSSION_HIST_ITEM*)pCell2->GetData();
如果(!pData1 | |!pData2)返回0;
如果(pData1->datMeetingdatMeeting)
返回-1;
如果(pData1->datMeeting>pData2->datMeeting)
返回1;
返回pData1->strName.CollateNoCase(pData2->strName);
}
按预期工作:


在推广虚拟模式时,性能通常是唯一需要考虑的因素。还有另一个经常被忽视的方面,也是同样重要的:在这种情况下,它强制将关注点、视觉表现和行为(如排序)进行更严格的分离。使用虚拟模式,您可以单独更改:如果决定添加列、对列重新排序或更改列的显示,则只需更新显示代码。排序将保持不变。@dxiv否,用户对排序没有选择,您不能通过单击标题进行排序。对于我的软件的这一部分,这是一种“按设计”的方法。这种方式对用户来说是有意义的,因为它是需要升序的日期敏感信息。任何其他呈现数据的方式都会使该工具对于轻松确定下一步选择的对象毫无意义。但是谢谢你的评论——总的来说,它们是有效的!为什么不使用
CMFCListCtrl
native小部件?design支持按多列排序。@sergiol这是一个使用CGridCtrl将近20年的项目。那么为什么现在要重做呢?但我可以调查你提到的那个班级!IIRC,我在参考资料中使用了一个普通的列表控件,但在我的dialog类中使用了一个
CMFCListCtrl
成员变量。我想我在VisualStudio/微软Visual C++包中输入了 Stase< /Cord>文件夹。