在运行时设置 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 中创建编辑由您决定。作为示例,我已尽可能简化它。