再次通过Delphi中的接口

时间:2015-02-12 07:27:59

标签: delphi

为了理解界面,我实现了一个带有表单的小应用程序,一个带有简单数据库的数据模块。 这是表格

enter image description here

数据模块仅包含连接,表和TDataSource组件。

接口单元是:

unit databaseInterface;

interface

uses
  MSAccess;

type
  IDBTest = interface
  ['{5B8CF4FF-66F7-402D-8E18-0159CB22F805}']
    procedure SetTable(table: TMSTable);
    function SetPriorRecord: Boolean;
    function SetNextRecord: Boolean;
  end;

implementation

end.

它的实现是这样的:

unit databaseImplementation;

interface

uses
  databaseInterface, database, MSAccess;

type
  TDBTest = class(TInterfacedObject, IDBTest)
  protected
    DBTable: TMSTable;
    FbtnPriorStatus: Boolean;
    procedure SetTable(Table: TMSTable);
    function SetPriorRecord: Boolean;
    function SetNextRecord: Boolean;
  public
    property Table: TMSTable read DBTable write SetTable;
  end;

implementation

{ TDBTest }

procedure TDBTest.SetTable(Table: TMSTable);
begin
  if DBTable <> Table then begin
    DBTable := Table;
    DBTable.Open;
  end;
end;

function TDBTest.SetPriorRecord: Boolean;
begin
  if not DBTable.Bof then begin
    DBTable.Prior;
    Result := DBTable.Bof;
  end else
    Result := True;
end;

function TDBTest.SetNextRecord: Boolean;
begin
  if not DBTable.Eof then begin
    DBTable.Next;
    Result := DBTable.Eof;
  end else
    Result := True;
end;

end.

现在,这是个问题。我的表格代码如下:

unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ExtCtrls, databaseInterface, databaseImplementation, JvExMask,
  JvToolEdit, JvMaskEdit, JvCheckedMaskEdit, JvDatePickerEdit,
  Vcl.StdCtrls, Vcl.Mask, Vcl.DBCtrls, JvDBDatePickerEdit, JvExControls,
  JvButton, JvTransparentButton, database;

type
  TfrmMain = class(TForm)
    pnlCommands: TPanel;
    pnlData: TPanel;
    pnlMessages: TPanel;
    bvlIcons: TBevel;
    bvlNavigation: TBevel;
    lblId: TLabel;
    lblFirstName: TLabel;
    lblLastName: TLabel;
    lblBirthday: TLabel;
    edtId: TDBEdit;
    edtFirstName: TDBEdit;
    edtLastName: TDBEdit;
    dtpBirthday: TJvDBDatePickerEdit;
    btnPrior: TJvTransparentButton;
    btnNext: TJvTransparentButton;
    procedure btnNextClick(Sender: TObject);
    procedure btnPriorClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    DBTest: IDBTest;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DBTest := TDBTest.Create;
end;

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  DBTest.SetTable(dmAuthors.tblAuthors);
end;

procedure TfrmMain.btnPriorClick(Sender: TObject);
begin
  btnPrior.Enabled := not DBTest.SetPriorRecord;
  btnNext.Enabled := True;
end;

procedure TfrmMain.btnNextClick(Sender: TObject);
begin
  btnNext.Enabled := not DBTest.SetNextRecord;
  btnPrior.Enabled := True;
end;

end.

所以当用户点击相关按钮然后相应的表格状态(BOF或EOF)时,我调用方法 SetPriorRecord SetNextRecord 禁用或启用按钮。 我想知道是否有办法通过接口设置按钮状态,将此操作与表单分离;例如以任何方式或其他方式绑定按钮,但我不知道如何做,如果可能的话! 我希望在解释问题时我很清楚。

2 个答案:

答案 0 :(得分:0)

现有界面还不够。您需要传递一些让客户端知道表状态的方法,但不要暴露TDataSet的详细逻辑(最好)。对事件处理程序的回调会起作用;触发TAction的方法可行;就像匿名方法一样。你基本上需要返回某种标志,表示BOF,EOF或其间的某个地方;也可能是记录#和记录数。

答案 1 :(得分:0)

我已经用这种方式修改了应用程序界面:

unit databaseInterface;

interface

uses
  MSAccess;

type

  IDBTest = interface
  ['{5B8CF4FF-66F7-402D-8E18-0159CB22F805}']
    procedure SetTable(table: TMSTable);
    procedure SetPriorRecord;
    procedure SetNextRecord;
    function GetIsBof: Boolean;
    function GetIsEof: Boolean;
    property IsBof: Boolean read GetIsBof;
    property IsEof: Boolean read GetIsEof;
  end;

implementation

end.

这是接口实现:

unit databaseImplementation;

interface

uses
  databaseInterface, database, MSAccess;

type
  TDBTest = class(TInterfacedObject, IDBTest)
  protected
    DBTable: TMSTable;
    FIsBof: Boolean;
    FIsEof: Boolean;
    procedure SetTable(Table: TMSTable);
    procedure SetPriorRecord;
    procedure SetNextRecord;
    function GetIsBof: Boolean;
    function GetIsEof: Boolean;
    procedure SetCursorStatus;
  public
    property Table: TMSTable read DBTable write SetTable;
    property IsBof: Boolean read GetIsBof;
    property IsEof: Boolean read GetIsEof;
  end;

implementation

{ TDBTest }

procedure TDBTest.SetTable(Table: TMSTable);
begin
  if DBTable <> Table then begin
    DBTable := Table;
    DBTable.Open;
  end;
end;


procedure TDBTest.SetPriorRecord;
begin
  try
    DBTable.Prior;
  finally
    SetCursorStatus;
  end;

end;

procedure TDBTest.SetNextRecord;
begin
  try
    DBTable.Next;
  finally
    SetCursorStatus;
  end;
end;

procedure TDBTest.SetCursorStatus;
begin
  FIsBof := DBTable.Bof;
  FIsEof := DBTable.Eof;
end;

function TDBTest.GetIsBof: Boolean;
begin
  Result := FIsBof;
end;

function TDBTest.GetIsEof: Boolean;
begin
  Result := FIsEof;
end;

end.

因此表单代码变为:

unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Mask, Vcl.DBCtrls, JvExMask, JvToolEdit,
  JvMaskEdit, JvCheckedMaskEdit, JvDatePickerEdit, JvDBDatePickerEdit,
  JvExControls, JvButton, JvTransparentButton, database, databaseInterface,
  databaseImplementation;

type

  TfrmMain = class(TForm)
    pnlCommands: TPanel;
    pnlData: TPanel;
    pnlMessages: TPanel;
    bvlIcons: TBevel;
    bvlNavigation: TBevel;
    lblId: TLabel;
    lblFirstName: TLabel;
    lblLastName: TLabel;
    lblBirthday: TLabel;
    edtId: TDBEdit;
    edtFirstName: TDBEdit;
    edtLastName: TDBEdit;
    dtpBirthday: TJvDBDatePickerEdit;
    btnPrior: TJvTransparentButton;
    btnNext: TJvTransparentButton;
    procedure btnNextClick(Sender: TObject);
    procedure btnPriorClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    DBTest: IDBTest;
    procedure SetNavButtonsStatus;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DBTest := TDBTest.Create;
end;

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  DBTest.SetTable(dmAuthors.tblAuthors);
end;


{ Begin table navigation ----------------------------------------------------- }

procedure TfrmMain.btnPriorClick(Sender: TObject);
begin
  DBTest.SetPriorRecord;
  SetNavButtonsStatus;
end;

procedure TfrmMain.btnNextClick(Sender: TObject);
begin
  DBTest.SetNextRecord;
  SetNavButtonsStatus;
end;

procedure TfrmMain.SetNavButtonsStatus;
begin
  btnPrior.Enabled := not DBTest.IsBof;
  btnNext.Enabled := not DBTest.IsEof
end;

{ End table navigation ------------------------------------------------------- }

end.

现在我认为按钮是分离的,但我不确定我找到的解决方案。可以这么好吗?