例如:在点击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等参数的事件?
答案 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.
我希望我能帮助你