DelphiWin32 - генерирует объект определенного класса - PullRequest
2 голосов
/ 22 ноября 2010

Я использую Delphi 2009. У меня есть TListBox с несколькими элементами. Я хочу создать объект определенного класса для каждого выбранного элемента. Поэтому, если пользователь выберет элемент № 2 и нажмет кнопку «Создать», будет создан объект определенного класса. Я думал реализовать это, просто проверяя значение индекса текущего выбранного элемента, а затем используя if-then-else. Или я должен использовать ссылку на класс, т. Е. Для каждого щелчка по элементу я устанавливаю тип ссылки на класс, а затем создаю объект в событии OnClick кнопки? Я хотел бы избежать всех этих элементов управления и просто создать объект на основе значения строки элемента. Любая идея? Большое спасибо!

Ответы [ 2 ]

4 голосов
/ 22 ноября 2010

Есть несколько вариантов.

Простой индекс

Простое решение:

case ListBox1.ItemIndex of
  0 : temp := TApple.Create;
  1 : temp := TPineapple.Create;
  2 : temp := TGrape.Create;
else
  raise EFruitError.Create('Unknown fruit');
end;

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

Ссылки на классы

Предположим, что все фрукты происходят из TFruit с помощью виртуального конструктора.Тогда вы можете сделать:

procedure TForm1.FormCreate(const Sender: TObject);
begin
  ListBox1.AddObject('Apple', TApple);
  ListBox1.AddObject('Pineapple', TPineapple);
  ListBox1.AddObject('Grape', TGrape);
end;

// Event handler:
procedure TForm1.CreateButtonClick(const Sender: TObject);
begin
  if ListBox1.ItemIndex>=0 then
    temp := TFruit(ListBox1.Items.Objects[ListBox1.ItemIndex]).Create;
end;

Это имеет одну точку обслуживания.Что здорово.

Ссылка на основе имени Но если вы хотите создать объекты на основе имени в списке, вы можете создать некую фабрику:

type
  TFruitClass = class of TFruit;
  TFruitFactory = class
  public
    class function CreateFruit(const AName: string): TFruit;
    class procedure RegisterFruit(const AName: string; const AFruitClass: TFruitClass);
  end;

Фабрика используется для привязки классов к именам.Каждый класс регистрируется с использованием имени.А теперь вы просто даете имя фабрике, и фабрика возвращает требуемый класс.

3 голосов
/ 22 ноября 2010

Чтобы добавить ответ Gamecat, вы можете использовать функции утилит класса в "classes.pas".В следующем примере используется функция GetClass (и предполагается, что создаваемые объекты происходят из TControl):

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListBox1.Items.CommaText := 'TEdit,TButton,TPanel';
  RegisterClasses([TButton, TEdit, TPanel]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  pc: TPersistentClass;
  c: TControl;
begin
  if ListBox1.ItemIndex > -1 then begin
    pc := GetClass(ListBox1.Items[ListBox1.ItemIndex]);
    if Assigned(pc) then begin
      c := TControlClass(pc).Create(Self);
      c.Parent := Self;
    end;
  end;
end;
...