首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >克隆Delphi组件

克隆Delphi组件
EN

Stack Overflow用户
提问于 2015-04-09 16:45:07
回答 2查看 805关注 0票数 0

我在一个窗体上声明了X(多于1)个组合框。(设计时)

所有这些组合框都有相同的属性(除了position、handle和其他一些它们不能共享的属性)

我想在运行时给它们提供相同的行为,这意味着如果我添加/删除了一个项目,或者更改了ItemIndex或类似的东西,那么所有的组合框都应该做同样的事情。

如何在运行时将所有属性/事件等从一个组件“克隆”到X个其他组件,而不是对每个组件反复执行操作?

EN

回答 2

Stack Overflow用户

发布于 2015-04-10 00:07:15

您也可以使用TStream中的ReadComponent和WriteComponent。

代码语言:javascript
运行
复制
procedure TForm1.Button1Click(Sender: TObject);
var
  oStream: TMemoryStream;
  i: integer;
  cbCombos: array[0..4] of TComboBox;
begin
  oStream := TMemoryStream.Create;
  ComboBox1.Tag := '666'; { \m/ }
  try
    oStream.WriteComponent(ComboBox1);
    for i := 0 to 4 do
    begin
      cbCombos[i] := TComboBox.CreateParented(Self.Handle);
      oStream.Position := 0;
      oStream.ReadComponent(cbCombos[i]);
      cbCombos[i].Name := 'AnotherComboBox' + IntToStr(i+1);
      cbCombos[i].Parent := Self;
      cbCombos[i].Tag := cbCombos[i].Tag + i + 1;
      cbCombos[i].Left := 16;
      cbCombos[i].Top := 36 * (i + 2);
      cbCombos[i].OnMouseEnter := ComboBox1MouseEnter;
    end;
  finally
    FreeAndNil(oStream);
  end;
end;

procedure TForm1.ComboBox1MouseEnter(Sender: TObject);
begin
  TWinControl(Sender).Hint := IntToStr(TWinControl(Sender).Tag);
end;
票数 2
EN

Stack Overflow用户

发布于 2015-04-09 17:10:19

您可以通过扩展RTTI来实现这一点

这只是一个开始--绝不是完整的:

代码语言:javascript
运行
复制
procedure TForm62.CloneComponent(const aSource, aDestination: TComponent);
var
  ctx: TRttiContext;
  RttiType, DestType: TRttiType;
  RttiProperty: TRttiProperty;
  Buffer: TStringlist;

begin
  if aSource.ClassType <> aDestination.ClassType then
    raise Exception.Create('Source and destiantion must be the same class');

  Buffer := TStringlist.Create;
  try
    Buffer.Sorted := True;
    Buffer.Add('Name');
    Buffer.Add('Handle');

    RttiType := ctx.GetType(aSource.ClassType);
    DestType := ctx.GetType(aDestination.ClassType);
    for RttiProperty in RttiType.GetProperties do
    begin
      if not RttiProperty.IsWritable then
        continue;

      if Buffer.IndexOf(RttiProperty.Name) >= 0 then
        continue;

      DestType.GetProperty(RttiProperty.Name).SetValue(aDestination, RttiProperty.GetValue(aSource));
    end;
  finally  
    Buffer.Free;
  end;
end;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29533798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档