Delphi TWinControl 在运行时复制其子级

问题描述 投票:0回答:1

当我构建这个组件并将其放置在表单上时,一切看起来都很好。但是,当我运行该程序时,该控件会复制其所有子项。它似乎调用了初始化组件两次,尽管我不明白为什么。

来自 TWinControl 组件的代码

    unit Payments_Test;

    interface

    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, AdvSmoothButton, EBSGrid,
       Vcl.StdCtrls, Vcl.ExtCtrls, Data.DB, MemDS, EBS3DataClass,
      DBAccess, AdvUtil, Vcl.Grids, AdvObj, BaseGrid, AdvGrid,AdvStyleIF;

    type
      TEBSPayments_Test = class(TWinControl)
      private
        { Private declarations }
        fDeletePayment, fNewPayment : TNotifyEvent;
        PYLabel33: TLabel;
        lblOverPayment: TLabel;
        cmdAddPayment: TAdvSmoothButton;
        cmdDeletePayment: TAdvSmoothButton;
        PYPanel1: TPanel;
        PyGrid1: TEBSGrid;
        FBackgroundColor, FPanelColor: TColor;
        procedure cmdDeletePaymentClick(Sender: TObject);
        procedure cmdAddPaymentClick(Sender: TObject);
        procedure SetBackgroundColor(const Value: TColor);
        procedure SetPanelColor(const Value: TColor);
        procedure InitializeComponents;
      Protected
        procedure SetParent(AParent: TWinControl); override;
      Published
        property Anchors  default [akLeft, akTop];
        property Align  default alNone;
        property AutoSize Default True;
        property PanelColor: TColor read FPanelColor write SetPanelColor default clSkyBlue;
        property BackgroundColor: TColor read FBackgroundColor write 
        SetBackgroundColor default clSkyBlue;
        property DeletePayment: TNotifyEvent read FDeletePayment write FDeletePayment;
        property NewPayment: TNotifyEvent read FNewPayment write FNewPayment;
      public
        { Public declarations }
        procedure Initialise;
        procedure CloseControl;
        constructor Create(AOwner: TComponent); override;
        Destructor Destroy; Override;
      end;

    Procedure Register;

    implementation


    Uses EBS3DataUtils;

    procedure TEBSPayments_Test.SetBackgroundColor(const Value: TColor);
    begin
      if FBackgroundColor <> Value then
      begin
        FBackgroundColor := Value;
        Color := FBackgroundColor;
      end;
    end;

    procedure TEBSPayments_Test.SetPanelColor(const Value: TColor);
    begin
      if FPanelColor <> Value then
      begin
        FPanelColor := Value;
        Color := FPanelColor;
      end;
    end;


    constructor TEBSPayments_Test.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      Width := 428;
      Height := 224;
    end;

    procedure TEBSPayments_Test.InitializeComponents;
    begin
      PYPanel1 := TPanel.Create(Self);
      PYPanel1.Parent := Self;
      PYPanel1.Height := 22;
      PYPanel1.Align := alTop;
      PYPanel1.Caption := '';
      PyGrid1 := TEBSGrid.Create(Self);
      PYGrid1.Parent := Self;
      PYGrid1.AutoSize := False;
      PYGrid1.Align := alBottom;
      PYGrid1.Height := ClientHeight - PYPanel1.Height;
      PYGrid1.FctlGrid.FixedCols := 0;
      FBackgroundColor := clSkyBlue;
      FPanelColor := clMoneyGreen;
      PYPanel1.Color := FPanelColor;
      Color := FBackgroundColor;
      cmdDeletePayment := TAdvSmoothButton.Create(Self);
      cmdDeletePayment.Parent := PYPanel1;
      cmdDeletePayment.SetBounds(182,1,54,20);
      cmdDeletePayment.UIStyle := tsCustom;
      cmdDeletePayment.Caption := 'Delete';
      cmdDeletePayment.Color := clBlue;
      cmdDeletePayment.Appearance.Font.Color := clWhite;
      cmdDeletePayment.Appearance.Rounding := 8;
      cmdDeletePayment.Bevel := True;
      cmdDeletePayment.BevelColor := clWhite;
      cmdAddPayment := TAdvSmoothButton.Create(Self);
      cmdAddPayment.Parent := PYPanel1;
      cmdAddPayment.SetBounds( 127,1,49,20);
      cmdAddPayment.UIStyle := tsCustom;
      cmdAddPayment.Caption := 'New';
      cmdAddPayment.Color := clBlue;
      cmdAddPayment.Appearance.Font.Color := clWhite;
      cmdAddPayment.Appearance.Rounding := 8;
      cmdAddPayment.Bevel := True;
      cmdAddPayment.BevelColor := clWhite;
      lblOverPayment := TLabel.Create(Self);
      lblOverPayment.Parent := PYPanel1;
      lblOverPayment.SetBounds(483,5,116,13);
      lblOverPayment.Font.Color := clRed;
      lblOverPayment.Font.Style := [fsBold];
      PYLabel33 := TLabel.Create(Self);
      PYLabel33.Parent := PYPanel1;
      PYLabel33.SetBounds(8,6,66,13);
      PYLabel33.Font.Color := clGreen;
      PYLabel33.Font.Style := [fsBold];
    end;

    procedure TEBSPayments_Test.SetParent(AParent: TWinControl);
    begin
      inherited SetParent(AParent);
      if Assigned(AParent) then  InitializeComponents;
    end;


    Destructor TEBSPayments_Test.Destroy;
    begin
      PYLabel33.Free;
      lblOverPayment.Free;
      cmdAddPayment.Free;
      cmdDeletePayment.Free;
      PYPanel1.Free;
      PyGrid1.Free;
      Inherited Destroy;
    end;


    procedure TEBSPayments_Test.Initialise;
    begin
    end;

    procedure TEBSPayments_Test.CloseControl;
    begin
      PYGrid1.SaveGridSettings;
    end;

    procedure TEBSPayments_Test.cmdAddPaymentClick(Sender: TObject);
    begin
      if Assigned(FNewPayment) then
        FNewPayment(Self);
    end;

    procedure TEBSPayments_Test.cmdDeletePaymentClick(Sender: TObject);
    begin
      if Assigned(FDeletePayment) then
        FDeletePayment(Self);
    end;


    procedure Register;
    begin
      RegisterComponents('EBSH', [TEBSPayments_Test]);
    end;


    end.

TForm 中的代码

    unit ComponentTest;

    interface

    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, 
      System.Variants, System.Classes,Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs,AdvUtil, Vcl.Grids, AdvObj,
      BaseGrid, AdvGrid, UniProvider, SQLServerUniProvider,
       Vcl.StdCtrls,  JvExStdCtrls, JvMemo, Vcl.ExtCtrls,
      Notes, ContactPanel, Payments_Test;

    type
      TfrmCompTest = class(TForm)
        Button1: TButton;
        EBSPayments_Test1: TEBSPayments_Test;
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      frmCompTest: TfrmCompTest;

    implementation

    {$R *.dfm}

    end.

我检查了多次调用初始化组件的代码。在某一阶段,它只是通过粘贴到表单来完成。这是由两次调用初始化组件引起的 现在它只在运行时执行此操作。断点触发两次,但我无法弄清楚第二次调用来自哪里

delphi duplicates components vcl oncreate
1个回答
0
投票

当您的容器组件正在处理其子组件的生命周期时,您需要将它们标记为子组件,以便流系统可以正确处理它们。为此,请在创建每个子组件后立即调用

SetSubComponent(True)

例如:

  PYPanel1 := TPanel.Create(Self);
  PYPanel1.SetSubComponent(True);
  PYPanel1.Parent := Self;
  PYPanel1.Height := 22;
  PYPanel1.Align := alTop;
  PYPanel1.Caption := '';
© www.soinside.com 2019 - 2024. All rights reserved.