Delphi 7:选择TList的某些项目

时间:2010-02-19 19:39:59

标签: delphi class list listview

在Delphi中,我有一个基于TList的自己的类。它是TPetList。 TPetList的每个实例都可以包含TPet类的一些项。 TPetList的实例使用for循环显示在TListView组件中。

TPet基于TObject并具有以下字段:

  • 城市
  • 年龄
  • 品种

现在我有一个复选框列表,用户可以勾选他想看到的品种。因此,如果他只想看到品种XYZ的宠物,我想只显示“品种”设置为“XYZ”的条目,而TPetList和TListView中的顺序必须保持不变。

我该怎么做?

如果我删除TPetList中的项目并在TListView中显示其余部分,那么一切都很好,直到用户想要查看另一个品种。此品种之前已被删除,无法显示。

2 个答案:

答案 0 :(得分:3)

尝试选择新列表,而不是删除。像这样:

function TPetList.Filter(criteria: TPetCriteria): TPetList;
var
  i: integer;
begin
  result := TPetList.Create;
  for i := 0 to self.Count - 1 do
    if criteria.matches(self[i]) then
      result.add(self[i]);
end;

您如何实施标准取决于您,但这是一般的想法。请记住,这个返回的列表是一个子视图,不拥有它包含的项目,所以当你释放过滤后的列表时不要释放它们。

答案 1 :(得分:1)

您可以将对象存储在数据集中。 (您可以使用内存数据集,如TClientDataSet,JVCL的TjvMemoryData或任何其他TDataSet后代,包括完整的RDBMS)

通过这种方式,您解决了以下问题:

  • 持久性(存储) - 您的RDBMS将负责这一点。对于内存数据集,您有像Load / SaveToFile
  • 这样的方法
  • 排序 - 有一些简单的方法可以做到这一点,或者如果您选择一个SQL后端,一个简单的'SELECT * FROM PETS ORDER BY NAME'将完成您的工作
  • 过滤器 - 您可以使用您喜欢的任何操作员对任何字段进行任何可逆过滤。在内存数据集的情况下,将Filter属性设置为 Breed =“foo”,将Filtered属性设置为“True”就足够了。对于RDBMS,您可以使用相同的方式和/或使用标准SQL:'SELECT * FROM PETS WHERE BREED='foo' ORDER BY NAME来实现它。您也可以使用OnFilterRecord事件。当然,您可以清除过滤器,撤消操作:将Filter属性设置为'False' - 或 - 发出类似SQL的'SELECT * FROM PETS'(不带WHERE子句)等。
  • 编辑 - 您对每种数据类型都有专用控件(包括多行输入的网格)。例如。对于“年龄”字段,输入仅限于数字。当然,如果'Age'介于0到33之间(例如),您可以在OnValidate事件中进行测试。

您拥有所有机制。也许最好走这条路而不是重新发明轮子。