Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TStringGrid fängt dem TBitBtn das OnClick-Ereignis weg


UweK - Di 27.09.22 12:04
Titel: TStringGrid fängt dem TBitBtn das OnClick-Ereignis weg
Hallo,

Ich erzeuge dynamisch eine Reihe von TBitBtn und zeichne sie mit TStringGrid.OnDrawCell flächenfüllend in bestimmte Zellen des TStringGrid. Das funktioniert optisch am besten, wenn ich die TBitBtn direkt in das TStringGrid einfüge:

Delphi-Quelltext
1:
2:
3:
BitBtn:= TBitBtn.Create(Self);
BitBtn.OnClick:= MeineOnClickProzedur;
StringGrid.InsertControl(BitBtn);

Aber großer Kummer: Die TBitBtn lassen sich zwar anklicken und zeigen dann auch die dafür typische Animation. Das Ereignis TBitBtn.OnClick wird jedoch nicht ausgelöst, und somit auch MeineOnClickProzedur nicht ausgeführt. So als ob das TStringGrid dem TBitBtn das Ereignis "zur Hälfte" wegfängt: Animation ist noch da, aber Auslösung nicht mehr.

Als funktionierenden Weg mit Auslösung von TBitBtn.OnClick habe ich gefunden, ein TPanel von gleicher Größe hinter das TStringGrid zu legen und die TBitBtn dort einzufügen:

Delphi-Quelltext
1:
2:
3:
BitBtn:= TBitBtn.Create(Self);
BitBtn.OnClick:= MeineOnClickProzedur;
Panel.InsertControl(BitBtn);

Das erfordert jedoch, bei jeder Größenordnung des TStringGrid parallel dazu auch das TPanel anzupassen. Und bei gleicher linker oberer Ecke von TStringGrid und TPanel sind deren Koordinatensysteme auch noch ein kleines Stück gegeneinander verschoben, was ich in TStringGrid.OnDrawCell korrigieren muss.

Geht im Prinzip so, aber "schön" finde ich diesen Umweg nicht. Hat jemand von Euch eine Idee, wie ich den Klick im ersten Fall vollständig zum TBitBtn durchleiten kann? Vielen Dank.

Gru Uwe


Blup - Do 29.09.22 16:11

Ich hatte einen vergleichbaren Anwendungsfall mit Checkbox.

Das Grid liegt auf einem Panel(PDetail) und die Checkbox(en) ebenfalls. Dadurch entfällt das Problem mit dem OnClick-Ereignis.
Die Checkbox(en) werden zur Laufzeit im OnShow auf das Panel erzeugt, Aber nur für die sichtbaren Zeilen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
   CheckBox := TCheckBox.Create(PDetail);
   CheckBox.Parent  := PDetail;
   CheckBox.Left    := x;
   CheckBox.Top     := y;
   CheckBox.OnClick := ChBoxGridClick;
   CheckBox.OnEnter := ChBoxGridEnter;

Im OnTopLeft-Ereignis des Grid aktualisiere auf Grundlage der angezeigten Daten den Status der Checkbox(en).
In meinem Fall ist horizontales Skrollen nicht vorgesehen und die Größe des Grids nicht veränderbar, deshalb entfällt die Neupositionierung der Checkbox(en).
Sonst müsste man dafür zusätzlichen Aufwand treiben.


Ralf Jansen - Do 29.09.22 19:07

Vielleicht einfach mal prüfen ob nicht das TStringGrid den Click wegfängt und ein eigenes Click Ereignis wirft. Möglicherweise kannst du dann das clicken einfach da verdrahten anstatt am Button um das gleiche zu erreichen.


jaenicke - Do 29.09.22 20:27


Delphi-Quelltext
1:
2:
3:
4:
BitBtn:= TBitBtn.Create(Self);
BitBtn.OnClick:= MeineOnClickProzedur;
BitBtn.ControlStyle := BitBtn.ControlStyle + [csClickEvents];
StringGrid.InsertControl(BitBtn);

Ein Blick in TControl.WMLButtonDown und TControl.WMLButtonUp zeigt, dass nur dann das OnClick ausgelöst wird.


UweK - Di 04.10.22 15:14

Danke jaenicke, der Tipp löst das Problem bequem. Gruß Uwe