Delphi通过接口

时间:2016-06-22 09:28:47

标签: delphi 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.

在界面中,我创建了两个框架,用于显示某些数据库表的列表和详细信息。 我创建的表单界面,brig以正确的框架前面并销毁它。 此时我需要将事件通知给创建的帧,但我不知道如何做这个工作之王。 例如,我需要通知详细信息框在列表框中按下按钮。

我该如何完成这项任务?

1 个答案:

答案 0 :(得分:0)

至少有两种方法可以做到这一点。 首先,我将推荐使用另一个接口;第二种方式是使用对象的过程,我们处理事件。 让我们把手放在击球手里!

  1. 在ITabella之前声明一个新接口,方法将要通知

    IProcessor=Interface
    {Shift+Ctrl+G}
    procedure Select; 
    procedure Search();
    
  2. 处理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}
    

    在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;
    

    传播TTabela.OnDoubleClick以获取相应的IProcessor方法

    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;
    

    正确使用界面 在创建TTabela时,通过处理器,例如

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

    此时我建议你实现构造函数create传递IProcessTabellaCustomer.create; {不需要使用Interface vartype自由}

    对于on TButton,请执行以下操作:

    Tabela1.ClickSelect;
    
    1. 使用对象内容或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;
      
    2. 请注意TNotifyEvent标志

      TNotifyEvent= procedure (Sender:TObject)of Object;
      

      在表单中,您创建了一些具有相同事件处理程序符号的方法,

      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;
      

      您可以在运行时

      中归档字段的过程
      Tabella1:=TTabela.create();
      Tabella1.Select:=Form1.btnSelectClick;
      Tabella1.Search:=Form1.btnSearchClick;