我刚刚开始学习德尔福,而且我遇到了问题。我从另一个表单刷新DBGrid。我的代码:
Form1中:
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如何?
答案 0 :(得分:4)
使用你的模式,我会做这样的事情:
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;
答案 1 :(得分:1)
解决从其他单元执行代码问题的更通用方法只是向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
的任何引用,因此此方法保留了单元的隔离。
正如其他人在评论中指出的那样,这可能不是解决特定问题的理想解决方案,但它确实回答了直接问题,并提供了一种在类和单元边界之间干净地调用代码的方法。
答案 2 :(得分:0)
简单的黑客方式,而不是我会做的事情
(FOwner as TForm1).grid.refresh
建议的方法是在创建FreeNotification
Form2
Forms.FreeNotification(Self).
当Form1
被销毁时,这会向Form2
发送通知方法。在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;
注意我没有使用它,但它应该可以工作。