使用具有多列的 CGridCtrl 进行自定义排序
Custom sorting with CGridCtrl with multiple columns
我现在这样排序 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;
}
本身没有问题。只是如果可能的话,我想添加第二层排序。目前数据在列 DISCUSS_COL_DATE
上排序。如果 lDate1
与 lDate2
相同,那么我希望它在 DISCUSS_COL_NAME
列上排序。但是我不知道如何在网格中建立每个单元格所在的行。
源代码中似乎有一个名为 GetCoords
的方法(在 CodeProject 上找到),但它们似乎什么也没做。
我想到了一个简单的解决方案。我突然想到我正在添加这样的项目数据:
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);
}
按预期工作:
我现在这样排序 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;
}
本身没有问题。只是如果可能的话,我想添加第二层排序。目前数据在列 DISCUSS_COL_DATE
上排序。如果 lDate1
与 lDate2
相同,那么我希望它在 DISCUSS_COL_NAME
列上排序。但是我不知道如何在网格中建立每个单元格所在的行。
源代码中似乎有一个名为 GetCoords
的方法(在 CodeProject 上找到),但它们似乎什么也没做。
我想到了一个简单的解决方案。我突然想到我正在添加这样的项目数据:
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);
}
按预期工作: