从Delphi的子单元访问主表单

时间:2012-04-16 12:38:54

标签: delphi circular-dependency delphi-units

我想从一个从main调用的类中访问一个主窗体变量。 像这样:

1单元:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,Unit2, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;
var
  Form1: TForm1;
  Chiled:TChiled;
const
 Variable = 'dsadas';
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Chiled.ShowMainFormVariable;
end;

end.

UNIT2:

unit Unit2;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

  type
  TChiled = class
  private
  public
    procedure ShowMainFormVariable;
  end;
var
  Form1: TForm1;
implementation

procedure TChiled.ShowMainFormVariable;
begin
  ShowMessage(Form1.Variable);
end;
end.

如果在我添加的Unit2中使用Unit1,则会弹出一个圆形错误。

如何使Unit1成为GLOBAL?

4 个答案:

答案 0 :(得分:5)

正如其他答案所述,您应该使用实施部分中的一个单元。

假设您在'unit2'中选择了在实现中使用'unit1'。那么你需要设计一种机制来告诉'TChiled'如何访问'Form1'。那是因为你没有在'unit2'的接口部分使用'unit1',你不能在接口部分声明'Form1:TForm1'变量。以下是一种可能的解决方案:

unit2

type
  TChiled = class
  private
    FForm1: TForm;
  public
    procedure ShowMainFormVariable;
    property Form1: TForm write FForm1;
  end;

implementation

uses
  unit1;

procedure TChild.ShowMainFormVariable;
begin
  ShowMessage((FForm1 as TForm1).Variable);
end;

然后在unit1中你可以在调用TChiled的方法之前设置TChiled的Form1属性:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Chiled.Form1 := Self;
  Chiled.ShowMainFormVariable;
end;

答案 1 :(得分:3)

最简单的解决方案是将Unit1添加到Unit2的实现部分中的uses子句,因为这会绕过循环引用。

但是我建议这个设计有缺陷。使用示例代码很难看到您要实现的目标,因此很难提供任何真正的建议。

答案 2 :(得分:2)

嗯,简单的天真答案是,您应该将Unit1添加到uses实施部分的Unit2条款中:

unit Unit2;
......
implementation

uses
  Unit1;
.....

您无法将其添加到uses的接口部分中的Unit2子句,因为这会在接口部分创建循环引用。换句话说,Unit1的界面将使用Unit2Unit2的界面将使用Unit1。该语言不允许这样做。常见的解决方案是use实施级别的其中一个单元。


话虽如此,您的代码相当混乱,并在许多其他方面失败。您的问题比循环引用更深入。例如,Form1.Variable是什么意思?常量Variable不是TForm1的成员。您声明了两个名为Form1的{​​{1}}类型的全局变量。你为什么这样做?

另外,你拼错了孩子。

答案 3 :(得分:1)

我通常创建一个数据模块(或任何类型的非可视容器)来共享全局变量。这样两个单元都可以使用变量而不需要循环引用。