Delphi FMX:如何将事件添加到对象中(就像TEdit.OnChange一样)

时间:2017-09-07 01:14:54

标签: oop delphi events firemonkey

假设我创建了一个新的FMX项目,其上只有一个TButton和一个TProgressBar。 现在我添加了一个' Countertest.pas'文件使用[Shift] + [F11]。 (见下面的代码)

现在我已经在' Unit1.pas'中实施了一个程序。 (主应用程序)由“Countertest.pas”中的程序触发。文件以更改TProgressBar的值。

Inside' 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事件。

当然我可以添加&#39; Unit1.pas&#39;进入&#39; Countertest.pas&#39;的使用部分然后直接调用该过程,但由于必须处理TCountertest的多个实例,我想让它更像这样:

procedure InstanceOfTCountertest.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached a new Percent ;)');
end;

在最终应用程序中有多个TCountertest实例,因此我也有多个Progressbars(以及其他GUI组件,如TLabels)。 也许还有其他方法可以做到这一点,所以请随意提出任何建议,以达到显示这些实例的进展的目的。

1 个答案:

答案 0 :(得分:3)

通常,组件(例如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.

我希望它有所帮助。如果没有,请随时询问。