在Delphi的列表中获取对象的位置?

时间:2011-04-26 12:33:41

标签: delphi list listview tobject

我想知道如何在创建的列表中获取某个对象的位置。 让我们说它就像一个图形列表,您可以在其中单击对象。 让我们说你右键单击一个对象并单击“刷新”,如何获取该对象的位置,以便刷新整个列表后(由于某种原因刷新清单)我回到列表中的相同位置?如果列表长度为1000个对象,那么在刷新后尝试向下滚动到相同位置会很麻烦。

代码使用Tobject,但我可以做类似的事情 位置:=整数(TObject的 “pointerinfo ???”); 之后程序刷新 比如将视图的位置设置为指针 像currentview(指针)或类似的东西?

实际上它不一定是同一个对象,但列表的相同“视图”会更好。

提前致谢

2 个答案:

答案 0 :(得分:4)

如果刷新将再次以相同的顺序为您提供相同的列表,那么就不要去发现有关该对象的任何内容。只需存储列表控件的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;

在所有这些情况下,您应该意识到对象在列表中的位置实际上不是对象的属性。相反,它是列表的属性,这就是为什么列表在所有代码中扮演比对象更大的角色。没有任何“指针信息”从对象中获取,因为对象通常不知道它甚至列表中,所以它肯定不知道它相对于所有的位置列表中的其他项目。

确定对象在列表中的位置后,需要将其滚动到视图中。对于TListBox,一种简单的方法是设置其TopIndex属性:

List.TopIndex := ObjectPosition;

最后,如果你根本不关心当前的对象,但只是想恢复当前的滚动位置,那就更容易了:< / p>

procedure Refresh;
var
  CurrentPosition: Integer;
begin
  CurrentPosition := List.TopIndex;
  RefreshList;
  List.TopIndex := CurrentPosition;
end;

答案 1 :(得分:1)

所以我想在得到的帮助下,我回答了自己的问题。 我所做的是写一些取得listview的x和y位置的东西,之后我用清单进行刷新后,我使用了scroll函数来回到同一个函数。我的程序看起来像这样。

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;

也许我早些时候已经说过它是一个listview类型,我想在“清单”之后再次回到同一位置。

感谢所有的帮助,这个社区摇滚!