我如何处理Delphi中的事件?

时间:2017-03-22 14:28:23

标签: delphi

例如:在点击Button1之后,我有一些程序,即做某事。如何在按钮中处理onclick事件,而无需Button1Click中的代码? 我需要为Button1动态添加事件吗?

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure MyTest;
    procedure OutData(Sender: TObject);
    procedure FormClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



procedure TForm1.FormClick(Sender: TObject);
begin
  MyTest; // Start up Main
end;

procedure TForm1.MyTest; // Main

begin
  Button1.OnClick := OutData;
end;

procedure TForm1.OutData(Sender: TObject);
begin
  ShowMessage('Button clicked!');
end;

end.

好吧,它适用于一个事件,但是如果我需要处理,两个,三个事件或带有OnMouseDown等参数的事件?

2 个答案:

答案 0 :(得分:3)

事件是对象方法的引用。每个事件都使用某些参数显式输入。最常见的TNotifyEvent类型具有参数(Sender: TObject),例如您在OnClick事件中看到的内容。

然而,其他事件还有其他参数集。 OnMouseDown例如TMouseEvent,其参数为(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer)。您必须确保您的过程参数与事件类型的参数匹配。

这里基本上是如何在幕后设置所有内容......

type
  TNotifyEvent = procedure(Sender: TObject) of object;

  TMouseEvent = procedure(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer) of object;

  TControl = class(TComponent)
  ...
    property OnClick: TNotifyEvent read FOnClick write FOnCLick;
    property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
  ...
  end;

在这种情况下,您还可以将同一事件处理程序分配给同一事件类型 的多个不同事件 。例如,5个不同的按钮及其OnClick事件指向同一个处理程序。

procedure TForm1.MyButtonClick(Sender: TObject);
begin
  //Do Something...
end;

procedure TForm1.MyButtonMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  //Do Something...
end;

Button1.OnClick := MyButtonClick;
Button2.OnClick := MyButtonClick;
Button3.OnClick := MyButtonClick;
Button4.OnClick := MyButtonClick;
Button5.OnClick := MyButtonClick;
Button1.OnMouseDown := MyButtonMouseDown;
Button2.OnMouseDown := MyButtonMouseDown;
Button3.OnMouseDown := MyButtonMouseDown;
Button4.OnMouseDown := MyButtonMouseDown;
Button5.OnMouseDown := MyButtonMouseDown;

如果您希望这两个事件都做同样的事情, 您不能将相同的事件处理程序分配给不同类型的事件 ,因为它们具有不同的参数。在这种情况下,您需要使两个事件处理程序重定向到同一个东西。使用上面的示例,您可以在两个位置看到//Do Something...,但您可以执行相同的操作。但是,不要简单地复制代码。只需进行第三个过程,并使两个事件处理程序都调用该过程。

procedure TForm1.MyButtonClick(Sender: TObject);
begin
  DoSomething;
end;

procedure TForm1.MyButtonMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DoSomething;
end;

procedure TForm1.DoSomething;
begin
  //Do Something...
end;

另一方面,上面的例子在现实世界中没有任何意义,因为这会导致每次按钮点击都会调用两次相同的过程。这只是为了演示如何在你的问题中使用你的例子完成你想要做的事情。

答案 1 :(得分:0)

你可以使用类似观察者模式的东西,你可以使用"框"输入方法并在按钮点击时触发这些方法。

就像那样:

unit UFrmMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;

type
  TFrmMain = class(TForm)
    BtnClickMe: TButton;
    procedure FormCreate(Sender: TObject);
    procedure BtnClickMeClick(Sender: TObject);
  private
    FListOfButtonEvents : TList<TNotifyEvent>;

    procedure FirstButtonEvent(Sender : TObject);
    procedure SecondButtonEvent(Sender : TObject);
    procedure ThirdButtonEvent(Sender : TObject);
  public

  end;

var
  FrmMain: TFrmMain;

implementation

{$R *.dfm}

procedure TFrmMain.FormCreate(Sender: TObject);
begin
  FListOfButtonEvents := TList<TNotifyEvent>.Create();
  FListOfButtonEvents.Add(FirstButtonEvent);
  FListOfButtonEvents.Add(SecondButtonEvent);
  FListOfButtonEvents.Add(ThirdButtonEvent);
end;

procedure TFrmMain.BtnClickMeClick(Sender: TObject);
var
  Event : TNotifyEvent;
begin
  for Event in FListOfButtonEvents do
    Event(Sender);
end;

procedure TFrmMain.FirstButtonEvent(Sender : TObject);
begin
  ShowMessage('This is a First Method');
end;
procedure TFrmMain.SecondButtonEvent(Sender : TObject);
begin
  ShowMessage('This is a Second Method');
end;

procedure TFrmMain.ThirdButtonEvent(Sender : TObject);
begin
  ShowMessage('This is a Third Method');
end;

end.

我希望我能帮助你