Duplicating components at Run-Time

后端 未结 4 2015
鱼传尺愫
鱼传尺愫 2020-12-06 11:03

Is there a simple way to duplicate all child components under parent component, including their published properties?

For example:

  • TPanel
    • TLa
4条回答
  •  遥遥无期
    2020-12-06 11:13

    You can propably use the CLoneProperties routine from the answer to "Replace visual component at runtime", after you have created the dup components in a loop thru the parent's controls.

    Update: some working code....

    . I assume from your question that you want to duplicate the Controls that are contained in a WinControl (as a Parent is a TWinControl).
    . As I did not know if you also wanted to hook the duplicated controls with the same Event Handlers as the originals, I made an option for that.
    . And you may want to give a proper meaningful Name to the duplicated controls.

    uses
      TypInfo;
    
    procedure CloneProperties(const Source: TControl; const Dest: TControl);
    var
      ms: TMemoryStream;
      OldName: string;
    begin
      OldName := Source.Name;
      Source.Name := ''; // needed to avoid Name collision
      try
        ms := TMemoryStream.Create;
        try
          ms.WriteComponent(Source);
          ms.Position := 0;
          ms.ReadComponent(Dest);
        finally
          ms.Free;
        end;
      finally
        Source.Name := OldName;
      end;
    end;
    
    procedure CloneEvents(Source, Dest: TControl);
    var
      I: Integer;
      PropList: TPropList;
    begin
      for I := 0 to GetPropList(Source.ClassInfo, [tkMethod], @PropList) - 1 do
        SetMethodProp(Dest, PropList[I], GetMethodProp(Source, PropList[I]));
    end;
    
    procedure DuplicateChildren(const ParentSource: TWinControl;
      const WithEvents: Boolean = True);
    var
      I: Integer;
      CurrentControl, ClonedControl: TControl;
    begin
      for I := ParentSource.ControlCount - 1 downto 0 do
      begin
        CurrentControl := ParentSource.Controls[I];
        ClonedControl := TControlClass(CurrentControl.ClassType).Create(CurrentControl.Owner);
        ClonedControl.Parent := ParentSource;
        CloneProperties(CurrentControl, ClonedControl);
        ClonedControl.Name := CurrentControl.Name + '_';
        if WithEvents then
          CloneEvents(CurrentControl, ClonedControl);
      end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      DuplicateChildren(Panel1);
    end;
    

提交回复
热议问题