簡體   English   中英

從delphi中的另一種形式刷新DBGrid

[英]Refresh DBGrid from another form in delphi

我剛剛開始學習Delphi,但遇到了問題。 我將從另一種形式刷新DBGrid。 我的代碼:

表格1:

unit uForm1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, Grids, DBGrids, StdCtrls;

type
  TForm1 = class(TForm)
    btnAdd: TButton;
    grid: TDBGrid;
    ADOQuery1: TADOQuery;
    DataSource1: TDataSource;
    procedure btnAdd(Sender: TObject);
  private
  public
       constructor Create(Owner:TComponent); overload;
  end;

var
  form1: TForm1;

implementation

uses uForm2, uDbOperations;

{$R *.dfm}

procedure TForm1.btnAddClick(Sender: TObject);
var
  frm : TForm2;
begin
  frm := TForm2.Create(form1);
  frm.ShowModal;
  frm.Free;
end;

表格2:

unit uForm2;
procedure TForm2.btnAddClick(Sender: TObject);
var
  query : string;
begin
       query := 'Insert into Employees(Name) Values('''+txtName.Text+''');';
       DbOperations.InsertOrUpdate(query, ADOQuery1);
        ModalResult := mrCancel;
        //And this here I'd refresh grid on form1           
end;
end.

在form2中添加記錄后,如何在form1中刷新dbgrid? 我已經嘗試了很多方法,但是沒有成功。 我知道在C#中需要在構造函數中傳遞引用,但是delphi怎么做?

使用您的模式,我將執行以下操作:

procedure TForm1.btnAddClick(Sender: TObject);
var
  frm : TForm2;
begin
  frm := TForm2.Create(form1);
  try
    if frm.ShowModal = mrOK then
    begin
      Grid.Datasource.Dataset.Refresh;
      // some databases require open/close to refresh
      // in this case Grid.Datasource.Dataset.close;
      //              Grid.Datasource.Dataset.Open;
    end;
  finally
    frm.Free;
  end
end;

procedure TForm2.btnAddClick(Sender: TObject);
var
  query : string;
begin
  query := 'Insert into Employees(Name) Values('''+txtName.Text+''');';
  DbOperations.InsertOrUpdate(query, ADOQuery1);
  ModalResult := mrOK;
  // let a cancel button on Form2 perform ModalResult = mrCancel  
  // to avoid unnecessary dataset refreshes..      
end;

解決從其他單元執行代碼的問題的一種更通用的方法是簡單地向TForm2添加一個事件。

 TForm2 = class(TForm)
 private
   FOnDataInserted : TNotifyEvent;
 public
   property OnDataInserted : TNotifyEvent read FOnDataInserted write FOnDataInserted;
 end;

將此事件實施為:

procedure TForm2.btnAddClick(Sender: TObject);
var
  query : string;
begin
  query := 'Insert into Employees(Name) Values('''+txtName.Text+''');';
  DbOperations.InsertOrUpdate(query, ADOQuery1);
  ModalResult := mrCancel;
  //And this here I'd refresh grid on form1
  If Assigned(FOnDatabaseInsert) then FOnDatabaseInsert(self);                
end;

現在,要為事件分配方法,請在TForm1中聲明一個合適的方法來處理該事件:

procedure TForm1.Form2DataInserted(Sender: TObject);
begin
  // do something, update grid, etc...
end;

在創建表單時:

procedure TForm1.btnAddClick(Sender: TObject);
var
  frm : TForm2;
begin
  frm := TForm2.Create(form1);
  try
    frm.OnDataInserted := Form2DataInserted;
    frm.ShowModal;
  finally
    frm.Free;
  end;
end;

此模型使您可以在代碼中的任何位置執行任何類型的回調。 這是依賴項注入的一種形式,因為擁有組件提供了方法TForm2不包含對TForm1任何引用,因此此方法保留了單位的隔離。

正如其他人在評論中指出的那樣,這可能不是您特定問題的理想解決方案,但是它確實回答了直接的問題,並提供了一種跨類和單元邊界干凈地調用代碼的方法。

簡單的破解方式,不是我會做的

 (FOwner as TForm1).grid.refresh

推薦的方法是在創建Form2之后注冊一個FreeNotification

Forms.FreeNotification(Self).

Form2被銷毀時,這將向Form1發送一個Notification方法。 在Form1中添加一個事件

protected
  procedure Notification(AComponent: TComponent; Operation: TOperation); override;

實施中

procedure TForm1.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (AComponent is TForm) and (Operation = opRemove) then
  begin
    grid.Refresh;
  end;
end; 

注意我還沒有使用它,但是它應該可以工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM