Diese generische Routine funktioniert entweder mit einem Formular oder Frame (aktualisiert, um eine Unterklasse für die neue Steuerung zu verwenden):
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;
diese Routine mit den Eigenschaften der neuen Steuerung passieren
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;
Gebrauch mag es:
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;
VORSICHT: Wenn Sie dies in der AfterConstruction des Frame tun, achten Sie darauf, dass die Erstellung des Hosting-Formulars noch nicht abgeschlossen ist.
Wenn Sie die Steuerelemente dort freigeben, kann dies zu vielen Problemen führen, da Sie Probleme mit der Verwaltung von Formularsteuerelementen haben.
Sehen Sie, was Sie bekommen, wenn Sie versuchen, die neue Beschriftung bearbeiten lesen in der Showmessage anzuzeigen ...
In diesem Fall Sie
... ReplaceControl (Edit1 ‚Edit2‘, Falsch) verwenden wollen
und dann tun Sie eine
... FreeAndNil (Edit1)
später.
Das wird nicht helfen, da er den TEdit durch einen anderen Komponententyp ersetzen wollte. (etwas Abkömmling) Für den Rest ist dies genau die erste Antwort, außer dass Sie es in eine Funktion eingepackt haben. Vielleicht ist der AfterConstruction-Tipp aber hilfreich. – Loesje
Eigentlich funktioniert die gleiche Idee mit einer Unterklasse, siehe aktualisierte Version. Habe mich aber nicht genau durchgelesen, da ich die "Unterklasse" verpasst habe ... –
2 weitere Kommentare: 1. Es ist am besten, nicht auf IsertControl/RemoveControl zu drillen, es sei denn, wirklich nötig. SetParent tut alles was benötigt wird. 2. Und ich möchte darüber differieren, dass es dasselbe ist: es ist viel generischer und flexibler, wenn man den Klassen-Factory-Ansatz mit TControlClass verwendet. –