开发者

Get position of object in a list in Delphi?

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


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;


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!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜