esto más genéricos trabajos de rutina, ya sea con un formulario o marco (actualizado para utilizar una subclase para el nuevo control):
function ReplaceControlEx(AControl: TControl; const AControlClass: TControlClass; const ANewName: string; const IsFreed : Boolean = True): TControl;
begin
if AControl = nil then
begin
Result := nil;
Exit;
end;
Result := AControlClass.Create(AControl.Owner);
CloneProperties(AControl, Result);// copy all properties to new control
// Result.Left := AControl.Left; // or copy some properties manually...
// Result.Top := AControl.Top;
Result.Name := ANewName;
Result.Parent := AControl.Parent; // needed for the InsertControl & RemoveControl magic
if IsFreed then
FreeAndNil(AControl);
end;
function ReplaceControl(AControl: TControl; const ANewName: string; const IsFreed : Boolean = True): TControl;
begin
if AControl = nil then
Result := nil
else
Result := ReplaceControlEx(AControl, TControlClass(AControl.ClassType), ANewName, IsFreed);
end;
utilizando esta rutina para pasar las propiedades del nuevo control
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;
usarlo como:
procedure TFrame1.AfterConstruction;
var
I: Integer;
NewEdit: TMyEdit;
begin
inherited;
NewEdit := ReplaceControlEx(Edit1, TMyEdit, 'Edit2') as TMyEdit;
if Assigned(NewEdit) then
begin
NewEdit.Text := 'My Brand New Edit';
NewEdit.Author := 'Myself';
end;
for I:=0 to ControlCount-1 do
begin
ShowMessage(Controls[I].Name);
end;
end;
PRECAUCIÓN: si está haciendo esto dentro de la construcción posterior del marco, tenga en cuenta que la construcción del formulario de alojamiento no ha finalizado aún.
Freeing Controles allí, pueden causar muchos problemas ya que estás jugando con controles de forma.
Vea lo que se obtiene si se intenta leer la nueva edición de subtítulos para mostrar en el ShowMessage ...
En ese caso, habría que desee utilizar
... ReplaceControl (Edit1, 'Edit2', Falso)
y luego hacer un
... FreeAndNil (Edit1)
posterior.
Esto no ayudará, ya que quería reemplazar el TEdit con otro tipo de componente. (algunos descendientes) Por lo demás, esta es exactamente la misma primera respuesta, excepto que la envuelve en una función. Quizás la sugerencia de AfterConstruction sea útil, sin embargo. – Loesje
En realidad, la misma idea funciona con una subclase, consulte la versión actualizada. Obtuve que no leía atentamente, ya que había omitido la "subclase" ... –
2 comentarios adicionales: 1. Lo mejor es no profundizar en IsertControl/RemoveControl a menos que sea realmente necesario. SetParent hace todo lo que se necesita. 2. Y pido diferir acerca de ser el mismo: es mucho más genérico y flexible utilizando el enfoque de fábrica de clase con TControlClass. –