Получить положение объекта в списке в Delphi? - PullRequest
0 голосов
/ 26 апреля 2011

Мне было интересно, как вы получаете положение определенного объекта в списке, который создается.Допустим, это похоже на графический список, где вы можете нажимать на объекты.Допустим, вы щелкаете правой кнопкой мыши по объекту и нажимаете «Обновить», как мне получить позицию этого объекта, чтобы после обновления всего списка (по какой-то причине обновляется с помощью clearlist) я возвращался к той же позиции в списке?Это если список имеет длину, скажем, 1000 объектов, что делает утомительным пытаться прокрутить вниз до той же позиции после обновления.

Код использует Tobject, но могу ли я сделать что-то вроде position: = integer (TObject."pointerinfo ???");И после этого, когда программа обновляется, например, установить позицию представления для указателя, например currentview (указатель) или что-то в этом роде?

На самом деле это не обязательно должен быть тот же объект, но тот же самый вид"списка было бы еще лучше.

Заранее спасибо

Ответы [ 2 ]

4 голосов
/ 26 апреля 2011

Если при обновлении вы снова получите тот же список и в том же порядке, не беспокойтесь об обнаружении чего-либо об объекте. Просто сохраните свойство 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;

И, наконец, если вы вообще не заботитесь о текущем объекте , но просто хотите восстановить текущую позицию прокрутки, тогда это еще проще:

procedure Refresh;
var
  CurrentPosition: Integer;
begin
  CurrentPosition := List.TopIndex;
  RefreshList;
  List.TopIndex := CurrentPosition;
end;
1 голос
/ 27 апреля 2011

Так что я думаю, что с помощью, которую я получил, я ответил на свой вопрос.Что я сделал, так это написал что-то, что заняло x и y позиции списка, и позже, после того, как я сделал обновление с помощью clearlist, я использовал функцию прокрутки, чтобы вернуться к той же функции.Моя программа выглядит примерно так:

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".

Спасибо за всю помощь, это сообщество качается!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...