Пользовательская сортировка с помощью 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);
}

Работает как положено:

Другие вопросы по тегам