【问题标题】:Focus control in a frame帧中的焦点控制
【发布时间】:2015-05-15 13:53:59
【问题描述】:

我希望我能解释一下我要解决的问题。 我有一个包含 3 个面板的表单:1 个用于按钮,1 个用于数据,1 个用于消息。数据面板填充了一些框架(我需要使用的每个数据库表一个)。 表格详细框架和另一个用于在网格中显示记录的框架通过界面进行操作。

这里是网格框:

unit FraEdtList;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.Grids, Vcl.DBGrids;

type
  TFraEdtLst = class(TFrame)
    grdEditori: TDBGrid;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

uses database;

end. 

这里是细节框架:

unit FraEdtDetail;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.Mask, Vcl.DBCtrls;

type
  TFraEdtDtl = class(TFrame)
    lblIdEditore: TLabel;
    edtIdEditore: TDBEdit;
    lblDscEditore: TLabel;
    edtDscEditore: TDBEdit;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

uses database;

{ TFraEdtDtl }


{ TFraEdtDtl }

end.

这里是接口单元:

unit Editori;

interface

uses
  FraEdtList, FraEdtDetail;

type
  IEditori = interface
    procedure CreateFraEdtLst();
    procedure CreateFraEdtDtl();
  end;

  TEditori = class(TInterfacedObject, IEditori)
  private
    FEdtLst: TfraEdtLst;
    FEdtDtl: TfraEdtDtl;
    procedure CreateFraEdtLst();
    procedure CreateFraEdtDtl();
  end;

implementation

{ TAutori }

uses Tabelle;

procedure TEditori.CreateFraEdtLst;
begin
  FEdtLst := FEdtLst.Create(frmTabelle);
  FEdtLst.Parent := frmTabelle.pnlDta;
end;

procedure TEditori.CreateFraEdtDtl;
begin
  FEdtDtl := TfraEdtDtl.Create(frmTabelle);
  FEdtDtl.Parent := frmTabelle.pnlDta;
end;

end.

我已将“Editori”单元添加到将使用框架的表单中。 对于此示例,我没有使用网格,而仅使用了详细信息框架,当用户选择表格时,记录将显示为以下示例:

例如,第一个按钮(带有空白纸的按钮)用于在我的数据库表中插入新记录,第二个按钮用于编辑当前显示的记录,依此类推。

问题是当用户单击“新建”按钮或“编辑”按钮时,我想关注 DBEdit 组件,但我无法进行此类操作。

这是使用这两个框架(以及其他一些框架)的来源

unit Tabelle;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ExtCtrls, RzPanel, dxBevel, Vcl.Buttons, PngSpeedButton, Autori,
  Editori, DBInterface, DbImplementation, MSAccess;

type
  TfrmTabelle = class(TForm)
    pnlCmd: TRzPanel;
    pnlDta: TRzPanel;
    pnlMsg: TRzPanel;
    bvlCmd: TdxBevel;
    bvlNav: TdxBevel;
    btnNew: TPngSpeedButton;
    btnEdit: TPngSpeedButton;
    btnSave: TPngSpeedButton;
    btnDelete: TPngSpeedButton;
    btnUndo: TPngSpeedButton;
    btnPrior: TPngSpeedButton;
    btnNext: TPngSpeedButton;
    procedure FormCreate(Sender: TObject);
    procedure btnNewClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnPriorClick(Sender: TObject);
    procedure btnNextClick(Sender: TObject);
    procedure btnEditClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
    procedure btnUndoClick(Sender: TObject);
  private
    FDBTable: IDBTable;
    FAutori: IAutori;
    FEditori: IEditori;
  public
    procedure SetButtonsStatus(stsNew, stsEdit, stsSave, stsDelete, stsUndo, stsPnlDta: Boolean);
    procedure SetTableName(Table: TMSTable);
  end;

var
  frmTabelle: TfrmTabelle;

implementation

{$R *.dfm}

{ TfrmTabelle }

{ Inizializzazione }
procedure TfrmTabelle.FormCreate(Sender: TObject);
begin
  FDBTable := TDBtable.Create;
end;

{ Impostazione tabella di lavoro }
procedure TfrmTabelle.SetTableName(Table: TMSTable);
begin
  FDBTable.DBTable := Table;
  SetButtonsStatus(True, True, False, True, False, False);

  // Tabella autori
  if Table.TableName = 'Autori' then begin
    if not Assigned(FAutori) then begin
      FAutori := TAutori.Create;
      FAutori.CreateFraAutDtl;
    end;
  end;

  // Tabella editori
  if Table.TableName = 'Editori' then begin
    if not Assigned(FEditori) then begin
      FEditori := TEditori.Create;
      FEditori.CreateFraEdtDtl;
    end;
  end;

end;

{ Impostazione pulsanti }
procedure TfrmTabelle.SetButtonsStatus(stsNew, stsEdit, stsSave, stsDelete, stsUndo, stsPnlDta: Boolean);
var
  flgTblEmpty: Boolean;
begin
  flgTblEmpty := FDBTable.TableIsEmpty;
  btnNew.Enabled := stsNew;
  btnEdit.Enabled := stsEdit and not flgTblEmpty;
  btnSave.Enabled := stsSave;
  btnDelete.Enabled := stsDelete and not flgTblEmpty;
  btnUndo.Enabled := stsUndo;
  pnlDta.Enabled := stsPnlDta;
end;

{ Inserimento nuovo record }
procedure TfrmTabelle.btnNewClick(Sender: TObject);

begin
  if FDBTable.NewRecord then
    SetButtonsStatus(False, False, True, False, True, True);
end;

{ Editazione record }
procedure TfrmTabelle.btnEditClick(Sender: TObject);
begin
  if FDBTable.EditRecord then
    SetButtonsStatus(False, False, True, False, True, True);
end;

{ Salvataggio record }
procedure TfrmTabelle.btnSaveClick(Sender: TObject);
begin
  if FDBTable.SaveRecord then
    SetButtonsStatus(True, True, False, True, False, False);
end;

{ Cancellazione record }
procedure TfrmTabelle.btnDeleteClick(Sender: TObject);
begin
  if FDBTable.DeleteRecord then
    SetButtonsStatus(True, True, False, True, False, False);
end;

{ Annulla l'operazione in corso }
procedure TfrmTabelle.btnUndoClick(Sender: TObject);
begin
  if FDBTable.UndoRecord then
    SetButtonsStatus(True, True, False, True, False, False);
end;



{ Record precedente }
procedure TfrmTabelle.btnPriorClick(Sender: TObject);
begin
  if FDBTable.PriorRecord then
    SetButtonsStatus(True, True, False, True, False, False);
end;

{ Record successivo }
procedure TfrmTabelle.btnNextClick(Sender: TObject);
begin
  FDBTable.NextRecord;
end;

end.

正如您在上面的代码中看到的,数据库也是通过接口使用的! 我希望我的解释很清楚,但我知道这个问题有点复杂。 有人能帮帮我吗?

【问题讨论】:

  • 使用edtIdEditore.SetFocus;ActiveControl := edIdEditore; 有什么问题?
  • 问题是 edtIdEditore 控件位于一个由接口控制的框架中,而“tabelle”表单不知道该控件。

标签: delphi interface


【解决方案1】:

例如,当用户单击btnEdit 时,要关注edtIdEditore,请执行以下操作:

{ Editazione record }
procedure TfrmTabelle.btnEditClick(Sender: TObject);
begin
  if FDBTable.EditRecord then
    SetButtonsStatus(False, False, True, False, True, True);
  frmTabelle.edtIdEditore.SetFocus;
end;

或将frmTabelle 替换为您单元的var 部分中公开的表单实例的名称,然后将该单元添加到您的uses 子句中,您就完成了。

【讨论】:

    【解决方案2】:

    IEditori 接口需要扩展,以便为外部控制表单提供一种通知接口所需内容的方法。例如,接口可以具有诸如AddingRecord、SavingRecord、ValidateRecord 等方法。然后父窗体不需要了解Frame 上的各个控件,但是可以通过设置焦点控件来告知Frame 发生了什么并做出正确反应。您可能还想做其他事情来创建新记录,例如默认值或设置其他状态。

    您有时可以通过直接从表中处理事件(例如 OnNewRecord)来解决问题,但是当您传递一个表时,您需要确保您不会踩到在其他地方设置的事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-06
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 2013-12-05
      相关资源
      最近更新 更多