TStringgrid und BEFORE und AFTER Selection

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

TStringgrid und BEFORE und AFTER Selection

Beitrag von Lorca »

Hallo zusammen,

irgendwie stimmen die Parameterwerte für AROW in beiden Methoden nicht.
Wenn ich das Ereignis "OnBeforeSelection" abfange erwarte ich die Zeilennummer welche VOR der Selektion angewählt war.
Analog dazu erwarte ich im Ereignis "OnAfterSelection" die neue Zeilennummer.
Diese Informationen schreibe ich (dank Winni :) ) in einer TMemo Komponete, um die Werte zu überprüfen


Beispiel: Die erste Zeile meiner GRID ist selektiert.
Nun wähle ich die Zeile 5 meiner StringGrid mit der Maus aus.

Im Ereignis OnBeforeSelection erwarte ich nun die 1. Hier möchte ich z.B. Vorbereitende Arbeiten erledigen. Dazu benötige ich die Zeilennummer 1
Ich erhalte jedoch die neue Zeilennummer 5

Im Ereignis OnAfterSelection möchte ich nun Abschlussarbeiten durchführen welche auf der neuen Zeilennummer 5 basieren.
Ich erhalte jedoch die Zeilennummer 1.

Zum Zeitpunkt "OnSelection" kann ich zwar auch die Abschlussarbeiten durchführen. Die vorbereitenden Arbeiten jedoch, welche die vorherige Zeilennummer bedingen lassen sich so nicht erledigen.

Übersehe ich da eine Einstellung in der Stringgrid Komponente? z.B. bei den Options?
Wo habe ich den Knoten in meinem Hirn?
Sowohl in der Lazarus 2.0.10 als auch in 2.0.12 erhalte ich diesen falschen Zeilenwert.


Kann mir jemand weiter helfen?

Viele Grüße
Lorca

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von theo »

Ist es nicht einfach genau umgekehrt?
OnAfterSelection bezieht sich auf die Zelle, welche gleich die Selection verlieren wird?

sstvmaster
Beiträge: 576
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von sstvmaster »

Hmm, jetzt wollte ich eigentlich schreiben das die Funktionsweise unterhalb der Events beschrieben ist.
Habe aber festgestellt das die Beschreibung zu den Events nur im Trunk verfügbar ist. Im 2.0.12 leider nicht.

OnAfterSelection:
Event handler signalled after a new Selection is made in the grid
——————————————————

OnAfterSelection is a TOnSelectEvent property that is the event handler signalled when the Selection for the control has been moved.

An application can implement and assign an object procedure using the event signature to perform any action needed for the notification. The arguments passed to the event handler include the column and row numbers prior to moving the Selection .
OnBeforeSelection:
Event handler signalled before changing the Selection in the grid control
——————————————————

OnBeforeSelection is a TOnSelectEvent property with the event handler signalled prior to changing the Selection for the grid control. OnBeforeSelection can be used to perform actions needed before the Selection is moved and an Editor is displayed for the newly selected cell.

OnBeforeSelection is triggered (when assigned) from the MoveExtend method, and occurs when a new column or row is selected in the grid using keyboard navigation, using the mouse, or by assigning values to the Col or Row properties. It is also triggered when an explicit value is assigned to the Selection property.

Use OnAfterSelection to performs actions needed after the Selection has been changed and the Editor has been displayed.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von wp_xyz »

Lorca hat geschrieben:
Fr 25. Jun 2021, 11:55
Wenn ich das Ereignis "OnBeforeSelection" abfange erwarte ich die Zeilennummer welche VOR der Selektion angewählt war.
Analog dazu erwarte ich im Ereignis "OnAfterSelection" die neue Zeilennummer.
Die Logik ist anders. Du kannst mit StringGrid.Row und StringGrid.Col immer abfragen, welche Zelle aktuell selektiert ist. Darüber hinaus sagt dir der ARow/ACol Parameter von OnBeforeSelection, welche Zelle ausgewählt sein wird, wenn die Aktion vorbei ist, und OnAfterSelection nennt die Zelle, die vorher ausgewählt war.

sstvmaster
Beiträge: 576
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von sstvmaster »

Genau verdrehte Logik, Before ist After und After ist Before.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von wp_xyz »

sstvmaster hat geschrieben:
Fr 25. Jun 2021, 12:46
Genau verdrehte Logik, Before ist After und After ist Before.
Nö. Die einzige logische Möglichkeit, wenn man voraussetzt, dass StringGrid.Row und StringGrid.Col immer auf die aktuelle Zelle verweisen. Andersherum wären die Parameter ACol, ARow nutzlos. So kann man z.B. in OnBeforeSelection prüfen, ob die neue Zelle überhaupt ausgewählt werden darf. Der folgende Code macht z.B. die Zeile ARow=2 nicht mehr anklickbar:

Code: Alles auswählen

procedure TForm1.StringGrid1BeforeSelection(Sender: TObject; aCol, aRow: Integer);
begin
  if ARow = 2 then Abort;
end;

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von Lorca »

Hallo zusammen,

zunächst herzlichen Dank für alle euren netten Antworten :)

Und ja, ihr habt alle recht (genau wie ich auch 8) ). Dennoch war es keine Frage von mir WANN die Ereignisse auftreten. Sondern vielmehr eine Feststellung das dies so ist und ob ich da etwas in den Einstellungen falsch gemacht habe.
Probiert es selber aus. Eine Stringgrid auf die Form und ein TMemo zur Dokumentation.

Die Events werden auch zum korrekten Zeitpunkt abgesetzt.
Nur.... die an das Event übergebene ARow hat einen falschen Wert.

Die Events werden von der Methode: TCustomGrid.MoveExtend(Relative: Boolean; DCol, DRow: Integer; ForceFullyVisible: Boolean): Boolean;
abgesetzt.
Hier wird nun die Methode BeforeMoveSelection(DCol,DRow); abgesetzt. Und anstatt der Zeile vor der Selektion wird hier die Zeile nach der Selektion übergeben.
Der Zeitpunkt des Aufrufes ist völlig korrekt.

Direkt danach erfolgen die Feldzuweisungen:
OldRange := FRange;
PrevRow := FRow; { in FRow steht jetzt der Wert der Zeile vor der Selektion }
PrevCol := FCol;

und ganz am Ende der Methode TCustomGrid.MoveExtend wird ebenfalls völlig korrekt die Methode
AfterMoveSelection(PrevCol, PrevRow); aufgerufen.
Und wie man auch ganz deutlich lesen kann werden hier ebenfalls die falschen Werte übergeben. Denn preview bedeutet vorher


Nun war meine Befürchtung, das eine falsche Einstellung meiner STRINGGRID zu den falschen Werten in den übergebenen Parametern
führt. Aber egal was ich tue, Es bleibt immer dabei. So könnte es sein, das durch eine entsprechende Einstellung nicht wie gesehen
die Methode TCustomGrid.MoveExtend ausgeführt wird sondern vllt. eine andere Methode.

Schlimm ist nur, das alle anderen Grids, die auf die TCustomgrid Referenzieren das gleiche Problem habe, (Habe ich ausprobiert)


Noch einmal ganz lieben Dank an euch alle
Gruß
Lorca



PROCEDURE Tform1.Stringgrid1beforeselection( Sender : Tobject; Acol, Arow : Integer);
BEGIN
memo1.Lines.Clear;
memo1.Lines.ADD(' Zeile VOR der Selektion: ' + IntToStr( ARow ) );
End;


PROCEDURE Tform1.Stringgrid1afterselection( Sender : Tobject; Acol, Arow : Integer) ;
BEGIN
memo1.Lines.ADD(' Zeile NACH der Selektion: ' + IntToStr( ARow ) );
End;


PROCEDURE Tform1.Stringgrid1selection( Sender : Tobject; Acol, Arow : Integer) ;
BEGIN
memo1.Lines.ADD(' Zeile WÄHREND der Selektion: ' + IntToStr( ARow ) );
End;

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von wp_xyz »

Ich finde hier nichts falsches:

Code: Alles auswählen

function TCustomGrid.MoveExtend(Relative: Boolean; DCol, DRow: Integer;
  ForceFullyVisible: Boolean): Boolean;
var
  OldRange: TRect;
  prevCol, prevRow: Integer;
begin
  // Hier werden in DCol/DRow die Indizes der neu zu selektierenden Zelle berechnet.
  Result:=TryMoveSelection(Relative,DCol,DRow);
  ...
  // Hier wird das OnBeforeSelection Event erzeugt. Die übergebenen Koordinaten sind die der neu zu selektierenden Zelle
  // (Die bisher selektierte Zelle ist uninteressant, denn diese kennt man über StringGrid.Col/StringGrid.Row).
  BeforeMoveSelection(DCol,DRow);

  // Da sich nach der Selektieren die Koordinaten der AKTUELL selektierten Zelle ändern werden, werden 
  //diese in PrevRow/PrevCol gespeichert.
  PrevRow := FRow;
  PrevCol := FCol;
  ...
  // Neue Zelle sektieren
  if not ScrollToCell(DCol, DRow, ForceFullyVisible) then
    InvalidateMovement(DCol, DRow, OldRange);
  // Die Koordinaten der selektierten Zelle aktualisieren
  FCol := DCol;
  FRow := DRow;

  MoveSelection;
  ...
  
  // Nun wird das Event OnAfterSelection erzeugt. Es erhält die vorher gespeicherten Koordinaten der alten 
  // selektierten Zelle
  AfterMoveSelection(PrevCol,PrevRow);
end;                 
Siehe auch beigefügtes Projekt. Die angezeigten Koordinaten sind völlig logisch und richtig.
Dateianhänge
BeforeSelection_AfterSelection.zip
(2.09 KiB) 59-mal heruntergeladen

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von Lorca »

Hallo wp_xyz

Wenn die Parameter Werte von DCol und DRow uninteressant sind, dann erkläre mir bitte warum diese überhaupt übergeben werden?
Und weiter würde ich dann gerne wissen warum im Methodenaufruf: AfterMoveSelection(PrevCol,PrevRow);
die Parameter PrevCol und PrevRow übergeben werden. Ebenfalls wäre es interessant zu wissen, warum dann hier die zuvor ausgewählte Zeile übergeben wird.
Niemand , übergibt sinnlose Parameter.


Also: Die Selektion steht auf Zeile 2 der GRID.
Nun wechsel ich auf Zeile 5.
Ich erwarte nun im Ereignis: OnBefore das mir die Zeile übergeben wird au welche die Selektion vorher gestanden hat. (Also Zeile 2)
Im Gegensatz dazu erwarte ich im Ereignis OnAfter nun die Zeile die aktuelle selektiert ist. (Also Zeile 5)

Wenn dem so sein sollte, wie du es sagst das die Row immer über TSTRINGGRID.ROW abgefragt werden kann, ist die Übergabe dieser Parameter völliger Unsinn.

Wie gesagt ich bin noch nicht lang genug im Lazarus unterwegs. Und in den Sprachen, in denen ich im Berufsleben entwickelt habe, war es genau so wie ich es beschrieben habe.

Ich tippe hier eher darauf, das nicht die Methode: TCustomGrid.MoveExtend(Relative: Boolean; DCol, DRow: Integer; ForceFullyVisible: Boolean): Boolean; aufgerufen werden sollte sondern ein andere Methode. Und dies könnte z.B. an anderen Einstellungen der GRID liegen.
Und genau deshalb habe ich hier auch nachgefragt.
Es liegt mir fern, den Entwicklern dieser Komponenten bzw. Lazarus, mit meinem Halbwissen über Lazarus einen Fehler zu unterstellen.
Aber es ist wie es ist.


Viele Grüße
Lorca

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von h-elsner »

Wenn ich es richtig verstanden habe ist es so:

BeforeSelection:
Zeile und Spalte der Zelle, die aktuell (before) selektiert ist, hast du doch in TStringGrid.Row und TStringGrid.Col. Macht also keinen Sinn dies zu übergeben. Aber es macht Sinn genau die Zeile/Spalte zu übergeben, die als nächstes selektiert werden soll (z.B. um irgendetwas zu überprüfen). Da hat der Programmierer schlau gedacht.

After Selection:
Genauso. Zeile und Spalte der Zelle, die aktuell (after) selektiert ist, hast du in TStringGrid.Row und TStringGrid.Col. Macht also auch keinen Sinn dies zu übergeben. Aber es macht Sinn hier wieder die Zeile/Spalte zu übergeben, die als vorher selektiert war (für was auch immer).

Namen sind Schall und Rauch, als Programmierer muss man um die Ecke denken und bestimmte Dinge einfach voraussehen. Dies ist hier aus meiner Sicht sehr gut gelungen. Man muss aber erst mal darufkommen!

Gruß HE

wp_xyz
Beiträge: 4885
Registriert: Fr 8. Apr 2011, 09:01

Re: TStringgrid und BEFORE und AFTER Selection

Beitrag von wp_xyz »

Lorca, lass mal deine Vorstellung beiseite und lies das was h-elsner geschrieben hat, er hat das sehr schön zusammengefasst.

Antworten