复制时如何保留控件之间的连接?

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

我想问一下,当我复制一个控件时,如何保留控件之间的联系。例如,我有一个编辑框,可以用滑块控制数值的变化,当我使用这段代码复制时,我实现了项目的复制,但滑块停止控制编辑框的数值。

 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;
delphi designer
1个回答
5
投票

除非我误解了你的意思,否则你的CloneProperties似乎与你所问的问题没有任何关系。 在你的例子中,一个编辑控件E1和一个滑块S1,你可以克隆它们两个来产生E2和S2,但是在你的代码中的某个地方必须有一条语句,根据S1的值来改变E1的值。 然而,在你很可能写的方式中,该语句并不适用于E2和S2。

最简单的方法是写一个方法,它接受组件实例,并将这两个实例的操作联系在一起。

  procedure TForm1.SetEditControlFromSlider(AnEdit : TEdit; ASlider : { TWhatever the slider actually is);
  begin
    // Set AnEdit's value from ASlider's properties
  end;

然后,你可以像这样用EditSlider对来调用这个方法

  SetEditControlFromSlider(E1, S1);
  [...]
  SetEditControlFromSlider(E2, S2);

我可以想象你可能不喜欢这样做。

IMO,最干净的解决方案是完全避免尝试克隆组件,并创建一个包含Edit、Slider和连接它们的代码的TFrame,然后根据你的需要添加到你的表单中的框架实例。 这就像从一根木头上掉下来一样简单。

type
  TEditFrame = class(TFrame)  // needs to be in its own unit, Used by your form
    Edit1: TEdit;
    TrackBar1: TTrackBar;
    procedure TrackBar1Change(Sender: TObject);
  private
  public
  end;
  [...]
  procedure TEditFrame.TrackBar1Change(Sender: TObject);
  begin
    Edit1.Text := IntToStr(TrackBar1.Position)
  end;

然后,你可以通过以下方式将框架的克隆添加到TForm1中。

  procedure TForm1.Button1Click(Sender: TObject);
  var
    AFrame : TEditFrame;
  begin
    Inc(FrameCount); // Field of TForm1
    AFrame := TEditFrame.Create(Self);
    AFrame.Name := AFrame.Name + IntToStr(FrameCount);
    AFrame.Parent := Self;
    AFrame.Top := AFrame.Height * FrameCount;
  end;

请注意,因为连接这两个组件的代码。TrackBar1Change它被编译到框架的单元中,它被你创建的每一个框架实例自动共享,不需要 "克隆 "代码。

© www.soinside.com 2019 - 2024. All rights reserved.