从主窗体

时间:2018-01-05 11:43:23

标签: delphi

我有一个表单FormOrder,它在运行时动态创建TPageControl组件下的一些帧。基本上PageControl中的每个标签都位于名为FrameCust的框架内。

uses ..., UnitFrameSupp;

TPageSupp = record
    SuppId: Cardinal;
    SuppName: String;
    TabSheet: TTabSheet;
    Frame: TFrameSupp;
  end;

  TOrder = record
    Id: Cardinal;
    RefYear: Word;
    RefNo: Cardinal;
    Loaded: Boolean;
    Changed: Boolean;
    PageCust: TPageCust;
    PageSupp: array of TPageSupp;
  end;

TFormOrder = class(TForm)
  private
    FOrder: TOrder;
    procedure SetOrderId(const Value: Cardinal);
  public
    property OrderId: Cardinal write SetOrderId;
  end;

...

TFrameSupp = class(TFrame)
    BtnSave: TBitBtn;
    procedure BtnSavelick(Sender: TObject);
  private
    FSuppId: Cardinal;
    FSuppName: String;
    FOrderId: Cardinal;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property SuppId: Cardinal write FSuppId;
    property SuppName: String write FSuppName;
    property OrderId: Cardinal write FOrderId;
  end;

procedure TFrameSupp.BtnSaveClick(Sender: TObject);
begin
  FOrderId:= 100;

  //here I would like to update the value of `Order.Id` from `FormOrder`
  //and also to inform the others frames about this change.
end;

如何从主表单更新Order.Id的值,并告知其他有关此更改的框架?

我知道我可以在Order:TOrder下公开DataModule并从所有单位访问它而不创建循环引用。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

首先,我会使用MainForm来更新所有帧,因此问题会减少,以通知更改的主要形式。

有(至少)两种方法可以做到这一点。一种是在框架定义的实现部分包含一个uses子句,然后使用(Owner as TFormOrder)或直接访问表单。

另一方面,在我看来更好的方法是创建一个回调属性,可能是在所有帧的共同祖先上,就像在组件上创建一个事件一样,例如。

property OnIDChange : TNotifyEvent read fOnIDChange write fOnIDChange;

然后在ButonSaveClick中添加块

if assigned( fOnIDChange ) then fOnIDChange( self );

您可以通过定义自己的事件类型来改善这一点

TOnIDChange = procedure( Sender : TObject; NewVal : cardinal ) of object;

然后

property OnIDChange : TOnIDChange read fOnIDChange write fOnIDChange;

然后在ButonSaveClick中添加块

if assigned( fOnIDChange ) then fOnIDChange( self, fOrderID );

这种方法的缺点是你必须在主窗体中定义事件过程并在创建时将其分配给帧。