【问题标题】:How to solve the CYCLIC relation issue between 2 or more Units in Delphi?如何解决 Delphi 中 2 个或多个 Units 之间的 CYCLIC 关系问题?
【发布时间】:2019-08-27 13:07:14
【问题描述】:

我在 Delphi 2010 中使用 2 个单元:Unit1 有一个带有 TEditButton 的表单,这个 Button 将调用来自 Unit2 的过程strong>(Unit2 没有表格)。该过程将更改Unit1TEdit的'caption'属性,我尝试将Unit2放入Unit1“Uses”中以访问程序,并将Unit1放在Unit2的“Uses”中,以访问Unit1中的TEdit,但这种关系是循环的。

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

【问题讨论】:

  • 不要将 GUI 元素捆绑在一起,问题会自行解决。使用对象并在表单之间传递它们,对象可以在一个单独的单元中定义,两个表单都可以使用...
  • 嗯,可以通过将 uses Unit1 子句移至单元 2 的实现部分来完成,但这远非良好做法。单元 2 应该真正组织起来,这样就不需要知道单元 1。例如,单元 2 中的过程可以是一个函数,它返回一个字符串,然后单元 1 将分配给单元 1 的标题属性。
  • 谢谢大家的回复,我会试试你的建议

标签: delphi delphi-2010


【解决方案1】:

有很多方法可以做到这一点,哪一种最合适取决于具体情况,所以从技术上讲,这个问题对于 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;
    

    在您将Unit2 添加到implementation 部分的uses 子句之后。完整的,

    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.

方法3

可以说更好:

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.

【讨论】:

  • 非常感谢您的帮助和回复!我全部实现了它们并且它们刚刚工作,如果我需要获取 DataSetProviders、TSQLStoredProcs、TDataSource 等元素,您建议使用哪一个?
  • 我不知道。如果我曾经看到像 Unit1.Form1.Edit1.Text := 'Hello, World!'; 这样的代码,我会用火把它从代码库中烧掉。这是直奔意大利面条代码噩梦的道路。我绝不会建议任何人编写这样的代码,即使是作为练习。方法1应该是如何不做的例子。曾经。 Form1 应该是唯一直接操作 Form1 的子对象或字段的对象。其他进入内部的班级或单位应该始终是一个巨大的危险信号。
  • @J 阿门!归根结底就是坚持SOLID原则,RAD开发鼓励用户做错事……
  • 由于 SOLID 编码原则,我个人会选择类似于选项 2 或 3 的东西。如果明天我决定使用另一种类型的编辑或更改编辑控件的名称,我只需要更改它在一个地方而不是在任何地方引用编辑。在选项2的SetCaption中,我还要检查一下是否分配了AEdit参数,否则会导致访问冲突;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 2021-10-31
  • 2020-12-22
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
相关资源
最近更新 更多