如何解决 Delphi 中 2 个或更多 Unit 之间的 CYCLIC 关系问题?

How to solve the CYCLIC relation issue between 2 or more Units in Delphi?

我在 Delphi 2010 年使用了 2 个单元:Unit1 有一个带有 TEditButton 的表格,这个 Button 将从 Unit2 调用过程(Unit2 没有表单)。那个程序会改变Unit1TEdit的'caption'属性,我试着把Unit2Unit1 "Uses" 中访问程序,并将 Unit1 放在 Unit2[ 的 "Uses" 中=29=] 访问 Unit1 中的 TEdit,但这种关系是循环的。

我不确定我能做些什么来解决这个问题,有什么建议吗?

有很多方法可以做到这一点,哪一种最合适主要取决于具体情况,所以从技术上讲这个问题对于 Stack Overflow 来说太宽泛了,我怀疑。

方法一

不过,让我向您展示一种非常简单的方法。这可能不是一个好方法,但它接近于您正在尝试做的事情。

  1. 创建一个新的 VCL 应用程序。
  2. 在主窗体上拖放一个 TButton 和一个 TEdit 控件(Unit1 中的 TForm1)。
  3. 创建一个新单元,Unit2:

    unit Unit2;
    
    interface
    
    procedure SetCaption;
    
    implementation
    
    uses
      Unit1;
    
    procedure SetCaption;
    begin
      Unit1.Form1.Edit1.Text := 'Hello, World!';
    end;
    
    end.
    
  4. 在主窗体上,将此事件处理程序用于按钮的 OnClick 事件:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Unit2.SetCaption;
    end;
    

    implementation 部分的 uses 子句中添加 Unit2 之后。完整,

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    uses
      Unit2;
    
    {$R *.dfm}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Unit2.SetCaption;
    end;
    
    end.
    

注意如果仅在实施部分引用这些单元如何相互使用。另请注意,我们在 Unit1 中使用全局变量 Form1 来引用自动创建的 TForm1 实例。在许多(大多数)情况下,您不想使用自动创建的表单,但那是另一回事(我可以在这里写一本 100 页的 Delphi 教科书!)。

方法二

此外,让我重申一个事实,即有许多其他方法可以实现此结果。例如,这可以说是一种更好的方法:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Unit2.SetCaption(Edit1);
end;

end.



unit Unit2;

interface

uses
  StdCtrls;

procedure SetCaption(AEdit: TCustomEdit);

implementation

procedure SetCaption(AEdit: TCustomEdit);
begin
  AEdit.Text := 'Hello, World!';
end;

end.

方法三

可以说更好:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := Unit2.GetText;
end;

end.



unit Unit2;

interface

function GetText: string;

implementation

function GetText: string;
begin
  Result := 'Hello, World!';
end;

end.