Delphi→ Компоненты в массиве TObjectList
Сен 16, 2010
Недавно, при написании одной из программ, столкнулся с проблемой большого количества элементов на форме. А именно 20 объектов TShape, 20 объектов TEdit и 100 объектов TMaskEdit.
Проблема заключается в том, что при операциях с этими элементами через программный код, его необходимо было бы тиражировать ровно столько раз, сколько этих элементов, а в каждой новой копии изменять только имя элемента (например, Edit1, Edit2 и т.д.) Недостатки такого метода достаточно серьезны: большая вероятность допустить ошибку при изменении имени в каждом блоке; в случае каких-либо изменений кода, его потребуется менять во всех блоках; исходник разрастается до тысяч строк и становится менее понятен и т.д. Обратится к элементам, как к массиву, в виде Edit[i].Text в цикле не получится.
Что же делать? Мы будем использовать класс TObjectList из модуля Contnrs, который позволит нам добавить все элементы в массив, после чего к ним можно обращаться через индекс.
uses Windows, [...], Contnrs;
Как пользоваться? Для начала необходимо добавить в раздел uses модуль Contnrs, затем для каждого типа объекта (TShape, TEdit, TMaskEdit и т.д.) определить класс на основе TObjectList.
Пример для TEdit (размещается между uses и implementation):
type
TEditList = class(TObjectList)
{TEditList имя нового класса, на основе TObjectList}
private
function GetItems(Index: Integer): TEdit; {Заменить TEdit на нужный тип: TShape, TMaskEdit и т.д.}
procedure SetItems(Index: Integer; const Value: TEdit); {Заменить TEdit на нужный тип: TShape, TMaskEdit и т.д.}
published
public
property Items[Index: Integer]: TEdit read GetItems write SetItems; default; {Заменить TEdit на нужный тип: TShape, TMaskEdit и т.д.}
end;
Затем добавляем объявленные функции и процедуры после строки implementation. Эти функции отвечают за установление и получение значений через оператор квадратные скобки [].
{GetItems}
function TEditList.GetItems(Index: Integer): TEdit; {Заменить TEdit на нужный тип: TShape, TMaskEdit и т.д.}
begin
Result := TEdit(inherited GetItem(Index)); {Заменить TEdit на нужный тип: TShape, TMaskEdit и т.д.}
end;
{SetItems}
procedure TEditList.SetItems(Index: Integer; const Value: TEdit); {Заменить TEdit на нужный тип: TShape, TMaskEdit и т.д.}
begin
inherited SetItem(Index, Value);
end;
Теперь можно объявить переменную этого класса и использовать её как массив, предварительно заполнив его нужными элементами.
Объявляем переменную EditList:
var EditList: TEditList;
Добавляем в массив визуальные элементы (код можно разместить в событии OnCreateформы):
EditList := TEditList.Create(); EditList.Add(Edit1.Text); EditList.Add(Edit2.Text); EditList.Add(Edit3.Text); EditList.Add(Edit4.Text); ...
Пример обращения к элементу Edit1.Text:
EditList[0].Text := 'TEST';
Исходный текст полностью:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ComCtrls, Contnrs;
type
TfrmCallbase = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Edit7: TEdit;
Edit8: TEdit;
Edit9: TEdit;
Edit10: TEdit;
Edit11: TEdit;
Edit12: TEdit;
Edit13: TEdit;
Edit14: TEdit;
Edit15: TEdit;
Edit16: TEdit;
Edit17: TEdit;
Edit18: TEdit;
Edit19: TEdit;
Edit20: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
public
end;
type
TEditList = class(TObjectList)
private
function GetItems(Index: Integer): TEdit;
procedure SetItems(Index: Integer; const Value: TEdit);
published
public
property Items[Index: Integer]: TEdit read GetItems write SetItems; default;
end;
var
frmCallbase: TfrmCallbase;
EditList: TEditList;
implementation
{$R *.dfm}
procedure TfrmCallbase.FormCreate(Sender: TObject);
begin
EditList := TEditList.Create();
EditList.Add(Edit1);
EditList.Add(Edit2);
EditList.Add(Edit3);
EditList.Add(Edit4);
EditList.Add(Edit5);
EditList.Add(Edit6);
EditList.Add(Edit7);
EditList.Add(Edit8);
EditList.Add(Edit9);
EditList.Add(Edit10);
EditList.Add(Edit11);
EditList.Add(Edit12);
EditList.Add(Edit13);
EditList.Add(Edit14);
EditList.Add(Edit15);
EditList.Add(Edit16);
EditList.Add(Edit17);
EditList.Add(Edit18);
EditList.Add(Edit19);
EditList.Add(Edit20);
for i:=0 to EditList.Count - 1 do
EditList[i].Text = 'default';
end;
procedure TfrmCallbase.FormDestroy(Sender: TObject);
begin
EditList.Free;
end;
function TEditList.GetItems(Index: Integer): TEdit;
begin
Result := TEdit(inherited GetItem(Index));
end;
procedure TEditList.SetItems(Index: Integer; const Value: TEdit);
begin
inherited SetItem(Index, Value);
end;
end.
Таким образом, мне удалось уменьшить функцию в 1000 строк до 46 (20 блоков по 46 строк).
Похожие статьи:





