Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - TSringGrid keine Scrollbar Events?
Knulli - Di 09.06.15 13:41
Titel: TSringGrid keine Scrollbar Events?
Hi Leute,
ich hab nen Programm, wo ich in 'nem Stringgrid 'ne CSV Tabelle darstellen möchte.
Problem ist das Scrollen.
Erstens will ich, dass ich beim Scrollen mit der Srcollbar den Tabelleninhalt gleich verschiebe.
Das hab ich mit goThumbTracking gemacht.
Nun ist es aber so, dass wenn ich anschließend mit dem Mausrad weiterscrollen will, springt die Anzeige wieder nach oben.
Der Focus "kommt nicht mit".
Ziel soll aber sein, dass ich mit den Scrollbalken die grobe Suche der Zeile machen will und mit dem Mausrad danach ab dieser Position weitermachen will.
Wie setze ich das Focusrect o.ä. nach dem Scrollen (Scrollbar-Gnubbel losgelassen) auf Mitte der sichtbaren Zeilen?
Knulli
SMO - Di 09.06.15 15:16
Knulli hat folgendes geschrieben : |
Nun ist es aber so, dass wenn ich anschließend mit dem Mausrad weiterscrollen will, springt die Anzeige wieder nach oben.
Der Focus "kommt nicht mit". |
Das ist normal / Standard. Was bei den Grids nicht normal ist, ist dass das Mausrad das Fokus-Rechteck bewegt, statt des Scrollbalkens.
Siehe z.B. Verhalten im Windows Explorer: markiert man eine oder mehrere Dateien und scrollt dann (per Mausrad oder per Balken), können die markierten Elemente aus der Sicht verschwinden. Drückt man dann eine Pfeiltaste, wird der Fokus bewegt und die Sicht springt zum fokussierten Element zurück. So sollte es auch sein.
Kann man auf diese Art für Grids nachbilden (Mausrad = vertikaler Scrollbalken):
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:
| var GridMouseWheelScroll: Boolean = True;
procedure TForm1.StringGrid1MouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin with Sender as TDrawGrid do if GridMouseWheelScroll then begin if TopRow < RowCount - VisibleRowCount then TopRow := TopRow + 1; Handled := True; end else Handled := False; end;
procedure TForm1.StringGrid1MouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin with Sender as TDrawGrid do if GridMouseWheelScroll then begin if TopRow > FixedRows then TopRow := TopRow - 1; Handled := True; end else Handled := False; end; |
Falls du
wirklich das fokussierte Element ändern willst, wenn gescrollt wird, könnte das so gehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| uses Math; procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject); begin with Sender as TDrawGrid do begin Row := EnsureRange(Row, TopRow, TopRow + VisibleRowCount); Col := EnsureRange(Col, LeftCol, LeftCol + VisibleColCount); end; end; |
Das fokussierte Elemente kann dann aber immer noch aus der Sicht verschwinden, wenn die Größe des Fensters / Grids verkleinert wird. Das müsstest du dann separat behandeln.
Knulli - Mi 10.06.15 08:24
Super, das hat geklappt.
War mir garnicht so aufgefallen, dass die Ursache darin liegt, dass das Mausrad eigentlich den Scrollbalken und nicht den Focus verändern soll...
Komischerweise hatte ich die beiden Wheel-Events gestern auch schon mal "am Haken", nur bleib der Debugger beim Scrollen nicht auf den Breakpoints stehen, heute gings aber. Hmmm... brauch wohl mal Urlaub.
Noch eine zweite Frage, zum Thema:
In den Wheel-Events kann ich ja auch sehr schön um zwei Zeilen incrementieren, wenn ich z.B. im Grid immer zwei Zeilen mit zusammenhängendem Inhalt habe.
Wie "verklicker" ich nun dem Grid, dass der Grid-eigene Scrollbalken das auch so macht?
Das hier (im Event TopLeftChanged) klappt leider nicht (TopRow ist ReadOnly...)
Delphi-Quelltext
1:
| if (TopRow Mod 2) <> 0 then Inc(TopRow); |
Knulli
SMO - Mi 10.06.15 09:48
TopRow ist ein Property mit Setter und kann deswegen nicht genau wie eine Variable verwendet werden. Eine Zuweisung wie "TopRow := y" wird in einen Prozeduraufruf "SetTopRow(y)" übersetzt.
So geht's:
Delphi-Quelltext
1:
| if Odd(TopRow - FixedRows) then TopRow := TopRow + 1; |
Wenn man mit Grid-Koordinaten hantiert, sollte man immer FixedRows und FixedCols abziehen, um 0-basierte Koordinaten zu bekommen. Das gilt jedenfalls wenn man gerade nur an den scrollbaren Zellen interessiert ist, nicht an den festen Zellen am linken und oberen Rand.
"Odd" prüft ob ein Wert ungerade ist, prinzipiell genau das gleiche wie "mod 2 <> 0" und "and 1 <> 0".
Knulli - Do 11.06.15 09:20
Oh Mann, ich brauch wirklich mal Urlaub...
In Deinem ersten Post hast Du ja eine Zuweisung an "TopRow" vorgemacht...
Delphi-Quelltext
1:
| if TopRow < RowCount - VisibleRowCount then TopRow := TopRow + 1; |
und ich hab auch noch aus der Eins ne Zwei gemacht und nichts gecheckt...
wie peinlich... :oops: :oops: :oops: :oops: :oops:
Wie bedankt man sich hier eigentlich?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!