Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Problem mit eigenen Ereignissen in abgeleiteter Komponente


Kay E. - Mo 27.06.11 10:10
Titel: Problem mit eigenen Ereignissen in abgeleiteter Komponente
Hallihallo!

Ich möchte eine Komponente bauen, die von TCustomPanel abgeleitet ist und die zwei Buttons (ButtonLeft und ButtonRight) enthält. Die Buttons sind in einer TList untergebracht.
Ich will jetzt Ereignisse für die Buttons integrieren, einmal OnLeftButtonClick und OnRightButtonClick, die sinnigerweise dann ausgelöst werden sollen, wenn der entsprechende Button gedrückt wird. Mein Code sieht bisher (als Auszug) so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
TTastenfeld = class(TCustomPanel)
    private
      ButtonList: TList;
      FOnLeftButtonClick: TLeftButtonClickEvent;
      FOnRightButtonClick: TRightButtonClickEvent;
      procedure LeftButtonClick(Sender: TObject);
      procedure RightButtonClick(Sender: TObject);
    published
      property OnLeftButtonClick: TLeftButtonClickEvent read FOnLeftButtonClick write FOnLeftButtonClick;
      property OnRightButtonClick: TRightButtonClickEvent read FOnRightButtonClick write FOnRightButtonClick;
  end;

implementation

constructor TTastenfeld.Create(AOwner: TComponent);
var
  vButton: TTastenfeldButton;
  i: Integer;
begin
  inherited;
  ButtonList := TList.Create;

  for i := ord(Low(TButtonPos)) to ord(High(TButtonPos)) do
  begin
    vButton := TTastenfeldButton.Create(self); 
    vButton.Caption := GetInitialButtonCaption(TButtonPos(i));
    if vButton.Caption = CaptionLeft then
      vButton.OnClick := OnLeftButtonClick
    else
    if vButton.Caption = CaptionRight then
      vButton.OnClick := OnRightButtonClick
    end;
    ButtonList.Add(vButton);
  end;
end;

procedure TTastenfeld.LeftButtonClick(Sender: TObject);
begin
  inherited OnClick(Sender);
  if assigned(OnLeftButtonClick) then
    OnLeftButtonClick(Sender);
end;

procedure TTastenfeld.RightButtonClick(Sender: TObject);
begin
  inherited OnClick(Sender);
  if assigned(OnRightButtonClick) then
    OnRightButtonClick(Sender);
end;


Die Ereignisse werden zwar verfügbar, aber wenn ich sie zuweise und die Buttons drücke, wird offenbar kein Ereignis ausgelöst. Wo liegt der Fehler in meinem Code?

Wäre für jede Hilfestellung dankbar :)

Grüße Kay


Andreas L. - Mo 27.06.11 10:30

Einfach so zuweisen geht nicht, du musst einen Handler für die Button-Ereignisse in deine Klasse integrieren.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
type
  TMyPanel = class(TCustomPanel)
  private
    FOnButtonLeftClick: TNotifyEvent;
  protected
    procedure HandleButtonLeftClick(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ButtonLeftClick: TNotifyEvent read FOnButtonLeftClick write FOnButtonLeftClick;   

...

constructor TMyPanel.Create(AOwner: TComponent); 
begin
  inherited Create(AOwner);

  ButtonLeft.OnClick := HandleButtonLeftClick;
end;

procedure TMyPanel.HandleButtonLeftClick(Sender: TObject);
begin

  // evtl. noch was machen

  if Assigned(FOnButtonLeftClick) then
    OnButtonLeftClick(Sender);

end;


Habe den Code jetzt nicht getestet, sollte aber funktionieren ;-)

EDIT: Im Prinzip machst du es schon richtig, nur im Contructor darfst du nicht die Property OnButtonLeftClick sondern die procedure ButtonLeftClick zuweisen. Für die Properties würde ich keine eigenen Typen definieren sondern das Standard TNotifyEvent verwenden. Außerdem darfst du in der ButtonLeftClick-procedure nicht inherited OnClick aufrufen.


Kay E. - Mo 27.06.11 10:48

Spitze! Mit der Zuweisung an den Handler und ohne die inherited's funktionierts so, wie es soll. Vielen Dank :)