简体   繁体   English

Delphi从接口通知事件

[英]Delphi notify events from interfaces

I'm here again for a question about notification. 我再次在这里提出有关通知的问题。 I've the followinf interface: 我有followinf界面:

unit TblInterface;

interface

uses
  System.TypInfo, Vcl.Forms, RzPanel, Winapi.Windows, Winapi.Messages,
  UserMessages, Vcl.Dialogs, Vcl.Controls;

type

  TFrameType = (ftList, ftDetail);

  TFrameInfo = record
    Frame: TFrame;
    FrameType: TFrameType;
  end;

  TFrameClass = class of TFrame;

  ITabella = interface
  ['{D21924F9-BB41-493B-B06D-0908C0CA73D8}']
    function GetCurrentActiveFrameType: TFrameInfo;
    procedure CreateLstFrame(ParentForm: TForm; Frame: TFrameClass);
    procedure CreateDtlFrame(ParentForm: TForm; Frame: TFrameClass);
    procedure DestroyLstFrame;
    procedure DestroyDtlFrame;
    procedure BringFrameToFront(FrameType: TFrameType);
    procedure OnDoubleClick;
  end;

  TTabella = class(TInterfacedObject, ITabella)
  private
    FLst: TFrame;
    FDtl: TFrame;
    ActFrame: TFrameInfo;
    function GetCurrentActiveFrameType: TFrameInfo;
    procedure CreateLstFrame(ParentForm: TForm; Frame: TFrameClass);
    procedure CreateDtlFrame(ParentForm: TForm; Frame: TFrameClass);
    procedure DestroyLstFrame;
    procedure DestroyDtlFrame;
    procedure BringFrameToFront(FrameType: TFrameType);
    procedure OnDoubleClick;
  end;

implementation

{ TTabella }

{ Creazione frame lista }
procedure TTabella.CreateLstFrame(ParentForm: TForm; Frame: TFrameClass);
begin
  FLst := Frame.Create(ParentForm);
  FLst.Parent := ParentForm;
  FLst.Align := alClient;
end;

{ Creazione frame dettaglio }
procedure TTabella.CreateDtlFrame(ParentForm: TForm; Frame: TFrameClass);
begin
  FDtl := Frame.Create(ParentForm);
  FDtl.Parent := ParentForm;
  FDtl.Align := alClient;
end;

{ Distruzione frame lista }
procedure TTabella.DestroyLstFrame;
begin
  FLst.Free;
end;

{ Distruzione frame dettaglio }
procedure TTabella.DestroyDtlFrame;
begin
  FDtl.Free;
end;

{ Porta in primo piano il frame richiesto }
procedure TTabella.BringFrameToFront(FrameType: TFrameType);
begin
  case FrameType of
    ftList: begin
      FLst.BringToFront;
      ActFrame.Frame := FLst;
    end;
    ftDetail: begin
      FDtl.BringToFront;
      ActFrame.Frame := FDtl;
    end;
  end;
  ActFrame.FrameType := FrameType;
end;

{ Restiruisce il frame attivo }
function TTabella.GetCurrentActiveFrameType: TFrameInfo;
begin
  Result := ActFrame;
end;

procedure TTabella.OnDoubleClick;
begin
  BringFrameToFront(ftList);
end;

end.

In the interface I create two frames that are used to display list and detail of some database tables. 在界面中,我创建了两个框架,用于显示一些数据库表的列表和详细信息。 Form interface I create, brig to front the correct frame and destroy it. 我创建的表单界面,向正确的框架行进并销毁它。 At this point I need to notify events to the frames created, but I don't know how to do this king of job. 在这一点上,我需要将事件通知给创建的框架,但是我不知道该如何做。 For example I need to notify to the detail frame that a button was pressed in the list frame. 例如,我需要通知详细信息框在列表框中按下了一个按钮。

How can I achieve this task? 我该如何完成这项任务?

There are at least 2 ways to do that. 至少有两种方法可以做到这一点。 First, which i will recommend, is using another Interface; 首先,我将建议使用另一个接口; Second way is using procedure of object, which we handle event. 第二种方法是使用对象的过程,我们处理事件。 Let's put the hands in the batter! 让我们将手放在击球手中!

  1. Declare a new Interface before ITabella with the methods will want to notify 在ITabella希望使用该方法通知之前,声明一个新接口

     IProcessor=Interface {Shift+Ctrl+G} procedure Select; procedure Search(); 

A very basic example to handle Click event and same Search event, to call the frame ftList Then we implement the methods in descendant classes 一个处理Click事件和相同Search事件的非常基本的示例,以调用ftList框架,然后在后代类中实现这些方法

TProcessTabellaPeople=class(TnterfacedObject,IProcessor)
procedure Select; virtual; abstract;
procedure Search; virtual; abstract;
..
end;
TProcessTabellaCustomer=class(TProcessTabellaPeople)
procedure Select; virtual; abstract;
procedure Search; virtual; abstract;
..
end;
{remove abstract clause to implement the methods using Shift+Ctrl+C,
or keep them to late binding in descendant Classes}

Add a reference to IProcessor in ITabella 在ITabella中添加对IProcessor的引用

ITabella = interface
  ['{D21924F9-BB41-493B-B06D-0908C0CA73D8}']
    fProc:IProcessor ;
    function GetCurrentActiveFrameType: TFrameInfo;
    procedure CreateLstFrame(ParentForm: TForm; Frame: TFrameClass);
    procedure CreateDtlFrame(ParentForm: TForm; Frame: TFrameClass);
    procedure DestroyLstFrame;
    procedure DestroyDtlFrame;
    procedure BringFrameToFront(FrameType: TFrameType);
    procedure OnDoubleClick;
    **procedure clickSelect;**
    **property Proc:IProcessor read fProc write fProc;**
  end;

Propagates TTabela.OnDoubleClick for corresponding IProcessor method 为相应的IProcessor方法传播TTabela.OnDoubleClick

procedure TTabella.OnDoubleClick;
begin
  BringFrameToFront(ftList);
  If Assigned(fProc) then Proc.Search(); {Call IProcessorMethod}
end;
procedure TTabella.ClickSelect;
begin
If Assigned(fProc) then Proc.Select(); {Call IProcessorMethod}
end;

using the interface properly On Create of TTabela pass the Processor, for example 正确使用接口在创建TTabela时传递处理器,例如

Var Tabella1: ITabella;
Begin
Tabela1:=TTabela.create();
Tabela1.proc:=TProcessor
end;

At this point I will recommend to you implement the constructor create passing the IProcessTabellaCustomer.create; 在这一点上,我将建议您通过IProcessTabellaCustomer.create;来实现构造函数create IProcessTabellaCustomer.create; {don't need to free using Interface vartype} {不需要使用Interface vartype释放}

For onClick of TButton do like that: 对于TButton onClick,请执行以下操作:

Tabela1.ClickSelect;
  1. Use procedure of object contents or TNotify class methods You can declare ClassMethods like this 对象内容或TNotify类方法的使用过程可以这样声明ClassMethods

     TSelectMethod = procedure(name:String; Sender:TObject) of object; ITabella = interface ['{D21924F9-BB41-493B-B06D-0908C0CA73D8}'] property Select:TSelectMethod read fSelect write fSelect; property Search:TNotifyEvent; end; 

Note that TNotifyEvent signs 请注意, TNotifyEvent标志

TNotifyEvent= procedure (Sender:TObject)of Object;

While in the form you create some methods with the same signs of Events Handler, 在表单中,您创建了一些带有事件处理程序符号的方法,

procedure TForm1.btnSearchClick(Sender:TObject)of Object; //*the same sign of TButtonClick, for example*
begin
end;
procedure TForm1.ShowSelected(name:String; Sender:TObject) of object;//*customized sign with new parameters
begin
showmessage(Format('Selected name%s',[name]));
end;

You can attribute the procedures for fields in run time 您可以在运行时为字段分配过程的属性

Tabella1:=TTabela.create();
Tabella1.Select:=Form1.btnSelectClick;
Tabella1.Search:=Form1.btnSearchClick;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM