Delphi FMX:如何将事件添加到对象中(就像TEdit.OnChange)
Delphi FMX: How to add an Event into an object (just like TEdit.OnChange)
假设我创建了一个新的 FMX 项目,上面只有一个 TButton 和一个 TProgressBar。
现在我使用 [Shift] + [F11] 添加了一个 'Countertest.pas' 文件。 (见下面的代码)
现在我已经在 'Unit1.pas'(主应用程序)中实施了一个程序,由 'Countertest.pas' 文件中的程序触发以更改 TProgressBar 的值。
在 'Unit1.pas' 中我写了这个从 'Countertest.pas' 文件中调用:
procedure TForm1.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached '+IntToStr(newPercentage)+' Percent ;)');
end;
为了简化我的问题,这是我精简的 'Countertest.pas' 文件:
unit Countertest;
interface
uses FMX.Memo; // Will be used later
type
TCountertest = Class
private
zahl: Integer;
published
constructor Create();
destructor Destroy();
procedure Counter();
property Percentage: Integer read zahl;
end;
implementation
constructor TCountertest.Create();
begin
end;
destructor TCountertest.Destroy();
begin
end;
procedure TCountertest.Counter();
begin
for i := 0 to 1337 do
Percentage:=0;
begin
zahl:=i;
if Percentage<>round(i / 100) then
begin
// Here I want to call a Procedure inside 'Unit1.pas' to change a Value of the TProgressBar (and some other components like TLabel.Text)
end;
Percentage:=round(i / 100);
end;
end;
end.
据我所知,可以使用 procedure(Sender: TObject) of object;
之类的东西,这似乎是我想要使用的东西,但我不知道如何使用它。
我的意图是编写类似于 TEdit 控件中使用的 OnChange 事件的内容。
当然,我可以将 'Unit1.pas' 添加到 'Countertest.pas' 的 Uses 部分,然后直接调用该过程,但由于必须处理 TCountertest 的多个实例,我希望它更像这样:
procedure InstanceOfTCountertest.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached a new Percent ;)');
end;
在最终的应用程序中有多个 TCountertest 实例,因此我也有多个进度条(以及其他 GUI 组件,例如 TLabel)。
也许还有其他方法可以做到这一点,所以请随时提出任何建议,以符合显示这些实例进度的目的。
通常,组件(例如 TButton
)将事件公开为属性(例如:TButton.OnCLick
),这取决于父组件或兄弟组件(父组件 TForm
在这种情况下)设置事件处理程序。假设我们要更改 Button1.OnClick
事件处理程序:
// Setting the handler:
procedure TForm1.Create(AOwner: TComponent);
begin
Button1.OnClick := Self.MyCustomClickHandler;
end;
// And the handler implementation:
procedure TForm1.MyCustomClickHandler(Sender: TObject);
begin
// ...
end;
因此,我想您希望为您的 TCountertest
创建一个事件,例如 TCountertest.OnCount
,以便其他组件/表单可以设置处理程序并响应计数器进度的变化。让我们描述一下如何使用 Delphi 方式(未经测试的代码):
首先,您的组件应该实现并公开事件:
unit Countertest;
interface
type
// Custom type for your event handler
TCountEvent = procedure(Sender: TObject; Percentage: Integer) of object;
TCountertest = Class
private
FPercentage: Integer;
// Variable that holds the event handler set by the user
FOnCount: TCountEvent;
// Internal event trigger
procedure DoCount();
public
constructor Create();
destructor Destroy();
procedure Counter();
published
property Percentage: Integer read FPercentage;
// This is the property for your event handler assignment
property OnCount: TCountEvent read FOnCount write FOnCount;
end;
implementation
constructor TCountertest.Create();
begin
// Initialize event handler to nil
FOnCount := nil;
end;
destructor TCountertest.Destroy();
begin
end;
// Event trigger
procedure TCounterTest.DoCount();
begin
// Check that the user assigned an event handler
if Assigned(FOnCount) then
FOnCount(Self, FPercentage);
end;
procedure TCountertest.Counter();
begin
// Your code (update FPercentage in your code)...
// When you need to trigger the event:
DoCount();
// Rest of your code...
end;
end.
现在我们已准备好为您的实例创建和设置事件处理程序 TCountertest
:
unit Unit1;
// ...
type
TForm1 = class
private
// ...
// Declare the handler
procedure CounterCount(Sender: TObject; Percentage: Integer);
public
// ...
end;
implementation
// ...
// Implement the handler
procedure TForm1.CounterCount(Sender: TObject; Percentage: Integer);
begin
ProgressBar1.Value := Percentage;
end;
// Set the event handlers for your counters
procedure TForm1.Create(AOwner: TComponent);
var
Counter1, Counter2: TCountertest;
begin
// Create the counters
Counter1 := TCountertest.Create();
Counter2 := TCountertest.Create();
// Set the event handlers
Counter1.OnCount := Self.CounterCount;
Counter2.OnCount := Self.CounterCount;
end;
end.
希望对您有所帮助。如果没有,请随时询问。
假设我创建了一个新的 FMX 项目,上面只有一个 TButton 和一个 TProgressBar。 现在我使用 [Shift] + [F11] 添加了一个 'Countertest.pas' 文件。 (见下面的代码)
现在我已经在 'Unit1.pas'(主应用程序)中实施了一个程序,由 'Countertest.pas' 文件中的程序触发以更改 TProgressBar 的值。
在 'Unit1.pas' 中我写了这个从 'Countertest.pas' 文件中调用:
procedure TForm1.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached '+IntToStr(newPercentage)+' Percent ;)');
end;
为了简化我的问题,这是我精简的 'Countertest.pas' 文件:
unit Countertest;
interface
uses FMX.Memo; // Will be used later
type
TCountertest = Class
private
zahl: Integer;
published
constructor Create();
destructor Destroy();
procedure Counter();
property Percentage: Integer read zahl;
end;
implementation
constructor TCountertest.Create();
begin
end;
destructor TCountertest.Destroy();
begin
end;
procedure TCountertest.Counter();
begin
for i := 0 to 1337 do
Percentage:=0;
begin
zahl:=i;
if Percentage<>round(i / 100) then
begin
// Here I want to call a Procedure inside 'Unit1.pas' to change a Value of the TProgressBar (and some other components like TLabel.Text)
end;
Percentage:=round(i / 100);
end;
end;
end.
据我所知,可以使用 procedure(Sender: TObject) of object;
之类的东西,这似乎是我想要使用的东西,但我不知道如何使用它。
我的意图是编写类似于 TEdit 控件中使用的 OnChange 事件的内容。
当然,我可以将 'Unit1.pas' 添加到 'Countertest.pas' 的 Uses 部分,然后直接调用该过程,但由于必须处理 TCountertest 的多个实例,我希望它更像这样:
procedure InstanceOfTCountertest.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached a new Percent ;)');
end;
在最终的应用程序中有多个 TCountertest 实例,因此我也有多个进度条(以及其他 GUI 组件,例如 TLabel)。 也许还有其他方法可以做到这一点,所以请随时提出任何建议,以符合显示这些实例进度的目的。
通常,组件(例如 TButton
)将事件公开为属性(例如:TButton.OnCLick
),这取决于父组件或兄弟组件(父组件 TForm
在这种情况下)设置事件处理程序。假设我们要更改 Button1.OnClick
事件处理程序:
// Setting the handler:
procedure TForm1.Create(AOwner: TComponent);
begin
Button1.OnClick := Self.MyCustomClickHandler;
end;
// And the handler implementation:
procedure TForm1.MyCustomClickHandler(Sender: TObject);
begin
// ...
end;
因此,我想您希望为您的 TCountertest
创建一个事件,例如 TCountertest.OnCount
,以便其他组件/表单可以设置处理程序并响应计数器进度的变化。让我们描述一下如何使用 Delphi 方式(未经测试的代码):
首先,您的组件应该实现并公开事件:
unit Countertest;
interface
type
// Custom type for your event handler
TCountEvent = procedure(Sender: TObject; Percentage: Integer) of object;
TCountertest = Class
private
FPercentage: Integer;
// Variable that holds the event handler set by the user
FOnCount: TCountEvent;
// Internal event trigger
procedure DoCount();
public
constructor Create();
destructor Destroy();
procedure Counter();
published
property Percentage: Integer read FPercentage;
// This is the property for your event handler assignment
property OnCount: TCountEvent read FOnCount write FOnCount;
end;
implementation
constructor TCountertest.Create();
begin
// Initialize event handler to nil
FOnCount := nil;
end;
destructor TCountertest.Destroy();
begin
end;
// Event trigger
procedure TCounterTest.DoCount();
begin
// Check that the user assigned an event handler
if Assigned(FOnCount) then
FOnCount(Self, FPercentage);
end;
procedure TCountertest.Counter();
begin
// Your code (update FPercentage in your code)...
// When you need to trigger the event:
DoCount();
// Rest of your code...
end;
end.
现在我们已准备好为您的实例创建和设置事件处理程序 TCountertest
:
unit Unit1;
// ...
type
TForm1 = class
private
// ...
// Declare the handler
procedure CounterCount(Sender: TObject; Percentage: Integer);
public
// ...
end;
implementation
// ...
// Implement the handler
procedure TForm1.CounterCount(Sender: TObject; Percentage: Integer);
begin
ProgressBar1.Value := Percentage;
end;
// Set the event handlers for your counters
procedure TForm1.Create(AOwner: TComponent);
var
Counter1, Counter2: TCountertest;
begin
// Create the counters
Counter1 := TCountertest.Create();
Counter2 := TCountertest.Create();
// Set the event handlers
Counter1.OnCount := Self.CounterCount;
Counter2.OnCount := Self.CounterCount;
end;
end.
希望对您有所帮助。如果没有,请随时询问。