Пользовательская сортировка с помощью CGridCtrl с несколькими столбцами
я сортирую свои
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), но они, похоже, ничего не делают.
1 ответ
Я придумал простое решение. Мне пришло в голову, что я добавляю данные элемента следующим образом:
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);
}
Работает как положено: