在Delphi中,我有一个基于TList的自己的类。它是TPetList。 TPetList的每个实例都可以包含TPet类的一些项。 TPetList的实例使用for循环显示在TListView组件中。
TPet基于TObject并具有以下字段:
现在我有一个复选框列表,用户可以勾选他想看到的品种。因此,如果他只想看到品种XYZ的宠物,我想只显示“品种”设置为“XYZ”的条目,而TPetList和TListView中的顺序必须保持不变。
我该怎么做?
如果我删除TPetList中的项目并在TListView中显示其余部分,那么一切都很好,直到用户想要查看另一个品种。此品种之前已被删除,无法显示。
答案 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)
通过这种方式,您解决了以下问题:
'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子句)等。OnValidate
事件中进行测试。您拥有所有机制。也许最好走这条路而不是重新发明轮子。