如何查看 Delphi 组件是否已存在于您的应用程序中?

3

如何测试当前应用程序中是否存在某个组件,例如如果您创建了一个名为radiogroup1的动态单选组,如何检查是否已经有一个名为radiogroup1的组件?


3
跟踪这些东西真的有那么难吗?人们不会在你不注意的情况下随意在你的应用程序中创建无线电组!组件的名称又有什么关系呢?任何 FindComponent 都可能是您所提出的问题的答案,但是对于您的潜在问题,谁知道呢。 - David Heffernan
2
给动态创建的组件命名几乎总是没有意义的(我猜你想避免“已存在名为<Name>的组件”异常)。最好不要给它们命名(除非你真的需要给它们命名),并通过在创建时存储的引用来访问它们。 - TLama
2
叹气。我怀疑FindComponent真的能拯救你。 - David Heffernan
FindComponent 的作用域是窗体范围,而您的要求是应用程序范围。 - Free Consulting
2
@FreeConsulting:实际上,FindComponent()的作用域是组件级别的,因为它是TComponent的一个方法。只有当该组件恰好是TForm时,它才是窗体级别的。 - Remy Lebeau
显示剩余2条评论
2个回答

5

首先,您需要列出应用程序中所有的表单。

之后,您需要使用FindComponent在每个表单中搜索您的组件。
以下是一些示例代码:

类似这样:

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;  

如果你这样调用它:

procedure TForm1.Test;
var
  MyRadioGroup: TComponent;
begin
  MyRadioGroup:= FindMyComponent(Application, 'RadioGroup1');
  ....
end;

它将递归查找应用程序中所有已注册的表单以获取您的radiogroup。 请参阅:http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TComponent.FindComponent 注意,搜索不区分大小写。
自行进行簿记 当然,如果您以这种方式寻找很多控件,这段代码将非常慢。 正如David所说,将名称附加到以编程方式创建的控件是没有意义的。最好只需在字典中保留控件名称列表,并以那种方式引用它们。
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;

0
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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接