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

发布于 2024-11-03 03:42:49 字数 331 浏览 1 评论 0原文

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

该代码使用 Tobject 但我可以做类似的事情吗 位置:=整数(TObject。“指针信息???”); 之后当程序刷新时 就像将视图的位置设置为指针一样 像 currentview(pointer) 或者类似的东西?

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

提前致谢

I was wondering how you get a position of a certain object in a list that is created.
Lets say it is like a graphical list where you can click on objects.
Lets say you right click on a object and click "Refresh", how do I get the position of that object so that after the whole list is refreshed (refreshes with a clearlist for some reason) i go back to the same position in the list? This is if the list is say 1000 objects long which makes it bothersome to try and scroll down to the same position after the refresh.

The code uses Tobject but can i do something like
position:=integer(TObject."pointerinfo???");
And after that when the program refreshes
like set the position of the view to the pointer
like currentview(pointer) or something like that?

Actually it doesn't have to be the same object, but the same "view" of the list would be even better.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好听的两个字的网名 2024-11-10 03:42:49

如果刷新将再次以相同的顺序为您提供相同的列表,那么就不必费心去发现有关该对象的任何信息。只需存储列表控件的 ItemIndex 属性,该属性指示当前选定的项目。

如果刷新可能会给您一个不同的列表,那么您想要的对象之后可能不在同一位置,因此仅记住 ItemIndex 是不够的。在这种情况下,您需要找到该对象的新位置。如何做到这一点取决于列表控件的功能以及它如何公开与每个位置关联的对象。例如,如果您有一个 TListBox,则 Items 属性是一个 TStrings 对象,您可以检查 Object 数组,直到找到所需的对象。存储对象引用的值,然后搜索它。像这样的事情:

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;

最后,如果您实际上根本不关心当前对象 ,但是只是想要恢复当前的滚动位置,那就更简单了:

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

If refreshing is going to give you the same list again, and in the same order, then don't bother discovering anything about the object. Just store the list control's ItemIndex property, which indicates the currently selected item.

If refreshing might give you a different list, then the object you want might not be at the same position afterward, so just remembering ItemIndex won't be enough. In that case, you'll need to find the new position of the object. How to do that depends on the capabilities of the list control and how it exposes the objects associated with each position. If you have a TListBox, for example, then the Items property is a TStrings object, and you can inspect each value of the Objects array until you find the object you want. Store the value of the object reference, and then search for that. Something like this:

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;

A final possibility is that refreshing doesn't actually keep the same objects at all. All the previous objects are destroyed, and a new list of objects is generated. In that case, you'll have to remember certain identifying characteristics of the original object so you can find the new object that represents the same thing. Something like this:

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;

In all these cases, you should realize that the object's position in the list is not actually a property of the object. Rather, it's a property of the list, which is why the list plays such a bigger role than the object in all that code. There isn't really any "pointerinfo" to get from the object because the object, in general, has no idea it's even in a list, so it certainly won't know its position relative to all the other items in the list.

Once you've determined the position of the object in the list, you need to scroll it into view. For TListBox, a simple way is to set its TopIndex property:

List.TopIndex := ObjectPosition;

And finally, if you don't actually care about the current object at all, but just want to restore the current scroll position, then that's even easier:

procedure Refresh;
var
  CurrentPosition: Integer;
begin
  CurrentPosition := List.TopIndex;
  RefreshList;
  List.TopIndex := CurrentPosition;
end;
琉璃繁缕 2024-11-10 03:42:49

所以我想在我得到的帮助下我回答了自己的问题。
我所做的是编写一些占据列表视图的 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;

也许我应该早点声明它是一个列表视图类型,并且我想在“clearlist”之后再次回到相同的位置。

感谢您的所有帮助,这个社区非常棒!

So I think with the help I got I answered my own question.
What I did was write something that took the x and y position of the listview and later after I did the refresh with a clearlist, I used the scroll function to get back to the same function. My program looks something like this.

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;

Maybe I should've stated earlier that it was a listview type and that I wanted to get back to the same position again after the "clearlist".

Thanks for all the help, this community rocks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文