How does one test if a component exists in your current application for example if you create a dynamic radiogroup named radiogroup1 how do you check if there already is a component with the name radiogroup1?
-
3Is it so hard to keep track of these things? People don't go around randomly creating radio groups in your app while you weren't looking! And what does the name of the component matter? Any `FindComponent` is probably the answer to the question you asked, but as for your underlying problem, who knows. – David Heffernan Aug 17 '14 at 11:24
-
2It's (almost always) pointless to give names to dynamically created components (I guess that you want to avoid the *"A component named
already exists"* exception). You'll better keep them with no name (unless you really need to give them names) and access them by references stored when creating. – TLama Aug 17 '14 at 13:11 -
Thank you very much for the reply David Hefferman you really solved my problem :) – theunie Aug 17 '14 at 17:04
-
2Sigh. I doubt FindComponent really is your salvation. – David Heffernan Aug 17 '14 at 17:24
-
`FindComponent`'s scope is form-wide, while your requirements states application-wide. – Free Consulting Aug 17 '14 at 20:25
-
2@FreeConsulting: actually `FindComponent()`'s scope is component-wise, as it is a method of `TComponent`. It is form-wise only if the component happens to be a `TForm`. – Remy Lebeau Aug 18 '14 at 15:39
-
Grep search is much easier and more versatile, in the GExperts suite. – Garth Thornton Mar 16 '21 at 19:50
2 Answers
First you'll have to make a list of all forms in the application.
Then you'll have to search each form for your component using FindComponent
.
Here's some sample code:
Something like this:
function TForm1.FindMyComponent(Parent: TComponent; Name: string): TComponent;
var
i: integer;
begin
if Parent.ComponentCount = 0 then exit(nil);
Result:= Parent.FindComponent(Name);
if Assigned(Result) then Exit;
for i:= 0 to Parent.ComponentCount do begin
Result:= FindMyComponent(Parent.Components[i], Name);
if Assigned(Result) then Exit;
end; {for i}
end;
If you call it like this:
procedure TForm1.Test;
var
MyRadioGroup: TComponent;
begin
MyRadioGroup:= FindMyComponent(Application, 'RadioGroup1');
....
end;
It will recursively look though all registered forms in the application for your radiogroup. See: http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TComponent.FindComponent
Note that the search is not case sensitive.
Do your own bookkeeping
Of course this code will be quite slow if you're looking for lots of controls in this manner.
Also as David stated it does not make sense to attach names to controls you create programmatically. Its better to just keep a list of the control names in a Dictionary and refer to them in that way.
type
TControlClass = class of TControl;
TForm1 = class(TForm)
private
NewIndex: TDictonary<string, integer>;
AllControls: TDictonary<string, TControl>;
....
function TForm1.AddControl(NewControl: TControl);
var
ClassName: string;
Index: integer;
ControlName: string;
begin
ClassName:= NewControl.ClassName;
if not(NewIndex.TryGetValue(ClassName, Index) then Index:= 0;
Inc(Index);
NewIndex.AddOrSetValue(ClassName, Index);
ControlName:= ControlName + IntToStr(Index);
NewControl.Name:= ControlName; //optional;
AllControls.Add(ControlName, NewControl);
end;

- 74,508
- 24
- 191
- 319
type
TFrameClass=class of TFrame;
procedure TForm1.LoadFrame(CurrentFrame: TFrameClass; Name:String);
var
Reference:TFrameClass;
Instance:TFrame;
begin
Instance:=TFrame(FindComponent(Name));
if (Instance=nil) then
begin
Reference:=TFrameClass(CurrentFrame);
Instance:=Reference.Create(Self);
Instance.Align := alClient;
Instance.Parent := ClientPanel;
end
else
begin
Instance.BringToFront;
end;
end;
procedure TForm1.scGPCharGlyphButton4Click(Sender: TObject);
var FrameInternalDistribution:TFrameInternalDistribution;
begin
LoadFrame(TFrameInternalDistribution, 'FrameInternalDistribution');
end;
procedure TForm1.scGPCharGlyphButton2Click(Sender: TObject);
var
FrameInboxDistribution:TFrameInboxDistribution;
begin
LoadFrame(TFrameInboxDistribution, 'FrameInboxDistribution');
end;

- 365
- 5
- 8