В Delphi как ссылаться на объекты, которые были созданы с использованием только одной переменной? - PullRequest
0 голосов
/ 25 февраля 2019

Я создавал форму с несколькими кнопками во время выполнения в своем приложении, и я понял, что меня очень беспокоит, и я не мог понять ни себя, ни где-либо еще в Интернете.

Посмотрите на следующий код.

procedure TfrmTest.CreateFourButtons(Sender: TObject);
var
  i: Integer; B: TButton;
begin
  for i := 1 to 4 do
    begin
      B := TButton.Create(frmTest);
      B.Parent := frmTest;
      B.SetBounds(250,(70+(30*i)),75,25);
      B.Caption := 'Button' + IntToStr(i);
      B.Visible := True;
    end;
end;

Итак, я только что создал четыре кнопки во время выполнения на форме в определенных местах.Пока все хорошо, верно?

Но теперь давайте представим, что я хочу изменить свойство Caption первой кнопки на «HotPotato»?Как мне теперь ссылаться на первую кнопку, поскольку я использовал только одну переменную для создания этих кнопок?Мне сказали хранить эти объекты в массиве TButtons или, что еще лучше, в TObjectList, и все они являются прекрасным решением этой проблемы.Но потом мне в голову пришел один вопрос!

Где находятся эти кнопки в памяти?Есть ли у меня способы ссылаться на них без использования массивов или списков объектов?

1 Ответ

0 голосов
/ 25 февраля 2019

Обычный способ отслеживать несколько похожих объектов - использовать массив.

procedure TfrmTest.CreateFourButtons(Sender: TObject);
var
  i: Integer; 
  B: TArray<TButton>; //or array of TButton for older versions
begin
  SetLength(B, 4);
  for i := 0 to 3 do begin
    B[i] := TButton.Create(frmTest);
    B[i].Parent := frmTest;
    B[i].SetBounds(250,(70+(30*i)),75,25);
    B[i].Caption := 'Button' + IntToStr(i);
    B[i].Visible := True;
  end;
  B[0].Caption:= 'HotPotato';
end;

При размещении кнопок на форме это не является строго необходимым, форма уже использует список для отслеживания размещенных на ней дочерних элементов управления, но вам потребуется какой-то способ различения различных кнопок.,

Для этого можно использовать свойство tag:

  for i := 1 to 4 do begin
    B := TButton.Create(frmTest);
    B.Parent := frmTest;
    B.Tag:= i;
    ...
  end;
  //This will get inefficient if there are many controls on a form.
  for var C in frmTest.Controls do begin  //10.3 syntax.
    if (C is TButton) and (C.tag = 1) then C.Caption:= 'HotPotato'
  end;

button - это объект, и поэтому он находится в куче.Если вы потеряете его ссылку, вы никогда не найдете его снова.Однако, если он размещен на родительском элементе управления, этот родитель будет отслеживать его, и вы всегда можете получить его, используя FindChildControl или список Controls формы.

FindChildControl выполняет поиск по имени.Для этого необходимо указать имя элемента управления, иначе оно не будет работать.

var B:= frmTest.FindChildControl('Button1');

Примечание : FindChildControl находит только непосредственные дочерние элементы элемента управления.Он не может найти элемент управления, являющийся дочерним по отношению к одному из дочерних элементов элемента управления.

Это обнаружение дочерних элементов может усложниться, если кнопка расположена в подпанели.Лучше использовать массив или список, чтобы отслеживать диапазон кнопок.

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