如何自定义排序 VCL TListBox?

Posted

技术标签:

【中文标题】如何自定义排序 VCL TListBox?【英文标题】:How to custom sort a VCL TListBox? 【发布时间】:2018-05-09 23:19:11 【问题描述】:

我试图弄清楚如何为 TListBox 中的项目和字符串提供我自己的自定义排序方法。

我的列表框在其Object 属性中存储了一个自定义对象,我需要在自定义排序中使用它。

我将以下代码基于这篇文章 (Delphi):Is it possible to sort a TListBox using a custom sort comparator?

我的自定义排序函数如下所示

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);

上面的代码对列表做了“一些事情”,但它没有排序。

结果列表以“-”项开头,所有“是”项都是连续的。然后将“否”、“通过”和“-”项目打乱。

有什么线索吗?

【问题讨论】:

我相信我正在查看 TStringList 的旧代码。我会在一秒钟内更新新代码 【参考方案1】:

您的排序函数应返回&lt; 00&gt; 0 的值,具体取决于所需的两个输入参数的顺序。但是你没有正确地做到这一点。您正在返回 01,但从不返回 &lt; 0,因为您正在返回布尔表达式的(隐式转换)结果,它只能是 falsetrue

你需要改变这一行:

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);

【讨论】:

以上是关于如何自定义排序 VCL TListBox?的主要内容,如果未能解决你的问题,请参考以下文章

python中自定义排序函数

Delphi TListView(TListBox+图标显示)

python之自定义排序函数sorted()

MySQL自定义排序

31Arrays数组排序(续)——自定义排序

sql 自定义排序