首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在TCollection中重新排序项目?

如何在TCollection中重新排序项目?
EN

Stack Overflow用户
提问于 2011-11-29 02:20:12
回答 3查看 3.3K关注 0票数 4

我正在尝试实现MoveItemUp和MoveItemDown方法,它们在TCollection中将选定的行上移或下移一个索引。

添加到我的TCollection子类中的以下代码不起作用:

代码语言:javascript
复制
procedure TMyCollection.MoveRowDown(index: Integer);
var
 item:TCollectionItem;
begin
  if index>=Count-1 then exit;
  item := Self.Items[index];
  Self.Delete(index); // whoops this destroys the item above.
  Self.Insert(index+1);
  Self.SetItem(index+1,item); // this actually does an assign from a destroyed object.
end;

我相当肯定这在运行时是可能的,因为它是在设计时由Delphi IDE本身完成的,它提供了一种在列表中重新排序Collection项的方法。我希望通过简单地重新排序现有对象来做到这一点,而不需要创建、销毁或分配任何对象。这在Classes.pas TCollection的子类中是可能的吗?(如果没有,我可能不得不从源克隆制作自己的TCollection )

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-29 02:34:25

根据VCL源代码,您不需要手动执行此操作。只需像@Sertac建议的那样设置Index属性,它就会工作得很好。如果您有源代码,请查看TCollectionItem.SetIndex的代码。

票数 9
EN

Stack Overflow用户

发布于 2011-11-29 02:32:58

您可以使用这样的方法--为一个集合声明一个伪类类型,并使用它来访问该集合的内部FItems,即一个TList。然后,您可以使用TList.Exchange方法来处理实际的移动(当然也可以使用TList的任何其他功能)。

代码语言:javascript
复制
type
  {$HINTS OFF}
  TCollectionHack = class(TPersistent)
  private
    FItemClass: TCollectionItemClass;
    FItems: TList;
  end;
  {$HINTS ON}

// In a method of your collection itself (eg., MoveItem or SwapItems or whatever)
var
  TempList: TList;
begin
  TempList := TCollectionHack(Self).FItems;
  TempList.Exchange(Index1, Index2);
end;
票数 4
EN

Stack Overflow用户

发布于 2014-10-03 04:56:37

这里是一个按DisplayName排序的类帮助器解决方案:如果你喜欢,你可以改进排序,我用了一个TStringList来帮我排序。Class helper在您引用包含类helper的单元的任何地方都可用,所以如果您有一个实用单元,请将它放在那里。

代码语言:javascript
复制
interface

  TCollectionHelper = class helper for TCollection    
  public    
    procedure SortByDisplayName;    
  end;

Implementation

procedure TCollectionHelper.SortByDisplayName;    
var i, Limit : integer;    
    SL: TStringList;    
begin    
  SL:= TStringList.Create;    
  try    
    for i := self.Count-1 downto 0 do    
      SL.AddObject(Items[i].DisplayName, Pointer(Items[i].ID));    
    SL.Sort;    
    Limit := SL.Count-1;    
    for i := 0 to Limit do    
      self.FindItemID(Integer(SL.Objects[i])).Index := i;    
  finally    
    SL.Free;    
  end;    
end;

然后使用方法,简单地假设它是TCollection类的一个方法。这也适用于TCollection的任何子类。

MyCollection.SortByDisplayNameMyCollectionItem.Collection.SortByDisplayName

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8300399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档