Как на заказ сортировать VCL TListBox? - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь выяснить, как предоставить свой собственный метод сортировки для элементов и строк в TListBox.

Мой список хранит пользовательский объект в свойстве Object, и мне нужно использовать его в пользовательской сортировке.

Я основываю приведенный ниже код на этом посте (Delphi): Можно ли отсортировать TListBox с помощью пользовательского компаратора сортировки?

Моя пользовательская функция сортировки выглядит так

int __fastcall SortListByValue (TStringList* sl, int item1, int item2)
{
    IniKey* k1 = (IniKey*) sl->Objects[item1];
    IniKey* k2 = (IniKey*) sl->Objects[item2];
    return k1->mValue < k2->mValue;
}

Значения ключа являются строками. В настоящее время они могут быть «-», «Да», «Нет» и «Пропустить».

И код, где он называется, выглядит так:

void __fastcall TMainForm::sortByValueAExecute(TObject *Sender)
{
    Log(lInfo) << "Sorting list based on Values";
    TStringList* sl = new TStringList();
    sl->Assign(imagesLB->Items);
    sl->CustomSort(SortListByValue);
    imagesLB->Items->Assign(sl);
}

Приведенный выше код «что-то» делает со списком, но он не отсортирован.

Полученный список начинается с элементов «-», а все элементы «Да» являются последовательными. Элементы «Нет» и «Пропустить» и «-» затем шифруются.

Есть какие-нибудь подсказки?

1 Ответ

0 голосов
/ 10 мая 2018

Ожидается, что ваша функция сортировки вернет значение, равное < 0, 0 или > 0, в зависимости от желаемого порядка двух входных параметров. Но вы делаете это неправильно. Вы возвращаете либо 0 или 1, но никогда < 0, потому что вы возвращаете (неявно преобразованный) результат логического выражения, которое может быть только false или true.

Вам необходимо изменить эту строку:

return k1->mValue < k2->mValue;

На это вместо:

if (k1->mValue < k2->mValue) return -1;
else if (k1->mValue > k2->mValue) return 1;
else return 0;

В качестве альтернативы вместо этого используйте функцию RTL AnsiCompareStr() или CompareStr():

return AnsiCompareStr(k1->mValue, k2->mValue);

return CompareStr(k1->mValue, k2->mValue);
...