0

作成されたリスト内の特定のオブジェクトの位置をどのように取得するのか疑問に思いました。オブジェクトをクリックできるグラフィックリストのようなものだとしましょう。オブジェクトを右クリックして[更新]をクリックすると、そのオブジェクトの位置を取得して、リスト全体が更新された後(何らかの理由でクリアリストで更新された後)、リスト内の同じ位置に戻るにはどうすればよいですか。 ?これは、リストの長さが1000オブジェクトであるため、更新後に同じ位置までスクロールダウンするのが面倒な場合です。

コードはTobjectを使用していますが、position:= integer(TObject。 "pointerinfo ???");のようなことを行うことができます。その後、プログラムが更新されたときに、ビューの位置をcurrentview(pointer)などのポインターに設定しますか?

実際には、同じオブジェクトである必要はありませんが、リストの同じ「ビュー」の方がさらに優れています。

前もって感謝します

4

2 に答える 2

5

更新すると同じリストが同じ順序で表示される場合は、オブジェクトについて何も気にしないでください。ItemIndex現在選択されているアイテムを示すリストコントロールのプロパティを保存するだけです。

更新すると別のリストが表示される場合は、必要なオブジェクトが後で同じ位置にない可能性があるため、覚えておくだけItemIndexでは不十分です。その場合、オブジェクトの新しい位置を見つける必要があります。これを行う方法は、リストコントロールの機能と、各位置に関連付けられたオブジェクトをどのように公開するかによって異なります。TListBoxたとえば、がある場合、プロパティItemsはオブジェクトであり、必要なオブジェクトが見つかるまで配列TStringsの各値を調べることができます。Objectsオブジェクト参照の値を格納してから、それを検索します。このようなもの:

procedure Refresh;
var
  CurrentSelection: TObject;
  ObjectPosition: Integer;
  i: Integer;
begin
  if List.ItemIndex >= 0 then
    CurrentSelection := List.Strings.Objects[List.ItemIndex]
  else
    CurrentSelection = nil;
  RefreshList;
  ObjectPosition := -1;
  if Assigned(CurrentSelection) then begin
    for i := 0 to Pred(List.Count) do begin
      if List.Strings.Objects[i] = CurrentSelection then begin
        ObjectPosition := i;
        break;
      end;
    end;
  end;
  if ObjectPosition = -1 then
    // Object isn't in refreshed list
  else
    // It is.
end;

最後の可能性は、更新しても実際には同じオブジェクトがまったく保持されないことです。以前のオブジェクトはすべて破棄され、オブジェクトの新しいリストが生成されます。その場合、同じものを表す新しいオブジェクトを見つけることができるように、元のオブジェクトの特定の識別特性を覚えておく必要があります。このようなもの:

var
  CurrentObject, Person: TPerson;
  CurrentName: string;
  i, ObjectPosition: Integer;
begin
  if List.ItemIndex >= 0 then begin
    CurrentObject := List.Strings.Objects[List.ItemIndex] as TPerson;
    CurrentName := CurrentObject.Name;
  end else
    CurrentName = '';
  RefreshList;
  ObjectPosition := -1;
  if CurrentName <> '' then begin
    for i := 0 to Pred(List.Count) do begin
      Person := List.Strings.Objects[i] as TPerson;
      if Person.Name = CurrentName then begin
        ObjectPosition := i;
        break;
      end;
    end;
  end;
  if ObjectPosition = -1 then
    // Object isn't in refreshed list
  else
    // It is.
end;

これらすべての場合において、リスト内のオブジェクトの位置は実際にはオブジェクトのプロパティではないことを理解する必要があります。むしろ、それはリストのプロパティであるため、リストはそのすべてのコードのオブジェクトよりも大きな役割を果たします。オブジェクトは、一般に、リスト内にあることを認識していないため、オブジェクトから取得する「pointerinfo」は実際にはありません。したがって、リスト内の他のすべてのアイテムに対する相対的な位置は確かにわかりません。

リスト内のオブジェクトの位置を決定したら、それをスクロールして表示する必要があります。の場合TListBox、簡単な方法はそのTopIndexプロパティを設定することです。

List.TopIndex := ObjectPosition;

そして最後に、現在のオブジェクトを実際にはまったく気にせず、現在のスクロール位置を復元したいだけの場合は、さらに簡単です。

procedure Refresh;
var
  CurrentPosition: Integer;
begin
  CurrentPosition := List.TopIndex;
  RefreshList;
  List.TopIndex := CurrentPosition;
end;
于 2011-04-26T13:12:14.577 に答える
1

だから私は私が得た助けを借りて私自身の質問に答えたと思います。私がしたことは、リストビューのxとyの位置をとる何かを書くことでした。後で、クリアリストで更新を行った後、スクロール関数を使用して同じ関数に戻りました。私のプログラムはこんな感じです。

procedure Refresh(Sender: TObject);
var
  horzpos:integer;
  vertpos:integer;
begin
    horzpos:=ListView1.ViewOrigin.X;
    vertpos:=ListView1.ViewOrigin.Y;
    RefreshListView(ListView1); //A function that refreshes the list and clears it
    ListView1.Scroll(horzpos, vertpos);
 end;

たぶん、それはリストビュータイプであり、「クリアリスト」の後で同じ位置に戻りたいと前に述べたはずです。

すべての助けに感謝します、このコミュニティは揺れ動きます!

于 2011-04-27T12:46:27.430 に答える