我在一个窗体上声明了X(多于1)个组合框。(设计时)
所有这些组合框都有相同的属性(除了position、handle和其他一些它们不能共享的属性)
我想在运行时给它们提供相同的行为,这意味着如果我添加/删除了一个项目,或者更改了ItemIndex或类似的东西,那么所有的组合框都应该做同样的事情。
如何在运行时将所有属性/事件等从一个组件“克隆”到X个其他组件,而不是对每个组件反复执行操作?
发布于 2015-04-09 16:07:15
您也可以使用TStream中的ReadComponent和WriteComponent。
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;
发布于 2015-04-09 09:10:19
您可以通过扩展RTTI来实现这一点
这只是一个开始--绝不是完整的:
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;
https://stackoverflow.com/questions/29533798
复制