Delphi - 引用在运行时创建的组件

Cap*_*fka 4 delphi components runtime reference

我正在使用Delphi 5,我在运行时创建了许多面板,然后在面板上创建按钮,显然在运行时再次创建.我需要这样做,因为我可能需要在将来动态创建更多的面板/按钮组合.

我可以做到这一切,但我不知道如何引用我创建的面板,因为我找不到访问面板组件名称的方法.在互联网上狩猎我发现我可以使用FindComponent按名称查找面板组件,但我仍然不知道如何使用该名称,因为我不能使用字符串变量来引用它 - 例如StringVar := Panel.Name.我得到一个类型不匹配,TComponentName与String.

我在创建面板时为每个面板创建了按钮.简化,它看起来像这样:

   With TypeQuery do begin // Create Panels
   First;
   While (not eof) do begin        // create the actual panel
      panelno := FieldByName('Product_type_id').AsInteger;
      pnl := Tpanel.Create(Self);
      pnl.name := FieldByName('PanelName').AsString;
      pnl.color := clInactiveCaption;
      pnl.parent := MainForm;
      pnl.width := 365;
      pnl.Height := 551;
      pnl.left := 434
      pnl.top := 122;
      pnl.caption := '';
      With ButtonQuery do begin
         Close;
         Parameters.parambyname('PanelID').Value := PanelNo;
         Open;
         First;
         While (not eof) and (FieldByName('Product_type_id').AsInteger = PanelNo) do begin    //put the buttons on it.
            btnName := FieldByName('ButtonName').AsString;
            BtnText := FieldByName('ButtonText').AsString;
            BtnGroup := FieldByName('Product_Group_ID').AsString;
            GrpColour := FieldByName('ButtonColour').AsString;
            btn := TColorButton.Create(Self);
            btn.Parent := pnl;
            btn.Name := BtnName;
            Btn.backcolor := HexToTColor(GrpColour);
            btn.Font.Name := 'Arial Narrow';
            btn.Font.Style := [fsBold];
            btn.Font.Size := 10;
            . . .
        end;
        . . .
     end; 
  end;
Run Code Online (Sandbox Code Playgroud)

我在几个论坛(包括这个论坛)上读过,没有办法直接按名称引用面板.我尝试过使用组件数组,但是我遇到了同样的问题 - 我需要通过指定的组件名称来引用组件.

好吧,我不是一个枪支程序员 - 我多年来一直使用Delphi来创建简单的程序,但这个程序要复杂得多.我之前从未使用过运行时组件.

我可以使用FindComponent使面板可见或不可见吗?如果是这样的话,鉴于我上面给你看过的内容,你能否给我一些我应该采取的步骤?

提前致谢 ...

kob*_*bik 11

我不确定你的意思是:" 我不能使用字符串变量来引用它 - 例如StringVar:= Panel.Name. "

试试这个:

procedure TForm1.FormCreate(Sender: TObject);
var
  p: TPanel;
begin
  p := TPanel.Create(Self); // create a TPanel at run-time
  p.Name := 'MyPanel'; // set a unique name
  p.Parent := Self;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  p: TPanel;
  StringVar: string;
begin
  p := FindComponent('MyPanel') as TPanel;
  if Assigned(p) then // p has reference to MyPanel
  begin
    // use that reference
    p.Caption := 'Foo';
    StringVar := p.Name;
    ShowMessage(StringVar);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

或者我错过了什么?

  • 不,你没有.应该是显而易见的,但事实并非如此!非常感谢. (2认同)

Rob*_*edy 6

您将组件名称变量名称混为一谈.对于IDE创建的组件,Delphi IDE努力保持这两者相同,但它们并不一定相同.您没有变量名称,因为您正在动态创建组件,并且您不知道需要多少变量.但是,您仍然可以控制组件名称:只需分配组件的Name属性,然后通过调用,您可以像使用任何其他组件名称一样使用它FindComponent.只需确保每个面板实例的名称都是唯一的.

还要记住,处理变量的方法是,当你在编译时不知道你需要多少时,就是使用数组列表.您可以使用普通的旧数组,也可以使用更复杂的数据结构,如TComponentListTDictionary.

最后,为了更容易参考您正在创建的面板的控件,您可以省去面板并使用框架代替.您可以TFrame在IDE中直观地设计a 并为按钮指定名称,并且在运行时,您可以实例化框架类,它将自动为您创建所有按钮,就像您实例化表单或数据模块一样.您只需要为新的帧对象指定一个名称,但该对象已经有指向按钮的命名字段.