Focus control in the frame

Hopefully I can explain what exactly the problem I am trying to solve. I have a form with 3 folders: 1 for buttons, 1 for data, and 1 for messages. The data pane is populated with some frames (one for each database table I need to use). The section of the table and the other used to display the record in the grid are controlled using the interface.

Here's the mesh frame:

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. 

      

and here's a detailed shot:

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.

      

Here is the interface:

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.

      

I've added an Editor block to the form that will use frames. In this example, I have not used a grid, but only a detail frame, and when the user selects a table, the records are displayed like the following example:

enter image description here

For example, the first button (with blank paper) is used to insert a new record into my database table, the second is used to edit the currently displayed record, etc.

I would like to focus the DBEdit component when the user clicks the "new" button or the "edit" button, but I cannot achieve this way of working.

Here is a source for using two frames (and some others)

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.

      

As you can see from the above code, the database is also used through the interface! Hope I was clear in my explanation, but I know the question gets a little more complicated. Can someone please help me?

+3


source to share


2 answers


The IEditori interface needs to be expanded to provide an external control form with a way to inform the interface what is needed. For example, an interface might have methods like AddingRecord, SavingRecord, ValidateRecord, etc. Then, the parent form doesn't need to be aware of the individual controls in the frame, but the frame can be informed of what's going on and respond correctly by setting focused controls. There may be other things you want to do for the new entry, such as defaults or setting additional state.



You can sometimes parse events directly from the table, such as OnNewRecord, but when you loop the table around, you need to make sure you are not stepping on events that were set elsewhere.

0


source


For example, to focus on edtIdEditore

when the user clicks a button btnEdit

, follow these steps:

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

      



Or replace frmTabelle

with the name of the instance of the form provided in var

your device section , then add the device to your proposal uses

and you're done.

+1


source







All Articles