4

選択した行を内の1つのインデックスの上または下に移動するMoveItemUpメソッドとMoveItemDownメソッドを実装しようとしていTCollectionます。

TCollectionのサブクラスに追加された次のコードは機能しません。

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;

リスト内のコレクションアイテムを並べ替える方法を提供するDelphiIDE自体によって設計時に行われるため、これは実行時に可能である必要があると確信しています。オブジェクトを作成、破棄、または割り当てずに、既存のオブジェクトを並べ替えるだけでこれを実行したいと考えています。これは、Classes.pas TCollectionのサブクラスから可能ですか?(そうでない場合は、ソースクローンから独自のTCollectionを作成する必要がある場合があります)

4

3 に答える 3

9

VCLの情報源によると、手動で行う必要はありません。Index@Sertacが提案するようにプロパティを設定するだけで、問題なく動作するはずです。ソースがある場合は、のコードを確認してくださいTCollectionItem.SetIndex

于 2011-11-28T18:34:25.443 に答える
4

FItems次のようなものを使用できます-コレクションのダミークラスタイプを宣言し、それを使用して、そのコレクションの内部(。)にアクセスしますTList。次に、このメソッドを使用して、実際の移動(または、もちろん、のTList.Exchangeその他の機能)を処理できます。TList

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;
于 2011-11-28T18:32:58.100 に答える
0

DisplayNameで並べ替えるクラスヘルパーソリューションは次のとおりです。必要に応じて並べ替えを改善できます。TStringListを使用して並べ替えを行いました。クラスヘルパーは、クラスヘルパーを含むユニットを参照する場所であればどこでも使用できるため、ユーティリティユニットがある場合はそこに配置します。

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.SortByDisplayNameまたはMyCollectionItem.Collection.SortByDisplayName

于 2014-10-02T20:56:37.480 に答える