在运行时设置 Delphi 按钮的 OnClick 过程
Setting the OnClick procedure of a Delphi button at runtime
我有一个程序,我需要在其中更新数据库 table,其中的信息输入到编辑框中,末尾有一个按钮来进行更新。但是,表单是在运行时创建的,包括按钮在内的所有元素也是以相同的方式创建的。我想出一种允许数据库参数的方法是定义一个更新数据库的过程,例如:
procedure UpdateDatabase(Field1,Field2,Field3:string);
begin
//update database here...
end;
然后将我的按钮的 OnClick 事件分配给此过程,并使用预先填充的参数,如:
Button1.OnClick := UpdateDatabase(Edit1.text,Edit2.Text,Edit3.Text);
但是这些类型不兼容,因为它需要不同的数据类型。我还注意到通常不能将参数传递给 OnClick 函数。真的有办法实现我的提议吗?
这是我当前的创建按钮代码:
function buttonCreate(onClickEvent: TProcedure;
left: integer; top: integer; width: integer; height: integer;
anchors: TAnchors; caption: string; parent: TWinControl; form: TForm;): TButton;
var
theButton: TButton;
begin
theButton := TButton.Create(form);
theButton.width := width;
theButton.height := height;
theButton.left := left;
theButton.top := top;
theButton.parent := parent;
theButton.anchors := anchors;
//theButton.OnClick := onClickEvent;
theButton.Caption := caption;
result := theButton;
end;
感谢任何帮助!
事件处理程序必须准确地声明事件类型的定义方式。 OnClick
事件被声明为 TNotifyEvent
,它采用参数 (Sender: TObject)
。你不能违反这条规则。
对于您的情况,您可以将自己的过程包装在事件处理程序中,就像这样...
procedure TForm1.Button1Click(Sender: TObject);
begin
UpdateDatabase(Edit1.text,Edit2.Text,Edit3.Text);
end;
请注意 TNotifyEvent
是一个过程 "of object",这意味着您的事件处理程序必须在对象内部声明。在您的情况下,事件处理程序应该在您的表单内声明(而不是在全局位置)。
您是否考虑过将编辑控件作为字段成员从 TButton 降级控件?
这是一个示例,希望您能从中获得一些想法。
TButtonHack = class(TButton)
fEdit1,
fEdit2,
fEdit3: TEdit;
procedure Click; override;
public
constructor Create(AOwner: TComponent; AParent: TWinControl; Edit1, Edit2, Edit3: TEdit); Reintroduce;
end;
Constructor TButtonHack.Create(AOwner: TComponent; AParent: TWinControl; Edit1, Edit2, Edit3: TEdit);
begin
inherited Create(AOwner);
Parent := AParent;
Left := 100;
Top := 100;
Width := 100;
Height := 20;
Caption := 'ButtonHack';
fEdit1 := Edit1;
fEdit2 := Edit2;
fEdit3 := Edit3;
end;
procedure TButtonHack.Click;
begin
Inherited Click;
Showmessage(fEdit1.text+','+ fEdit2.text+','+fEdit3.text);
end;
要进行测试,请在表单上放置一个按钮和三个 TEdit。
procedure TForm1.Button1Click(Sender: TObject);
var
ButtonHack: TButtonHack;
begin
ButtonHack := TButtonHack.Create(Form1, Form1, Edit1, Edit2, Edit3);
end;
您是提前创建编辑还是在 TButtonHack 中创建编辑由您决定。作为示例,我已尽可能简化它。
我有一个程序,我需要在其中更新数据库 table,其中的信息输入到编辑框中,末尾有一个按钮来进行更新。但是,表单是在运行时创建的,包括按钮在内的所有元素也是以相同的方式创建的。我想出一种允许数据库参数的方法是定义一个更新数据库的过程,例如:
procedure UpdateDatabase(Field1,Field2,Field3:string);
begin
//update database here...
end;
然后将我的按钮的 OnClick 事件分配给此过程,并使用预先填充的参数,如:
Button1.OnClick := UpdateDatabase(Edit1.text,Edit2.Text,Edit3.Text);
但是这些类型不兼容,因为它需要不同的数据类型。我还注意到通常不能将参数传递给 OnClick 函数。真的有办法实现我的提议吗?
这是我当前的创建按钮代码:
function buttonCreate(onClickEvent: TProcedure;
left: integer; top: integer; width: integer; height: integer;
anchors: TAnchors; caption: string; parent: TWinControl; form: TForm;): TButton;
var
theButton: TButton;
begin
theButton := TButton.Create(form);
theButton.width := width;
theButton.height := height;
theButton.left := left;
theButton.top := top;
theButton.parent := parent;
theButton.anchors := anchors;
//theButton.OnClick := onClickEvent;
theButton.Caption := caption;
result := theButton;
end;
感谢任何帮助!
事件处理程序必须准确地声明事件类型的定义方式。 OnClick
事件被声明为 TNotifyEvent
,它采用参数 (Sender: TObject)
。你不能违反这条规则。
对于您的情况,您可以将自己的过程包装在事件处理程序中,就像这样...
procedure TForm1.Button1Click(Sender: TObject);
begin
UpdateDatabase(Edit1.text,Edit2.Text,Edit3.Text);
end;
请注意 TNotifyEvent
是一个过程 "of object",这意味着您的事件处理程序必须在对象内部声明。在您的情况下,事件处理程序应该在您的表单内声明(而不是在全局位置)。
您是否考虑过将编辑控件作为字段成员从 TButton 降级控件?
这是一个示例,希望您能从中获得一些想法。
TButtonHack = class(TButton)
fEdit1,
fEdit2,
fEdit3: TEdit;
procedure Click; override;
public
constructor Create(AOwner: TComponent; AParent: TWinControl; Edit1, Edit2, Edit3: TEdit); Reintroduce;
end;
Constructor TButtonHack.Create(AOwner: TComponent; AParent: TWinControl; Edit1, Edit2, Edit3: TEdit);
begin
inherited Create(AOwner);
Parent := AParent;
Left := 100;
Top := 100;
Width := 100;
Height := 20;
Caption := 'ButtonHack';
fEdit1 := Edit1;
fEdit2 := Edit2;
fEdit3 := Edit3;
end;
procedure TButtonHack.Click;
begin
Inherited Click;
Showmessage(fEdit1.text+','+ fEdit2.text+','+fEdit3.text);
end;
要进行测试,请在表单上放置一个按钮和三个 TEdit。
procedure TForm1.Button1Click(Sender: TObject);
var
ButtonHack: TButtonHack;
begin
ButtonHack := TButtonHack.Create(Form1, Form1, Edit1, Edit2, Edit3);
end;
您是提前创建编辑还是在 TButtonHack 中创建编辑由您决定。作为示例,我已尽可能简化它。