Difference between revisions of "Grids Reference Page/de"

From Free Pascal wiki
Jump to navigationJump to search
m
m (Fixed syntax highlighting)
(22 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 
{{Grids Reference Page}}
 
{{Grids Reference Page}}
 
+
<br>
 +
Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].<br>
 +
<br>
 
== Die Zielsetzung ==
 
== Die Zielsetzung ==
 
Dieser Text will versuchen, dem Benutzer einige Aspekte der Grid-Komponenten in Lazarus zu zeigen. Es ist auch vorgesehen, als ein Handbuch für Benutzer zu dienen, die noch nie zuvor Grids benutzt haben (während erfahrene Benutzer im Allgemeinen nur eine Referenz benötigen für neue Funktionalitäten).
 
Dieser Text will versuchen, dem Benutzer einige Aspekte der Grid-Komponenten in Lazarus zu zeigen. Es ist auch vorgesehen, als ein Handbuch für Benutzer zu dienen, die noch nie zuvor Grids benutzt haben (während erfahrene Benutzer im Allgemeinen nur eine Referenz benötigen für neue Funktionalitäten).
Line 10: Line 12:
  
 
== Überblick ==
 
== Überblick ==
Ein Grid ist eine Komponente, die a mean zur Anzeige von Daten in einem tabellarischen Format bietet. Die offensichtlichste Charakteristik von Grids ist, daß sie aus Zellen bestehen, Zeilen und Spalten bildend.
+
Ein Grid ist eine Komponente, die hauptsächlich zur Anzeige von Daten in einem tabellarischen Format dient. Die offensichtlichste Charakteristik von Grids ist, dass sie aus Zellen bestehen, Zeilen und Spalten bildend.
  
 
Der Informationstyp, der in einem Grid angezeigt werden kann, ist sehr weitläufig, hauptsächlich abhängig von dem, was der Benutzer anzeigen möchte. Gewöhnlich wird diese Information in Text, Farben, Bilder oder eine Kombination daraus übersetzt.  
 
Der Informationstyp, der in einem Grid angezeigt werden kann, ist sehr weitläufig, hauptsächlich abhängig von dem, was der Benutzer anzeigen möchte. Gewöhnlich wird diese Information in Text, Farben, Bilder oder eine Kombination daraus übersetzt.  
  
In Anbetracht der großen Vielfalt von Informationen, die representiert werden können, existiert eine Reihe von Grids, deren Zweck darin besteht, den Benutzer zu unterstützen, eine spezifische Art von Informationen zu zeigen.
+
In Anbetracht der großen Vielfalt von Informationen, die repräsentiert werden können, existiert eine Reihe von Grids, deren Zweck darin besteht, den Benutzer zu unterstützen, eine spezifische Art von Informationen zu zeigen.
 +
 
 
== Vererbungsbaum ==
 
== Vererbungsbaum ==
  
Line 36: Line 39:
  
 
== Ein Anfangsbeispiel ==
 
== Ein Anfangsbeispiel ==
As one of the objectives of this is to be nice with people with little or no previous lazarus knowledge lets do a quick starting example of grids in action. Why not, lets make a traditional "hello world" Beispiel unter Verwendung der TStringGrid Komponente.
+
Eine Zielsetzung dieses Textes soll die Benutzerfreundlichkeit sein, insbesondere für diejenigen, die keine oder wenig Erfahrung mit Lazarus haben. Fangen wir also mit einem einfachen Beispiel an, in dem wir die Grids-Komponente in Aktion sehen und beginnen mit dem traditionellen "Hallo Welt" Beispiel unter Verwendung der TStringGrid Komponente.
 
#Erstellen sie eine neue Anwendung.  
 
#Erstellen sie eine neue Anwendung.  
 
#*Im Hauptmenü wählen sie: Projekt -> Neues Projekt
 
#*Im Hauptmenü wählen sie: Projekt -> Neues Projekt
Line 53: Line 56:
 
#Starten sie das Programm durch klicken auf das Start Icon [].
 
#Starten sie das Programm durch klicken auf das Start Icon [].
 
#*Durch Drücken von Button1, sollte der hello world Text in der Zelle Spalte 1, Zeile 1 erscheinen.
 
#*Durch Drücken von Button1, sollte der hello world Text in der Zelle Spalte 1, Zeile 1 erscheinen.
 +
 
== Unterschiede zwischen Lazarus und Delphi Grids ==
 
== Unterschiede zwischen Lazarus und Delphi Grids ==
Die aktuellen Grid-Komponenten zeigen verschiedene Unterschiede hinsichtlich der Delphi Grids. Das ist hauptsächlich so, weil die Lazarus Grids von Beginn an erstellt wurden ohne in erster Linie zu versuchen, sie vollständig kompatibel zu machen.  
+
Die momentanen Grid-Komponenten haben mehrere Unterschiede im Vergleich zu den Delphi Grid-Komponenten. Dies kommt vor allem daher, dass die Lazarus Grid-Komponenten komplett neu geschrieben wurden und dabei nicht zwingend auf die Kompatibilität geachtet wurde.
 +
 
 +
Die Kompatibiliät wurde erst zu einem späteren Zeitpunkt zu einem Ziel. Die Grid-Komponenten passten sich immer mehr dem Interface der Delphi Grid-Komponenten an, aber dabei wurde nicht jede einzelne Methode und jede Eigenschaft 1:1 übernommen.
 +
 
 +
Weil die Grid-Komponenten intern recht unterschiedlich sind, gibt es Dinge die nicht möglich sind oder anders als bei einer Delphi Grid-Komponente funktionieren.
 +
Im Laufe der Entwicklung der Grid-Komponenten, wurde die Kompatibilität jedoch immer besser was durchaus auch wünschenswert ist.
  
In einem späteren Stadium wurde die Kompatibilität mit Delphi Grids zu einem gewünschten Ziel und die Grids begannen der Delphi Grid-Schnittstelle enger zu folgen, aber ohne zwingende Bemühungen, jede einzelne Eigenschaft oder Methode passend zu ihrem Delphi Gegenstück zu machen.
 
Auch weil die Grid Interna sehr verschieden sind, sind manche Dinge nicht möglich oder müssen auf eine andere Weise erledigt werden in den Lazarus Grids.
 
As the grids were evolved, greater compatibility becomes and is a desired.
 
 
=== Unterschiede ===
 
=== Unterschiede ===
 
An dieser Stelle werden die bekannten Unterschiede aufgeführt ohne spezielle Reihenfolge.
 
An dieser Stelle werden die bekannten Unterschiede aufgeführt ohne spezielle Reihenfolge.
*Cell Editors
+
*Zelleneditoren
*Designtime Behaviour
+
*Entwicklungszeitverhalten
 +
*Es gibt einige Unterschiede beim Zeichnen der Zellen, siehe Abschnitt [[#Customizing grids|Customizing grids]]
 +
 
 
=== Neue Funktionsweise ===
 
=== Neue Funktionsweise ===
 
*Spalten
 
*Spalten
Line 80: Line 88:
  
 
== Grids Referenz ==
 
== Grids Referenz ==
 +
 
=== Information ===
 
=== Information ===
 
Der Ausgangspunkt für eine Referenz über TCustomGrid, TDrawGrid, TCustomDrawGrid, TCustomStringGrid und TStringGrid ist die [http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html Unit grids.pas Referenz].  
 
Der Ausgangspunkt für eine Referenz über TCustomGrid, TDrawGrid, TCustomDrawGrid, TCustomStringGrid und TStringGrid ist die [http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html Unit grids.pas Referenz].  
Line 86: Line 95:
 
[http://lazarus-ccr.sourceforge.net/docs/lcl/dbgrids/index.html  Unit dbgrids.pas Referenz].
 
[http://lazarus-ccr.sourceforge.net/docs/lcl/dbgrids/index.html  Unit dbgrids.pas Referenz].
  
Gegenwärtig enthalten diese Links noch nicht viel Inhalt, teilweise wegen des Fehlens eines Werkzeugs, das eine einfache Wartung ihres Inhalts erlaubt. Aber ein solches Werkzeug is under construction and eventually the gaps will be filled.
+
Gegenwärtig enthalten diese Links noch nicht viel Inhalt, teilweise wegen des Fehlens eines Werkzeugs, das eine einfache Wartung ihres Inhalts erlaubt. Aber ein solches Werkzeug ist im Aufbau befindlich und irgendwann werden die Lücken gefüllt werden.
  
 
Im Allgemeinen, jede Delphi Referenz über Grids sollte helfen, die Lazarus Grids zu verwenden (don't forget that there are several differences between Delphi and Lazarus grids being documented), with this in mind and as a temporal place for reference information, wird dieser Ort genutzt, um Dinge zu dokumentieren, die nicht wie in Delphi funktionieren oder die eine neue Funktionalität darstellen.
 
Im Allgemeinen, jede Delphi Referenz über Grids sollte helfen, die Lazarus Grids zu verwenden (don't forget that there are several differences between Delphi and Lazarus grids being documented), with this in mind and as a temporal place for reference information, wird dieser Ort genutzt, um Dinge zu dokumentieren, die nicht wie in Delphi funktionieren oder die eine neue Funktionalität darstellen.
 +
 +
[TODO: the rest of this section will dissapear, it's content will be moved to [http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html unit grids.pas reference]
 +
 
=== TCustomGrid ===
 
=== TCustomGrid ===
Siehe die vollständige [[doc:lcl/grids/tcustomgrid.html|TCustomGrid Referenz]].
+
See the full [[doc:lcl/grids/tcustomgrid.html|TCustomGrid Reference]]
==== Eigenschaft OnBeforeSelection: TOnSelectEvent ====
+
==== property OnBeforeSelection: TOnSelectEvent ====
==== Eigenschaft OnCompareCells: TOnCompareCells ====
+
==== property OnCompareCells: TOnCompareCells ====
==== Eigenschaft OnPrepareCanvas: TOnPrepareCanvasEvent ====
+
==== property OnPrepareCanvas: TOnPrepareCanvasEvent ====
==== Eigenschaft OnDrawCell: TOnDrawCell ====
+
==== property OnDrawCell: TOnDrawCell ====
==== Eigenschaft OnEditButtonClick: TNotifyEvent ====
+
==== property OnEditButtonClick: TNotifyEvent ====
==== Eigenschaft OnSelection: TOnSelectEvent ====
+
==== property OnSelection: TOnSelectEvent ====
==== Eigenschaft OnSelectEditor: TSelectEditorEvent ====
+
==== property OnSelectEditor: TSelectEditorEvent ====
==== Eigenschaft OnTopLeftChanged: TNotifyEvent ====
+
==== property OnTopLeftChanged: TNotifyEvent ====
==== Prozedur AutoAdjustColumns; ====
+
==== procedure AutoAdjustColumns; ====
==== Prozedur BeginUpdate; ====
+
==== procedure BeginUpdate; ====
==== Prozedur Clear; ====
+
==== procedure Clear; ====
==== Prozedur DeleteColRow(IsColumn: Boolean; index: Integer); ====
+
==== procedure DeleteColRow(IsColumn: Boolean; index: Integer); ====
==== Funktion EditorByStyle(Style: TColumnButtonStyle): TWinControl; ====
+
==== function EditorByStyle(Style: TColumnButtonStyle): TWinControl; ====
==== Prozedur EndUpdate(UO: TUpdateOption); overload; ====
+
==== procedure EndUpdate(UO: TUpdateOption); overload; ====
==== Prozedur EndUpdate(FullUpdate: Boolean); overload; ====
+
==== procedure EndUpdate(FullUpdate: Boolean); overload; ====
==== Prozedur EndUpdate; overload; ====
+
==== procedure EndUpdate; overload; ====
==== Prozedur ExchangeColRow(IsColumn: Boolean; index, WithIndex:Integer); ====
+
==== procedure ExchangeColRow(IsColumn: Boolean; index, WithIndex:Integer); ====
==== Funktion IscellSelected(aCol,aRow: Integer): Boolean; ====
+
==== function  IscellSelected(aCol,aRow: Integer): Boolean; ====
==== Funktion IscellVisible(aCol, aRow: Integer): Boolean; ====
+
==== function  IscellVisible(aCol, aRow: Integer): Boolean; ====
==== Prozedur LoadFromFile(FileName: string); ====
+
==== procedure LoadFromFile(FileName: string); ====
==== Funktion MouseToCell(Mouse: TPoint): TPoint; overload; ====
+
==== function  MouseToCell(Mouse: TPoint): TPoint; overload; ====
==== Funktion MouseToLogcell(Mouse: TPoint): TPoint; ====
+
==== function  MouseToLogcell(Mouse: TPoint): TPoint; ====
==== Funktion MouseToGridZone(X,Y: Integer): TGridZone; ====
+
==== function  MouseToGridZone(X,Y: Integer): TGridZone; ====
==== Funktion CellToGridZone(aCol,aRow: Integer): TGridZone; ====
+
==== function  CellToGridZone(aCol,aRow: Integer): TGridZone; ====
==== Prozedur MoveColRow(IsColumn: Boolean; FromIndex, ToIndex: Integer); ====
+
==== procedure MoveColRow(IsColumn: Boolean; FromIndex, ToIndex: Integer); ====
==== Prozedur SaveToFile(FileName: string); ====
+
==== procedure SaveToFile(FileName: string); ====
==== Prozedur SortColRow(IsColumn: Boolean; index:Integer); overload; ====
+
==== procedure SortColRow(IsColumn: Boolean; index:Integer); overload; ====
==== Prozedur SortColRow(IsColumn: Boolean; index,FromIndex,ToIndex: Integer); overload; ====
+
==== procedure SortColRow(IsColumn: Boolean; index,FromIndex,ToIndex: Integer); overload; ====
 +
 
 
=== TCustomStringGrid ===
 
=== TCustomStringGrid ===
TCustomStringGrid dient als Basis für TStringGrid. Es kann verwendet werden für von TStringGrid abgeleitete Komponenten, welche 'published' Eigenschaften verbergen wollen. Siehe [[new intermediate grids]] für mehr Informationen.
+
TCustomStringGrid dient als Basis für TStringGrid. It can be used for derived TStringGrid components that want to hide published properties. See [[new intermediate grids]] for more information.
 +
 
 +
These properties or methods are public and are also available to TStringGrid.
 +
 
 +
See the full [http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tcustomstringgrid.html TCustomStringGrid Reference]
  
Diese Eigenschaften bzw. Methoden sind public und auch bei TStringGrid verfügbar.
+
==== procedure AutoSizeColumn(aCol: Integer); ====
 +
This procedure sets the column width to the size of the widest text it finds in all rows for the column aCol. Tip: see the goDblClickAutoSize option to allow columns to be automatically resized when doubleClicking the column border.
  
Siehe die vollständige [http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tcustomstringgrid.html TCustomStringGrid Referenz].
+
==== procedure AutoSizeColumns; ====
==== Prozedur AutoSizeColumn(aCol: Integer); ====
+
Automatically resizes all columns by adjusting them to fit in the longest text in each column. This is a quick method of applying AutoSizeColumn() for every column in the grid.
Diese Prozedur setzt die Spaltenbreite auf die Größe des breitesten Texts, den sie in allen Zeilen finden kann für die Spalte aCol. Tipp: siehe die goDblClickAutoSize Option, um den Spalten die automatische Anpassung zu erlauben, wenn doppelt auf den Spaltenrand geklickt wird.
 
  
==== Prozedur AutoSizeColumns; ====
+
==== procedure Clean; overload; ====
Passt automatisch alle Spalten in der Größe an, damit der längste Text in jeder Spalte passend angezeigt wird. Dies ist eine schnelle Methode of applying AutoSizeColumn() für jede Spalte im Grid.
 
==== Prozedur Clean; overload; ====
 
 
Cleans all cells in the grid, fixed or not.
 
Cleans all cells in the grid, fixed or not.
==== Prozedur Clean(CleanOptions: TCleanOptions); overload; ====
+
 
Cleans all cells in the grid subject to the given CleanOptions. Siehe [[TCleanOptions]] für mehr Informationen. Einige Beispiele:
+
==== procedure Clean(CleanOptions: TCleanOptions); overload; ====
*Clean all cells: grid.Clean([]); (das selbe wie grid.clean)
+
Cleans all cells in the grid subject to the given CleanOptions. see [[TCleanOptions]] for more information. Some examples:
 +
*Clean all cells: grid.Clean([]); (the same as grid.clean)
 
*Clean all non fixed cells: grid.Clean([gzNormal]);
 
*Clean all non fixed cells: grid.Clean([gzNormal]);
 
*Clean all cells but don't touch grid column headers: Grid.Clean[gzNormal, gzFixedRows]);
 
*Clean all cells but don't touch grid column headers: Grid.Clean[gzNormal, gzFixedRows]);
==== Prozedur Clean(StartCol,StartRow,EndCol,EndRow: integer; CleanOptions:TCleanOptions); overload; ====
+
 
macht das selbe wie Clean(CleanOptions:TCleanOptions) but restricted to the given StartCol,StartRow,EndCol and EndRow. Beispiele:
+
==== procedure Clean(StartCol,StartRow,EndCol,EndRow: integer; CleanOptions:TCleanOptions); overload; ====
 +
does the same as Clean(CleanOptions:TCleanOptions) but restricted to the given StartCol,StartRow,EndCol and EndRow. Examples:
 
*Clean column index 4 to 6 but don't touch grid column headers: many variations, Grid.Clean(4,Grid.FixedRows,6,Grid.RowCount-1,[]); Grid.Clean(4,0,6,Grid,RowCount-1, [gzNormal]); etc.
 
*Clean column index 4 to 6 but don't touch grid column headers: many variations, Grid.Clean(4,Grid.FixedRows,6,Grid.RowCount-1,[]); Grid.Clean(4,0,6,Grid,RowCount-1, [gzNormal]); etc.
==== Prozedur Clean(aRect: TRect; CleanOptions: TCleanOptions); overload; ====
+
 
 +
==== procedure Clean(aRect: TRect; CleanOptions: TCleanOptions); overload; ====
 
The same as Clean(StartCol,StartRow,EndCol,EndRow, CleanOptions), just taking a TRect instead of individual cell coordinates. Useful to clean the selection: grid.Clean(Grid.Selection,[]);
 
The same as Clean(StartCol,StartRow,EndCol,EndRow, CleanOptions), just taking a TRect instead of individual cell coordinates. Useful to clean the selection: grid.Clean(Grid.Selection,[]);
==== Eigenschaft Cols[index: Integer]: TStrings read GetCols write SetCols; ====
+
 
Get/set a list of strings from/to the given grid's column index beginnend mit Spaltenindex 0 bis RowCount-1.  
+
==== property Cols[index: Integer]: TStrings read GetCols write SetCols; ====
 +
Get/set a list of strings from/to the given grid's column index starting from row index 0 to RowCount-1.  
 +
 
 
===== Beispiele =====
 
===== Beispiele =====
*Set Beispiel: Füllt die dritte Spalte im Grid mit dem Inhalt einer ListBox:
+
*Set Example: Set the content of the third column in the grid from a ListBox:
 
  Grid.Cols[2] := ListBox1.Items;
 
  Grid.Cols[2] := ListBox1.Items;
*Get Beispiel: Füllt eine Listbox mit dem Inhalt der Spalte mit dem Index 4:
+
*Get Example: Set the content of a Listbox from the grid's column index 4:
 
  procedure TForm1.FillListBox1;
 
  procedure TForm1.FillListBox1;
 
  var  
 
  var  
Line 157: Line 177:
 
     StrTempList.Free;
 
     StrTempList.Free;
 
   end;
 
   end;
  end;
+
  end;  
  
 
===== Anmerkungen =====
 
===== Anmerkungen =====
Diese Eigenschaft funktioniert beim Holen der Daten aus dem Grid in Lazarus auf eine andere Weise als in Delphi.  
+
This property works in a different way in Lazarus than in Delphi when getting the data from the grid.  
In Lazarus wird ein temporäres TStringList Objekt erzeugt, um den Spalteninhalt zu holen. Es liegt in der Verantwortung des Benutzers, dieses Objekt nach der Verwendung freizugeben.  
+
In Lazarus a temporary TStringList object is created for retrieving the column content. It is the responsibility of the user to free this object after use.  
 +
 
 +
This means also that changes in the returned list will not affect the grids content or layout.  
  
Das bedeutet auch, dass die Änderungen in der zurückgegebenen Liste weder den Inhalt noch das Aussehen des Grids beeinflussen werden.
+
See the Get Example.
  
Siehe das Get Beispiel.
+
==== property Rows[index: Integer]: TStrings read GetRows write SetRows; ====
 +
Get/set a list of strings from/to the given grid's row index starting from column index 0 to column ColCount-1.  
  
==== Eigenschaft Rows[index: Integer]: TStrings read GetRows write SetRows; ====
 
Get/set a list of strings from/to the given grid's row index beginnend mit Spaltenindex 0 bis Spalte ColCount-1.
 
 
===== Anmerkungen =====
 
===== Anmerkungen =====
Diese Eigenschaft funktioniert beim Holen der Daten aus dem Grid in Lazarus auf eine andere Weise als in Delphi.  
+
This property works in a different way in Lazarus than in Delphi when getting the data from the grid.  
In Lazarus wird ein temporäres TStringList Objekt erzeugt, um den Zeileninhalt zu holen. Es ist in der Verantwortung des Benutzers, dieses Objekt nach der Verwendung wieder freizugeben.  
+
In Lazarus a temporary TStringList object is created for retrieving the row content. It is the responsibility of the user to free this object after use.  
  
 
This means also that changes in the returned list will not affect the grids content or layout.  
 
This means also that changes in the returned list will not affect the grids content or layout.  
  
 
===== Beispiele =====
 
===== Beispiele =====
*Set Beispiel: Füllt die dritte Zeile im Grid (Zählung beginnt bei 0) mit dem Inhalt aus einer ListBox:
+
*Set Example: Set the content of the third row in the grid from a ListBox:
 
  Grid.Rows[2] := ListBox1.Items;
 
  Grid.Rows[2] := ListBox1.Items;
*Get Beispiel: Füllt eine Listbox mit dem Inhalt der Zeile mit dem Index 4:
+
*Get Example: Set the content of a Listbox from the grid's row index 4:
 
  procedure TForm1.FillListBox1;
 
  procedure TForm1.FillListBox1;
 
  var  
 
  var  
Line 189: Line 210:
 
   end;
 
   end;
 
  end;   
 
  end;   
*Nicht funktionierendes Beispiel und Berichtigung: Retrieved string list is read only
+
*Not Working Example and Fix: Retrieved string list is read only
  // dies wird nicht funktionieren und einen Speicherüberlauf verursachen
+
  // this will not work and will cause memory leak
  // weil die zurückgegebene StringList nicht freigegeben wird
+
  // because returned StringList is not being freed
 
  Grid.Rows[1].CommaText := '1,2,3,4,5';
 
  Grid.Rows[1].CommaText := '1,2,3,4,5';
 
  Grid.Rows[2].Text := 'a'+#13#10+'s'+#13#10+'d'+#13#10+'f'+#13#10+'g';  
 
  Grid.Rows[2].Text := 'a'+#13#10+'s'+#13#10+'d'+#13#10+'f'+#13#10+'g';  
 
   
 
   
  // berichtigen des ersten Falls
+
  // fixing the first case
 
  Lst:=TStringList.Create;
 
  Lst:=TStringList.Create;
 
  Lst.CommaText := '1,2,3,4,5';
 
  Lst.CommaText := '1,2,3,4,5';
Line 201: Line 222:
 
  Lst.Free;
 
  Lst.Free;
  
==== Eigenschaft UseXORFeatures; ====
+
==== property UseXORFeatures; ====
Boolean Eigenschaft, Vorgabewert: false;
+
Boolesche Eigenschaft, Vorgabewert: false;
  
Diese Eigenschaft steuert wie the dotted focus rectangle appears in the grid. When true, the rectangle is painted using the XOR raster operation. This allow us to see the focus rectangle no matter what the cells' background color is. When false, the user can control the color of the dotted focus rectangle using the [[FocusColor property]]
+
This property controls how the dotted focus rectangle appears in the grid. When true, the rectangle is painted using the XOR raster operation. This allow us to see the focus rectangle no matter what the cells' background color is. When false, the user can control the color of the dotted focus rectangle using the [[FocusColor property]]
  
 
It also controls the look of the column/row resizing. When true, a line shows visually the size that the the column or row will have if the user ends the operation. When false, the column or row resizing takes effect just as the user drags the mouse.
 
It also controls the look of the column/row resizing. When true, a line shows visually the size that the the column or row will have if the user ends the operation. When false, the column or row resizing takes effect just as the user drags the mouse.
  
 
== Grids Howto ==
 
== Grids Howto ==
 +
=== Customizing grids ===
 +
Grid are components derived from TCustomControl class, and don't have a native widget associated to them which means that grids are not restricted by the look of current interface theme. This can be equally considered an advantage but also a disadvantage because usually programmers want to create a uniform-look application. The good news is that Lazarus grids are flexible enough to get something from both worlds, programmers can easily make grids to look like other native controls or they can customize the grid to the finest detail so they can obtain almost the same look in any platform or widget interface, that is, with the exception of scrollbars because their look is still determined by current theme.
  
=== Look and Feel ===
+
=== Eigenschaften und Ereignisse für customizing grids ===
 
+
Some properties can affect the way the grid looks by acting when the cell is about to be painted in PrepareCanvas/OnPrepareCanvas by changing default canvas properties like brush color or font. Following is a list of such properties:
(this is a collection of notes to write this section, is not the final format)
+
*'''AlternateColor.''' With this the user can change the background color appears on alternated rows. This is to allow easy reading off of grid rows data.
 +
*'''Color.''' This sets the primary color used to draw non fixed cells background.
 +
*'''FixedColor.''' This is the color used to draw fixed cells background.
 +
*'''Flat.''' this eliminates the 3d look of fixed cells.<br>
 +
*'''TitleFont.''' Font used to draw the text in fixed cells.<br>
 +
*'''TitleStyle.''' This property changes the 3D look of fixed cells, there are 3 settings:
 +
**''tsLazarus.'' This is the default look
 +
**''tsNative.'' This tries to set a look that is in concordance with current widgetset theme.
 +
**''tsStandard.'' This style is a more contrasted look, like delphi grids.
 +
*'''AltColorStartNormal.''' boolean, if true alternate color is always in the second row after fixed rows, the first row after fixed rows will be always color, if false default color is set to the first row as if there were no fixed rows.
 +
*'''BorderColor.''' This sets the grid's border color used when Flat:=True and BorderStyle:=bsSingle;
 +
*'''EditorBorderStyle.''' If set to bsNone under windows the cell editors will not have the border, like in delphi, set to bsSingle by default because the border can be theme specific in some widgetsets and to allow a uniform look.<br>
 +
*'''FocusColor.''' The color used to draw the current focused cell if UseXORFeatures is not set, by default this is clRed.
 +
*'''FocusRectVisible.''' turns on/off the drawing of focused cell.
 +
*'''GridLineColor.''' color of grid lines in non fixed area.
 +
*'''GridLineStyle.''' Pen style used to draw lines in non fixed area, possible choices are: ''psSolid'', ''psDash'', ''psDot'', ''psDashDot'', ''psDashDotDot'', ''psinsideFrame'', ''psPattern'',''psClear''. default is ''psSolid''.
 +
*'''SelectedColor.''' Color used to draw cell background on selected cells.
 +
*'''UseXORFeatures.''' If set, focus rect is drawn using XOR mode so it should make visible the focus rect in combination with any cell color ackground. It also affects the moving columns look.
 +
*'''DefaultDrawing.''' boolean. Normally the grids prepare the grid canvas using some properties according to the kind of cell is being painted. If user write an OnDrawCell event handler, DefaultDrawing if set also paints the cell background, if user is drawing fully the cell is better turn off this property so painting is not duplicated. In a StringGrid if DefaultDrawing is set it draws the text in each cell.
 +
*'''AutoAdvance.''' where the cell cursor will go when pressing enter or tab/shift tab, or after editing.
 +
*'''ExtendedColSizing.''' If true user can resize columns not just at the headers but along the columns height.
 +
Other properties that also affect the grids look.
  
==== Customizing grids look ====
+
'''Options'''. Options property is a set with some elements to enable diverse functionality but some are related directly with grid's look. This options can be set at designtime or runtime.
(some properties that will be described in this section, change format later)
+
*'''goFixedVertLine, goFixedHorzLine''' it draws a vertical or horizontal line respectively delimiting cells or columns in fixed area, active by default.
 +
*'''goVertLine, goHorzLine''' the same as previous, but for normal browseable area. A listbox can be simulated with a grid by unsetting both of this elements.
 +
*'''goDrawFocusSelected''' if this element is enabled a selection background is painted in focused cell in addition to focused dotted rectangle (note this doesn't work yet when goRowSelect option is set, in such case row is always painted as if goDrawFocusSelected is set)
 +
*'''goRowSelect''' select the full row instead of individual cells
 +
*'''goFixedRowNumbering''' if set, grid will do numbering of rows in first fixed column
 +
*'''goHeaderHotTracking''' if set, the grid will try to show a different look when the mouse cursor is overing any fixed cell. In order for this to work, desired cell zone needs to be enabled with property HeaderHotZones. Try combining this option with property TitleStyle:=tsNative to get themed hot tracking look.
 +
*'''goHeaderPushedLook''' if set, this element enables a pushed look when clicking any fixed cell. The zone of "pushable" cells is enabled using HeaderPusedZones property.
  
LOOK:
+
(write more)
  
By modifying some properties user can adapt the grids to look different than default.<br>
+
=== Description of grid's drawing process ===
properties that can be changed at design time:
+
Like other custom controls, the grid draws itself in the paint method, in general terms the grid is drawn by painting all
 +
rows, and each row by painting it's individual cells. The process is as follow:
 +
*First the visible cells area is determined, each row is tested to see if it intersects the canvas clipping region, if it's ok, then visible area is painted by drawing columns of each row.
 +
*The column and row values are used to identify the cell that is about to be painted and again each column is tested for intersection with clippling region, if everything is ok, some additional properties like it's rectangualar extent and visual state are passed as arguments to DrawCell method.
 +
*As the drawing process is running, the visual state of each cell is adjusted according to grid options and position within grid. The visual state is resumed in a varible of type TGridDrawState which is a set with following elements:
 +
**''gdSelected'' The cell will have a selected look.
 +
**''gdFocused'' The cell will have a focused look.
 +
**''gdFixed'' Cell have to be painted with fixed cell look.
 +
**''gdHot'' the mouse is over this cell, so paint it with hot tracking look
 +
**''gdPushed'' the cell is being clicked, paint it with pushed look
 +
*'''DrawCell.''' The DrawCell method is virtual and may be overriden in descendant grids to do custom drawing. The information passed to DrawCell method helps to identify the particular cell is being painted, the physical area ocuppied in screen and it's visible status. See DrawCell reference for details. For each cell following occurs:
 +
*'''PrepareCanvas.''' PrepareCanvas method is called, in this method, If DefaultDrawing property es set, the grid canvas is setup with default properties for brush and font based on current visual state and on several design and runtime properties, the text alignment is set to match programmer selection in custom columns if they exists.  If DefaultDrawing is false, brush color is set to clWindow and Font color to clWindowText, the text alignment is set with grids defaultTextStyle property value.
 +
*'''OnPrepareCanvas.''' If programmer wrote a event handler for OnPrepareCanvas event, it's called at this point. This event can be used for doing simple customization like changing cell's background color, font's properties like color, fontface and style, Text layout like different combinations of left, center, top, bottom, right alignment, etc. Any change made to the canvas in this event would be lost, because the next cell drawing will reset canvas again to a default state. So it's safe doing changes only for particular cell or cells and forget about it for the rest. Using this event sometimes helps to avoid uusing OnDrawCell grid event where users would be forced to duplicate the grid's drawing code. todo: samples of what can be made and what to leave for OnDrawCell?...
 +
*'''OnDrawCell.''' Next if no handler for OnDrawCell event was specified, the grid calls the DefaultDrawCell method which simply paints the cell background using current canvas brush color and style, if OnDrawCell handler exists, the grid first paints the cell background but only if DefaultDrawing property was set, then it calls OnDrawCell event to do custom cell painting. Usually programmers want to do custom drawing only for particular cells, but standard drawing for others, in this case, they can restrict custom operation to certain cell or cells by looking into ACol,ARow and AState arguments, and for other cells simply call DefaultDrawCell method and let the grid to take care of it.
 +
*'''Text.''' At this point (only for TStringGrid) if DefaultDrawing property is true, the cell's text content is painted.
 +
*'''Grid lines'''. The last step for each cell is to paint the grid lines if grid options goVertLine,goHorzLine, goFixedVertLine and goFixedHorzLine are specified the cell grid is drawn at this point. Grids with only rows or only cols can be obtained by changing these options. If programmer elected to have a "themed" look it's done at this point also (see property TitleStyle).
 +
*'''FocusRect.''' When all columns of current row have been painted it's time to draw the focus rectangle for current selected cell or for the whole row if goRowSelect option is set.
  
AlternateColor: With this the user can change the background color appears on alternated rows. This is to allow easy lecture of grid rows data.<br>
+
=== Grid's cell selection ===
Color: This sets the primary color used to draw non fixed cells background.<br>
+
Grid's current (focused) cell (or row) can be changed of location using keyboard, mouse or through code, in order a cell focus can be successfully changed to another position, target position need to be tested if it's allowed to receive cell focus. When using keyboard, the property AutoAdvance takes part of the process by finding what should be the next focused cell. When using mouse by clicking or by code, the target cell needs to be allowed to receive focus or currently focused cell will not move.
FixedColor: This is the color used to draw fixed cells background.<br>
 
flat: this eliminates the 3d look of fixed cells.<br>
 
TitleFont: Font used to draw the text in fixed cells.<br>
 
TitleStyle: This property changes the 3D look of fixed cells, there are 3 settings: tsLazarus, this is the default look<br>
 
tsNative, this tries to set a look that is in concordance with current widgetset theme.<br>
 
tsStandard, this tries a more contrasted look, like delphi grids.<br>
 
  
at runtime we have many other possiblities:<br>
+
The way the grid knows what cell is focusable is by calling function SelectCell, if this function returns true, then the target cell identified with arguments acol and arow is focusable, current implementation in TCustomGrid simply returns true. TCustomDrawGrid and hence TDrawGrid and TStringGrid override this method to check first if cell is any wider than 0, normally you don't want a 0 width cell selected so a cell with this characteristics is skipped automatically in the process to find a suitable cell. The other thing the overriden method SelectCell does is to call the user configurable event OnSelectCell, this event receive as arguments, the cell coordinates and a default result value of true always.
AltColorStartNormal: boolean, if true alternate color is always in the second row after fixed rows, the first row after fixed rows will be always color, if false default color is set to the first row as if there were no fixed rows.<br>
 
BorderColor: This sets the grid's border color used when Flat:=True and BorderStyle:=bsSingle;<br>
 
EditorBorderStyle: if set to bsNone under windows the cell editors will not have the border, like in delphi, set to bsSingle by default because the border can be theme specific in some widgetsets and to allow a uniform look.<br>
 
FocusColor: The color used to draw the current focused cell if UseXORFeatures is not set, by default this is clRed.<br>
 
FocusRectVisible: turns on/off the drawing of focused cell.<br>
 
GridLineColor: color of grid lines in non fixed area.<br>
 
GridLineStyle: Pen style used to draw lines in non fixed area, possible choices are: psSolid, psDash, psDot, psDashDot, psDashDotDot, psinsideFrame, psPattern,psClear. default is psSolid.<br>
 
SelectedColor: Color used to draw cell background on selected cells.<br>
 
UseXORFeatures: if set focus rect is draw using XOR mode so it should make visible the focus rect in any cell color background. it affects the look of moving column.<br>
 
  
Customizing look:<br>
+
Once a cell is known to be focusable and for sure a movement will take place, first method BeforeMoveSelection is called which in turns triggers OnBeforeSelection event, this method's arguments are the coordinates the new focused cell will have, at this point any visible editor is hidden too. the "before" word means that selection is not yet changed and current focused coordinates can be accessed with grid.Col and grid.Row properties.
(this information is <for customizing the grid without writing derived ones)<br>
 
  
DefaultDrawing: boolean. Normally the grids prepare the grid canvas using some properties according to the kind of cell is being painted. If user write an OnDrawCell event handler, DefaultDrawing if set also paints the cell background, if user is drawing fully the cell is better turn off this property so painting is not duplicated. In a StringGrid if DefaultDrawing is set it draws the text in each cell.<br>
+
After that, the internal focused cell coordinates are changed and then method MoveSelection is called, this method purpose is to trigger OnSelection event if set, this is a notification that focused cell has, by this time, already changed and cell coordinates are now available through grid.row and grid.col properties.
  
OnDrawCell event: the user would want to write an event handler for this if needs to draw custom things in a cell, it could be text, a graphic a picture or anything else. If the grid doesn't to store the cell text in the grid but rather the text or content is in another structure it's probably better to use TDrawGrid for this. TStringGrid is specialized on handling Text on cells but also can be compleatly customized by writing an OnDrawCell event handler.<br>
+
Note that is not good to use OnSelectCell event to detect cell focus changes, this event will be triggered several times even for the same cell in the process of finding a suitable cell. Is better to use OnBeforeSelection or OnSelection events for this purpose.
if DefaultDrawing is true, the canvas brush, pen and font it's already prepared and even the cell background it's already filled so turn off this if you are drawing pictures or gradients in cell.<br>
 
if user needs to customize only certain cells in the grid (for example for a stringgrid) then (s)he could do special drawing on specific cells and for the rest, call grid.DefaultDrawCell() function which will do write cells normally.<br>
 
  
OnPrepareCanvas: Sometimes users needs to custom draw specific cells with simply things like a different cell color, a different font or a different text layout in case of stringgrid, users doesn't have to write an OnDrawCell handler to do this there they need to actually draw the text or fill the background using canvas primitives, instead users could write an OnPrepareCanvas so they affect canvas properties like Font, brush, pen and TextStyle, this could be done for just for specific cells, the grid will reset this canvas properties for the other cells. So no need to anything.<br>
+
=== Several differences with delphi have been identified ===
+
*In Lazarus TCustomGrid.DrawCell method is not abstract and it's default implementation do basic cell background filling.
(this information is for writing derived grids.)<br>
+
*In delphi, the cell's text is drawn before entering the OnDrawCell event see [http://www.freepascal.org/mantis/view.php?id=9619 bug report #9619]).
 +
*SelectCell and OnSelectCell behaviour is probably different, can't really comment on the differences but in lazarus is they are used in functinality like AutoAdvance which afaik doesn't exist in delphi.
  
 +
=== When above customizaton is not enough, derived grids ===
 
Derivd grids usually have to override following methods:<br>
 
Derivd grids usually have to override following methods:<br>
 
DrawAllRows: Draws all visible rows.<br>
 
DrawAllRows: Draws all visible rows.<br>
 
DrawRow: Draw All Cells in a Row.<br>
 
DrawRow: Draw All Cells in a Row.<br>
DrawRow draws all cells in the row by first checking if cell is withing clipping region, and only draws the cell if it is.<br>
+
DrawRow draws all cells in the row by first checking if cell is withing clipping region, and only draws the cell if it  
 +
is.<br>
 
DrawCell:<br>
 
DrawCell:<br>
 
DrawCellGrid:<br>
 
DrawCellGrid:<br>
Line 265: Line 316:
 
(write me).<br>
 
(write me).<br>
  
==== Customizing grids use ====
 
  
FEEL
+
=== Ablauf der Methodenaufrufe in <tt>TCustomGrid.Paint</tt> ===
 +
Die folgenden Auflistungen sollen den Ablauf zum Zeichnen eines TCustomGrid-Nachkommen vereinfacht darstellen.
 +
Die verschachtelten Aufzählungen bezeichnen jeweils Methodenaufrufe innerhalb eines Grids. Bei der Entwicklung von Nachkommen von TCustomGrid, kann so die richtige Methode zum Überschreiben leichter gefunden werden.
 +
*'''<tt>DrawEdges</tt>''': Zeichnet den äußeren Rahmen des Grids.
 +
*'''<tt>DrawAllRows</tt>''' (virtual): Hier werden alle sichtbaren Zellen des Gitters gezeichnet.
 +
**'''<tt>DrawRow</tt>''' (virtual): Zeichnet alle sichtbaren Zellen einer Zeile. Wird für jede Gitterzeile im aktuellen Sichtfenster einmal ausgeführt.
 +
***'''<tt>DrawCell</tt>''' (virtual): Wird zunächst für jede 'normale' (also nicht fixierte) Zelle der Zeile ausgeführt.
 +
****'''<tt>PrepareCanvas</tt>''' (virtual): Setzt die Eigenschaften der Zeichenfläche für das Zeichnen der aktuellen Zelle.
 +
****'''<tt>DrawFillRect</tt>''': Zeichnet den Hintergrund der Zelle im mit <tt>PrepareCanvas</tt> eingestellten Stil.
 +
****'''<tt>DrawCellGrid</tt>''' (virtual): Zeichnet die Begrenzungen der Zelle.
 +
***'''<tt>DrawFocusRect</tt>''' (virtual): In <tt>TCustomGrid</tt> hat diese Methode keine Funktion. In abeleiteten Grid-Klassen wird hier das Focus-Rechteck innerhalb der aktiven Zelle gezeichnet.
 +
***'''<tt>DrawCell</tt>''' (virtual): (siehe oben) Abschließend wird <tt>DrawCell</tt> für jede fixierte Zelle im Sichtbereich der Zeile einmal ausgeführt.
 +
*'''<tt>DrawColRowMoving</tt>''': Wird nur während des Verschiebens einer Zeile/Spalte ausgeführt. Es zeichnet die Linie mit welcher die neue Position der verschobenen Zeile/Spalte angedeutet wird.
 +
*'''<tt>DrawBorder</tt>''': Wenn nötig (<tt>Flat=TRUE</tt> und <tt>BorderStyle=bsSingle</tt>), wird hier ein innerer Rand gezeichnet.
 +
==== Weitere Methoden zum Zeichnen in <tt>TCustomGrid</tt> ====
 +
Die folgenden Methoden werden zwar in <tt>TCustomGrid</tt> deklariert, hier aber nicht direkt aufgerufen. Sie werden von abgeleiteten Klassen ausgeführt um den Zelleninhalt zu zeichnen.
  
AutoAdvance: where the cell cursor will go when pressing enter or tab/shift tab, or after editing.<br>
+
*'''<tt>DrawCellText</tt>''' (virtual): Zeichnet den im Parameter übergebenen Text in die Zelle. Verwendet zur Formatierung die in <tt>Canvas.TextStyle</tt> aktiven Einstellungen (siehe <tt>PrepareCanvas</tt>).
ExtendedColSizing: if true user can resize columns not just at the headers but along the columns height.<br>
+
<br>
OnSelectCell: <br>
+
*'''<tt>DrawThemedCell</tt>''' (virtual): Wird nur für fixierte Zellen verwendet, wenn <tt>TitleStyle=tsNative</tt>. Zeichnet den Hintergrund der Zelle mit den Einstellungen der <tt>ThemeServices</tt>.
(write me)
+
<br>
 +
*'''<tt>DrawColumnText</tt>''' (virtual): Wird nur für die Zellen der Spaltenüberschriften ausgeführt
 +
**'''<tt>DrawColumnTitleImage</tt>''': Wenn eine <tt>TitleImageList</tt> zugewiesen und in <tt>Columns.Title[x].Title.ImageIndex</tt> ein gültiger Wert eingetragen ist, wird das entsprechende Icon gezeichnet.
 +
**'''<tt>DrawCellText</tt>''' : (siehe oben)
 +
<br>
 +
*'''<tt>DrawTextInCell</tt>''' (virtual): Wird nur für 'normale' (nicht fixierte) Zellen verwendet. In <tt>TCustomGrid</tt> hat diese Methode keine Funktion. In abeleiteten Grid-Klassen wird hier der Zelleninhalt in die Zelle gezeichnet. In <tt>TStringGrid</tt> ruft diese Methode wiederum <tt>DrawCellText</tt> (siehe oben) auf.
 +
==== Erweiterung des Zeichenfunktionen in <tt>TCustomDrawGrid</tt> ====
 +
Wie man sieht, Zeichnet die Basisklasse <tt>TCustomGrid</tt> keinen Inhalt in das Grid. Dies geschieht in '''<tt>TCustomDrawGrid</tt>'''.
 +
Hier wird die Methode <tt>DrawCell</tt> folgendermaßen überschrieben.
 +
*'''<tt>DrawCell</tt>''' (override):
 +
**'''<tt>PrepareCanvas</tt>''': Aufruf der von '''<tt>TCustomGrid</tt>'''geerbten Methode
 +
**'''<tt>DefaultDrawCell</tt>''' (virtual): Ist eine Ereignisbehandlung für <tt>OnDrawCell</tt> zugewiesen, wird diese Methode '''nicht''' ausgeführt. Sonst
 +
***'''<tt>DrawFillRect / DrawThemedCell</tt>''' (von <tt>TCustomGrid</tt>): Zeichnet den Hintergrund der Zelle. Ist <tt>TitleStyle=tsNative</tt>, wird der Hintergrund für fixierte Zellen mit <tt>DrawThemedCell</tt> gezeichnet.
 +
***'''<tt>DrawCellAutonumbering</tt>''' (virtual): Nur, wenn <tt>goFixedAutonumbering in Options</tt> wird in der ersten fixierten Spalte mit <tt>TCustomGrid.DrawCellText</tt> die Numerierung gezeichnet.
 +
***'''<tt>DrawColumnText</tt>''' (von <tt>TCustomGrid</tt>): Wird nur für die Zellen der Spaltenüberschriften ausgeführt. Siehe ''Weitere Methoden zum Zeichnen in <tt>TCustomGrid</tt>''.
 +
***'''<tt>DrawTextInCell</tt>''' (von <tt>TCustomGrid</tt>): Wird nur für 'normale' (nicht fixierte) Zellen ausgeführt. Siehe ''Weitere Methoden zum Zeichnen in <tt>TCustomGrid</tt>''.
 +
**'''<tt>DrawCellGrid</tt>''' (virtual): Zeichnet die Begrenzungen der Zelle.
  
 
=== Operationen ===
 
=== Operationen ===
 +
 
==== Save and Retrieve Grid Content ====
 
==== Save and Retrieve Grid Content ====
  
Die '''SaveToFile''' Prozedur erlaubt ihnen, die TStringGrid Formate, Attribute und Werte in eine XML Datei zu speichern.
+
The '''SaveToFile''' procedure allows you save the TStringGrid format, attributes & values to a XML file.
Zuvor müssen sie die SaveOptios Eigenschaft wie folgt setzen:
+
Previously you must set the SaveOptios property as follow:
  
 
  soDesign:    Save & Load ColCount,RowCount,FixedCols,FixedRows,
 
  soDesign:    Save & Load ColCount,RowCount,FixedCols,FixedRows,
Line 286: Line 368:
 
  soContent:    Save & Load Text (TCustomStringGrid)
 
  soContent:    Save & Load Text (TCustomStringGrid)
  
Die '''LoadFromFile''' Prozedur erlaubt ihnen, Attribute, Formate und Werte aus einer '''XML''' Datei in eine StringGrid Instanz zu laden.
+
The '''LoadFromFile''' procedure allows you to load into a StringGrid instance, attributes, formats & values, from a
Zuerst müssen sie einige dieser Optionen der SaveOptios Eigenschaft setzen (in ihrer TStringGrid Instanz)  [[SaveOptions]]   
+
'''XML''' file.
 +
First, you must set some of this options of the SaveOptios property (on your TStringGrid instance)  [[SaveOptions]]   
 
   soDesign:    Save & Load ColCount,RowCount,FixedCols,FixedRows,
 
   soDesign:    Save & Load ColCount,RowCount,FixedCols,FixedRows,
 
                 ColWidths, RowHeights and Options (TCustomGrid)
 
                 ColWidths, RowHeights and Options (TCustomGrid)
Line 297: Line 380:
  
 
'''Beispiel:'''
 
'''Beispiel:'''
1) Zuerst öffnen sie ein neues Projekt "Application".
+
1) First Open a new project "Application".
2) Legen sie ein leeres TStringGrid ab.
+
2) Put an empty TStringGrid.
3) Legen sie einen TButton ab.
+
3) Put a TButton.
4) Legen sie einen TOpenDialog ab.
+
4) Put a TOpenDialog  
5) Fügen sie ein OnCreate Ereignis für das Formular hinzu.
+
5) Add the event OnCreate for the Form
5) Fügen sie ein OnClick Ereignis für den Button hinzu.
+
5) Add the event OnClick for the Button
<pre>
+
<syntaxhighlight lang=pascal>
 
unit Unit1;  
 
unit Unit1;  
  
Line 338: Line 421:
 
procedure TForm1.Form1Create(Sender: TObject);
 
procedure TForm1.Form1Create(Sender: TObject);
 
begin
 
begin
  //setzt die SaveOptions bei der Erzeugung des Formulars
+
  //sets the SaveOptions at creation time of the form
 
  stringgrid1.SaveOptions := [soDesign,soPosition,soAttributes,soContent];
 
  stringgrid1.SaveOptions := [soDesign,soPosition,soAttributes,soContent];
 
end;
 
end;
Line 364: Line 447:
  
 
end.
 
end.
</pre>
+
</syntaxhighlight>
 
----
 
----
'''Die Beispiel-XML-Datei:'''
+
'''Die Beispiel XML-Datei:'''
(Kopieren sie den Text unterhalb in eine Textdatei und vergessen sie den XML Header nicht :-))
+
(Kopieren sie den text unterhalb in eine .txt Datei. Vergessen sie den XML header nicht :-))
<pre>
+
<syntaxhighlight lang="xml">
 
''<?xml version="1.0"?>
 
''<?xml version="1.0"?>
 
<CONFIG>
 
<CONFIG>
Line 415: Line 498:
 
   </grid>
 
   </grid>
 
</CONFIG>''
 
</CONFIG>''
</pre>
+
</syntaxhighlight>
 
----
 
----
 
--[[User:Raditz|Raditz]] 21:06, 11 Jan 2006 (CET) from '''ARGENTINA'''
 
--[[User:Raditz|Raditz]] 21:06, 11 Jan 2006 (CET) from '''ARGENTINA'''
Line 421: Line 504:
 
=== Grid Cell Editors ===
 
=== Grid Cell Editors ===
  
The grid uses cell editors to change the content of cells. For a specilized grid like TStringGrid, the editor is the habitual single line text editor control, sometimes it's desireable to have other means to enter information. For example, to call the open file dialog to find the location of a file so the user doesn't have to type the full path manually, if the text in the cell represents a date, it would be more friendly if we could popup a calendar so we can choose a specific date easily. Sometimes the information the user should enter in a cell is restricted to a limited list of words, in this case typing the information directly might introduce errors and validating routines might need to be implemented, we can avoid this by using a cell editor that present the user a list with only the legal values. This is also the case of generic grids like TDrawGrid where user have to have some kind of structure to hold the data that will be shown in the grid, in this situation, the information that is entered in the cell editor updates the internal structure to reflect the changes in the grid.
+
The grid uses cell editors to change the content of cells. For a specilized grid like TStringGrid, the editor is the  
 +
habitual single line text editor control, sometimes it's desireable to have other means to enter information. For example,
 +
to call the open file dialog to find the location of a file so the user doesn't have to type the full path manually, if  
 +
the text in the cell represents a date, it would be more friendly if we could popup a calendar so we can choose a  
 +
specific date easily. Sometimes the information the user should enter in a cell is restricted to a limited list of words,  
 +
in this case typing the information directly might introduce errors and validating routines might need to be implemented,  
 +
we can avoid this by using a cell editor that present the user a list with only the legal values. This is also the case  
 +
of generic grids like TDrawGrid where user have to have some kind of structure to hold the data that will be shown in the  
 +
grid, in this situation, the information that is entered in the cell editor updates the internal structure to reflect the  
 +
changes in the grid.
  
 
==== Builtin cell editors ====
 
==== Builtin cell editors ====
  
The grids.pas unit already include some of the most used cell editors ready for use in grids, there is also the posibility to create new cell editors (custom cell editors) if the builtin editors are not appropiated for a specific tasks.
+
The grids.pas unit already include some of the most used cell editors ready for use in grids, there is also the  
 +
posibility to create new cell editors (custom cell editors) if the builtin editors are not appropiated for a specific  
 +
tasks.
  
 
The builtin cell editors are Button, Edit, and Picklist.
 
The builtin cell editors are Button, Edit, and Picklist.
Line 432: Line 526:
  
 
Users can specify what editor will be used for a cell using one of two methods.
 
Users can specify what editor will be used for a cell using one of two methods.
#Using a custom column and selecting the ButtonStyle property of column. In this method the user can select the style of the editor that will be shown. Available values are: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn
+
#Using a custom column and selecting the ButtonStyle property of column. In this method the user can select the style of  
#Using OnSelectEditor grid event, here the user specify in the Editor parameter which editor to use for a cell identified for column aCol and row ARow in a TCustomDrawGrid derived grid or TColumn in TCustomDBGrid. For this purpose there is a useful public function of grids, EditorByStyle() that takes as parameter one of the following values: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn. This method takes precedence over the first one using custom columns. A Custom cell editor can be specified here. This event is also the place to setup the editor with values specific to the cell, row or column.
+
the editor that will be shown. Available values are: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn
 +
#Using OnSelectEditor grid event, here the user specify in the Editor parameter which editor to use for a cell identified  
 +
for column aCol and row ARow in a TCustomDrawGrid derived grid or TColumn in TCustomDBGrid. For this purpose there is a  
 +
useful public function of grids, EditorByStyle() that takes as parameter one of the following values: cbsAuto,  
 +
cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn. This method takes precedence over the first one using custom  
 +
columns. A Custom cell editor can be specified here. This event is also the place to setup the editor with values  
 +
specific to the cell, row or column.
  
 
==== Description of editor styles ====
 
==== Description of editor styles ====
  
The following is the description of each editor style, they are enumeated values of type TColumnButtonStyle and so they are prefixed by 'cbs'. This type was used so it remains compatible with delphi's dbgrid.
+
The following is the description of each editor style, they are enumeated values of type TColumnButtonStyle and so they  
 +
are prefixed by 'cbs'. This type was used so it remains compatible with delphi's dbgrid.
  
 
*'''cbsAuto'''
 
*'''cbsAuto'''
:This is the default editor style for TCustomGrid derived grids. The actual editor class that will be used to edit the cell content, depends on several factors. For TCustomGrids it uses a TStringCelleditor class derived from TCustomMaskEdit, this editor is speciallized to edit single line strings. It is then used in TStringGrid and TDrawGrid by default. When using Custom Columns and programmer filled the Column's PickList property, this behaves as if cbsPickList editor style was set. For a TCustomDBGrid that have a field of type boolean, behaves as if cbsCheckBoxColumn editor style was specified. This is the recomended value for Custom Cell Editors TODO: related OnEditingDone.
+
:This is the default editor style for TCustomGrid derived grids. The actual editor class that will be used to edit the  
 +
cell content, depends on several factors. For TCustomGrids it uses a TStringCelleditor class derived from TCustomMaskEdit,
 +
this editor is speciallized to edit single line strings. It is then used in TStringGrid and TDrawGrid by default. When  
 +
using Custom Columns and programmer filled the Column's PickList property, this behaves as if cbsPickList editor style  
 +
was set. For a TCustomDBGrid that have a field of type boolean, behaves as if cbsCheckBoxColumn editor style was  
 +
specified. This is the recomended value for Custom Cell Editors TODO: related OnEditingDone.
 
*'''cbsEllipsis'''
 
*'''cbsEllipsis'''
:This editor style is the most generic one. When used, a button appears in the editing cell, programmers could use the OnEditButtonClick grid event to detect when user has pressed the button and take any action was programmed for such cell. For example a programmer could use this editor style to pop up a calendar dialog so user can easily pick a specific date, another could be to show a file open dialog to find files, a calculator so user can enter the numeric result of calcs, etc.  
+
:This editor style is the most generic one. When used, a button appears in the editing cell, programmers could use the  
 +
OnEditButtonClick grid event to detect when user has pressed the button and take any action was programmed for such cell.  
 +
For example a programmer could use this editor style to pop up a calendar dialog so user can easily pick a specific date,  
 +
another could be to show a file open dialog to find files, a calculator so user can enter the numeric result of calcs,  
 +
etc.  
  
:OnEditButtonClick is just a notification, so to find out which cell a button has been clicked, take a look at grid.Row and grid.Col properties.
+
:OnEditButtonClick is just a notification, so to find out which cell a button has been clicked, take a look at grid.Row  
 +
and grid.Col properties.
  
:A DbGrid has specific properties to retrieve the active column or field and because this event occurs in active record, it could update the information in active field.
+
:A DbGrid has specific properties to retrieve the active column or field and because this event occurs in active record,  
 +
it could update the information in active field.
  
 
:This editor style is implemented using TButtonCellEditor a direct descendant of TButton.
 
:This editor style is implemented using TButtonCellEditor a direct descendant of TButton.
 
*'''cbsNone'''
 
*'''cbsNone'''
:This editor style instruct the grid to not use any editor for a specific cell or column, it behaves then, as if the grid is readonly for such cell or column.
+
:This editor style instruct the grid to not use any editor for a specific cell or column, it behaves then, as if the grid  
 +
is readonly for such cell or column.
 
*'''cbsPickList'''
 
*'''cbsPickList'''
:Used to present the user a list of values that can be entered, this editor style is implemented using TPickListCellEditor a component derived from TCustomComboBox. The list of values that are shown, are filled in two ways depending of the method used to select the editor style.
+
:Used to present the user a list of values that can be entered, this editor style is implemented using  
:#When using custom columns, programmers can enter a list of values using the column's PickList property. [FOR BEGINNERS: TODO: exact procedure to edit the list]
+
TPickListCellEditor a component derived from TCustomComboBox. The list of values that are shown, are filled in two ways  
:#In OnSelectEditor, programmers get the TPickListCellEditor instance using the function EditorByStyle(cbsPickList), an example would be: var Lst:TPickListCellEditor; begin [...] Lst:=TPickListCellEditor(EditorByStyle(cbsPickList)); Lst.clear; Lst.Items.add('One');lst.items.add('Two'); Editor:=Lst; end;
+
depending of the method used to select the editor style.
:The value in a TStringGrid grid will automatically reflect the value selected, if necessary the programmer could detect the moment the value is selected by writing an event handler for grid's OnPickListSelect event, so additional steps can be taken for example, to process the new value. TODO: related OnEditingDone.
+
:#When using custom columns, programmers can enter a list of values using the column's PickList property. [FOR BEGINNERS:  
 +
TODO: exact procedure to edit the list]
 +
:#In OnSelectEditor, programmers get the TPickListCellEditor instance using the function EditorByStyle(cbsPickList), an  
 +
example would be: var Lst:TPickListCellEditor; begin [...] Lst:=TPickListCellEditor(EditorByStyle(cbsPickList));  
 +
Lst.clear; Lst.Items.add('One');lst.items.add('Two'); Editor:=Lst; end;
 +
:The value in a TStringGrid grid will automatically reflect the value selected, if necessary the programmer could detect  
 +
the moment the value is selected by writing an event handler for grid's OnPickListSelect event, so additional steps can  
 +
be taken for example, to process the new value. TODO: related OnEditingDone.
 
*'''cbsCheckboxColumn'''
 
*'''cbsCheckboxColumn'''
:This editor style is at the moment only available in TDbGrid. This editor style can be useful when field content associated with the column are restricted to a pair of values, for example, yes-no, true-false, on-off, 1-0, etc. Instead of forcing the user to type the values for this kind of field in a StringCellEditor or to choose one from a list, cbsCheckboxColumn is used to modify the field content of a column by using a checkbox representation that user can toggle by using a mouse click or pressing the SPACE key.
+
:This editor style is at the moment only available in TDbGrid. This editor style can be useful when field content  
 +
associated with the column are restricted to a pair of values, for example, yes-no, true-false, on-off, 1-0, etc. Instead  
 +
of forcing the user to type the values for this kind of field in a StringCellEditor or to choose one from a list,  
 +
cbsCheckboxColumn is used to modify the field content of a column by using a checkbox representation that user can toggle  
 +
by using a mouse click or pressing the SPACE key.
  
:If columns' ButtonStyle property is set to cbsAuto and DbGrid detects that the field associated to the column is a boolean field, then the grid use this editor style automatically, this automatic selection can be disabled or enabled using dbgrid's OptionsExtra property, setting dgeCheckboxColumn element to false disable this feature.
+
:If columns' ButtonStyle property is set to cbsAuto and DbGrid detects that the field associated to the column is a  
 +
boolean field, then the grid use this editor style automatically, this automatic selection can be disabled or enabled  
 +
using dbgrid's OptionsExtra property, setting dgeCheckboxColumn element to false disable this feature.
  
:The values that are used to recognize the checked or unchecked states are set in column's properties ValueChecked and ValueUnchecked.
+
:The values that are used to recognize the checked or unchecked states are set in column's properties ValueChecked and  
 +
ValueUnchecked.
  
:In any moment, the field value can be in one to three states: Unchecked, checked or grayed. Internally this states are identified by the following values of type TDBGridCheckBoxState: gcbpUnChecked, gcbpChecked and gcbpGrayed.
+
:In any moment, the field value can be in one to three states: Unchecked, checked or grayed. Internally this states are  
 +
identified by the following values of type TDBGridCheckBoxState: gcbpUnChecked, gcbpChecked and gcbpGrayed.
  
:This editor style doesn't use real TCheckbox components to handle user interaction, the visual representation is given by three builtin bitmap images that corresponds to the possible states of checkbox. The used bitmaps can be customized by writing a handler for DBGrid event OnUserCheckboxBitmap, the handler of this event gets the state of the checkbox in parameter CheckedState of type TDbGridCheckboxState and a bitmap parameter that programmer could use to specify custom bitmaps.
+
:This editor style doesn't use real TCheckbox components to handle user interaction, the visual representation is given  
 +
by three builtin bitmap images that corresponds to the possible states of checkbox. The used bitmaps can be customized by  
 +
writing a handler for DBGrid event OnUserCheckboxBitmap, the handler of this event gets the state of the checkbox in  
 +
parameter CheckedState of type TDbGridCheckboxState and a bitmap parameter that programmer could use to specify custom  
 +
bitmaps.
  
 
==== Beispiel: How to set a custom cell editor ====
 
==== Beispiel: How to set a custom cell editor ====
  
 
Siehe lazarus/examples/gridcelleditor/gridcelleditor.lpi
 
Siehe lazarus/examples/gridcelleditor/gridcelleditor.lpi
 +
 +
=== Wie scrollt man ein Grid in "Echtzeit" (während man den Scrollbalken per Maus bewegt) ===
 +
 +
Wenn man ein Grid scrollt, indem man den Scrollbalken per Maus bewegt, dann scrollt das Grid per Default nicht "in Echtzeit", sondern erst, wenn man die Maus los lässt, "springt" das Grid an seine neue Position. Man kann ein scrollen "in Echtzeit" aktivieren, in dem man Option <code>goThumbTracking</code> hinzufügt.
 +
 +
Beispiel: <syntaxhighlight lang="pascal"> StringGrid1.Options:=StringGrid1.Options + [goThumbTracking]; </syntaxhighlight>
 +
 +
Leider ist diese Option weder dokumentiert in <tt><lazarus-installdir>\lcl\grids.pas</tt> (ver 2.0.6) noch in https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tgridoptions.html
  
 
== Todo ==
 
== Todo ==
 
*TInplaceEditor Unterstützung
 
*TInplaceEditor Unterstützung
 +
 
=== Bekannte Probleme ===
 
=== Bekannte Probleme ===
 
29-März-2005:
 
29-März-2005:
 
*mouse autoedit
 
*mouse autoedit
** Linux: Klicken auf eine gewählte Zelle löst nicht die autoedit Funktion aus (der Editor verliert sofort den Fokus)
+
** linux: clicking a selected cell doesn't trigger the autoedit function (the editor lost focus inmmediatelly)
** Windows: it should work only if the grid has the focus, if not it should focus and a second click should autoedit (cannot detect if the grid was previously focused or not)
+
** windows: it should work only if the grid has the focus, if not it should focus and a second click should autoedit (cannot detect if the grid was previously focused or not)
*ColumnWidths: Linux, Windows: dbgrid start with default column widths instead of calculated ones (it's disabled because early canvas creation causes strange effects if the parent is a notebook page)
+
*ColumnWidths: linux, windows: dbgrid start with default column widths instead of calculated ones (it's disabled because early canvas creation causes strange effects if the parent is a notebook page)
*Resizing Columns: Linux, Windows. Resizing a column should not hide the editor (specially in dbgrid if we are inserting)
+
*Resizing Columns: linux, windows. Resizing a column should not hide the editor (specially in dbgrid if we are inserting)
 
*MouseWheel:
 
*MouseWheel:
**Linux: mousewheel doesn't work as it should, (seems it's calling the default mousewheel handler)
+
**linux: mousewheel doesn't work as it should, (seems it's calling the default mousewheel handler)
**Windows: patch was sent.
+
**windows: patch was sent.
*Double painting: Apparently dbgrid is painting twice the cell background (one with fillrect and one in textRect)
+
*Double painting: Apparently dbgrid paints the cell background twice (once with fillrect and once in textRect)
 
*AutoFillColumns: sometimes the clientwidth is evaluated incorrectly (sometimes there are phantom scrollbars)
 
*AutoFillColumns: sometimes the clientwidth is evaluated incorrectly (sometimes there are phantom scrollbars)
 +
<br>
 +
<br>
 +
 +
[[Category:Tutorials/de]]{{AutoCategory}}

Revision as of 12:14, 16 February 2020

Deutsch (de) English (en) español (es) polski (pl) русский (ru)

Zurück zu den Zusätzlichen Informationen.

Die Zielsetzung

Dieser Text will versuchen, dem Benutzer einige Aspekte der Grid-Komponenten in Lazarus zu zeigen. Es ist auch vorgesehen, als ein Handbuch für Benutzer zu dienen, die noch nie zuvor Grids benutzt haben (während erfahrene Benutzer im Allgemeinen nur eine Referenz benötigen für neue Funktionalitäten). Daher will dieser Text versuchen, die folgenden Ziele zu erreichen:

  1. Die Grid-Komponenten den Menschen mit geringem oder gar keinem Delphi Kontakt vorzustellen.
  2. Die Unterschiede hinsichtlich der Delphi Grid-Komponenten zu dokumentieren.
  3. Die neuen Funktionalitäten in Lazarus Grids zu dokumentieren.
  4. Referenzen und Beispiele für die Komponenten zu erstellen.

Überblick

Ein Grid ist eine Komponente, die hauptsächlich zur Anzeige von Daten in einem tabellarischen Format dient. Die offensichtlichste Charakteristik von Grids ist, dass sie aus Zellen bestehen, Zeilen und Spalten bildend.

Der Informationstyp, der in einem Grid angezeigt werden kann, ist sehr weitläufig, hauptsächlich abhängig von dem, was der Benutzer anzeigen möchte. Gewöhnlich wird diese Information in Text, Farben, Bilder oder eine Kombination daraus übersetzt.

In Anbetracht der großen Vielfalt von Informationen, die repräsentiert werden können, existiert eine Reihe von Grids, deren Zweck darin besteht, den Benutzer zu unterstützen, eine spezifische Art von Informationen zu zeigen.

Vererbungsbaum

                      [TCustomControl]           
                              |                    
                              |                    
                         TCustomGrid               
                              |                    
                +-------------+------------+       
                |                          |       
          TCustomDrawGrid             TCustomDbGrid
                |                          |       
       +--------+--------+                 |       
       |                 |              TDbGrid    
   TDrawGrid      TCustomStringGrid                
                         |                         
                         |                         
                    TStringGrid                    

Ein Anfangsbeispiel

Eine Zielsetzung dieses Textes soll die Benutzerfreundlichkeit sein, insbesondere für diejenigen, die keine oder wenig Erfahrung mit Lazarus haben. Fangen wir also mit einem einfachen Beispiel an, in dem wir die Grids-Komponente in Aktion sehen und beginnen mit dem traditionellen "Hallo Welt" Beispiel unter Verwendung der TStringGrid Komponente.

  1. Erstellen sie eine neue Anwendung.
    • Im Hauptmenü wählen sie: Projekt -> Neues Projekt
    • Im Erzeuge neues Projekt Dialog drücken sie den "Erzeuge Button"
    • Ein neues leeres Formular wird angezeigt.
  2. Platzieren sie ein Grid auf dem Formular.
    • In der Komponentenpalette wählen sie den "Additional" Tab.
    • Klicken sie auf das TStringGrid Icon [].
    • Klicken sie auf das Formular, in der Nähe der oberen linken Ecke. Ein neues leeres Grid erscheint.
  3. Platzieren sie einen Button auf dem Formular.
    • In der Komponentenpalette wählen sie den "Standard" Tab.
    • Klicken sie auf das TButton Icon [].
    • Klicken sie auf einen freien Bereich im Formular. Ein neuer Button erscheint.
  4. Klicken sie doppelt auf den Button von Schritt 3, und schreiben sie den folgenden Code in den click button handler:
    • Stringgrid1.Cells[1,1] := 'Hi World!';
  5. Starten sie das Programm durch klicken auf das Start Icon [].
    • Durch Drücken von Button1, sollte der hello world Text in der Zelle Spalte 1, Zeile 1 erscheinen.

Unterschiede zwischen Lazarus und Delphi Grids

Die momentanen Grid-Komponenten haben mehrere Unterschiede im Vergleich zu den Delphi Grid-Komponenten. Dies kommt vor allem daher, dass die Lazarus Grid-Komponenten komplett neu geschrieben wurden und dabei nicht zwingend auf die Kompatibilität geachtet wurde.

Die Kompatibiliät wurde erst zu einem späteren Zeitpunkt zu einem Ziel. Die Grid-Komponenten passten sich immer mehr dem Interface der Delphi Grid-Komponenten an, aber dabei wurde nicht jede einzelne Methode und jede Eigenschaft 1:1 übernommen.

Weil die Grid-Komponenten intern recht unterschiedlich sind, gibt es Dinge die nicht möglich sind oder anders als bei einer Delphi Grid-Komponente funktionieren. Im Laufe der Entwicklung der Grid-Komponenten, wurde die Kompatibilität jedoch immer besser was durchaus auch wünschenswert ist.

Unterschiede

An dieser Stelle werden die bekannten Unterschiede aufgeführt ohne spezielle Reihenfolge.

  • Zelleneditoren
  • Entwicklungszeitverhalten
  • Es gibt einige Unterschiede beim Zeichnen der Zellen, siehe Abschnitt Customizing grids

Neue Funktionsweise

  • Spalten
  • Ereignisse
  • Grid Editor

Anpassungen zur Verbesserung der Delphi grids Kompatibilität

Hier ist eine Liste von Eigenschaften und Anpassungen die vorgenommen werden können, damit Lazarus grids wie Delphi grids aussehen oder sich so verhalten. This adjustments are based in a newly created grid. Einträge mit [Code] müssen im Quellcode gesetzt werden, [Design] Einträge können zur Entwicklungszeit geändert werden.

  • [Design] TitleStyle:=tsStandard;
  • [Design] DefaultRowHeight:=24;
  • [Code] EditorBorderStyle:=bsNone; // dies dürfte nur unter Windows funktionieren.
  • [Code] UseXORFatures:=true;
  • [Code] AllowOutBoundClicks:=False; (r10992 oder später)
  • [Code] FastEditing:=False; (unterstützt in dbgrid. StringGrid benötigt r10992 oder später)
  • [Design] AutoAdvance:=aaNone;

Grids Referenz

Information

Der Ausgangspunkt für eine Referenz über TCustomGrid, TDrawGrid, TCustomDrawGrid, TCustomStringGrid und TStringGrid ist die Unit grids.pas Referenz.

Für TCustomDBGrid und TDBgrid ist es die Unit dbgrids.pas Referenz.

Gegenwärtig enthalten diese Links noch nicht viel Inhalt, teilweise wegen des Fehlens eines Werkzeugs, das eine einfache Wartung ihres Inhalts erlaubt. Aber ein solches Werkzeug ist im Aufbau befindlich und irgendwann werden die Lücken gefüllt werden.

Im Allgemeinen, jede Delphi Referenz über Grids sollte helfen, die Lazarus Grids zu verwenden (don't forget that there are several differences between Delphi and Lazarus grids being documented), with this in mind and as a temporal place for reference information, wird dieser Ort genutzt, um Dinge zu dokumentieren, die nicht wie in Delphi funktionieren oder die eine neue Funktionalität darstellen.

[TODO: the rest of this section will dissapear, it's content will be moved to unit grids.pas reference

TCustomGrid

See the full TCustomGrid Reference

property OnBeforeSelection: TOnSelectEvent

property OnCompareCells: TOnCompareCells

property OnPrepareCanvas: TOnPrepareCanvasEvent

property OnDrawCell: TOnDrawCell

property OnEditButtonClick: TNotifyEvent

property OnSelection: TOnSelectEvent

property OnSelectEditor: TSelectEditorEvent

property OnTopLeftChanged: TNotifyEvent

procedure AutoAdjustColumns;

procedure BeginUpdate;

procedure Clear;

procedure DeleteColRow(IsColumn: Boolean; index: Integer);

function EditorByStyle(Style: TColumnButtonStyle): TWinControl;

procedure EndUpdate(UO: TUpdateOption); overload;

procedure EndUpdate(FullUpdate: Boolean); overload;

procedure EndUpdate; overload;

procedure ExchangeColRow(IsColumn: Boolean; index, WithIndex:Integer);

function IscellSelected(aCol,aRow: Integer): Boolean;

function IscellVisible(aCol, aRow: Integer): Boolean;

procedure LoadFromFile(FileName: string);

function MouseToCell(Mouse: TPoint): TPoint; overload;

function MouseToLogcell(Mouse: TPoint): TPoint;

function MouseToGridZone(X,Y: Integer): TGridZone;

function CellToGridZone(aCol,aRow: Integer): TGridZone;

procedure MoveColRow(IsColumn: Boolean; FromIndex, ToIndex: Integer);

procedure SaveToFile(FileName: string);

procedure SortColRow(IsColumn: Boolean; index:Integer); overload;

procedure SortColRow(IsColumn: Boolean; index,FromIndex,ToIndex: Integer); overload;

TCustomStringGrid

TCustomStringGrid dient als Basis für TStringGrid. It can be used for derived TStringGrid components that want to hide published properties. See new intermediate grids for more information.

These properties or methods are public and are also available to TStringGrid.

See the full TCustomStringGrid Reference

procedure AutoSizeColumn(aCol: Integer);

This procedure sets the column width to the size of the widest text it finds in all rows for the column aCol. Tip: see the goDblClickAutoSize option to allow columns to be automatically resized when doubleClicking the column border.

procedure AutoSizeColumns;

Automatically resizes all columns by adjusting them to fit in the longest text in each column. This is a quick method of applying AutoSizeColumn() for every column in the grid.

procedure Clean; overload;

Cleans all cells in the grid, fixed or not.

procedure Clean(CleanOptions: TCleanOptions); overload;

Cleans all cells in the grid subject to the given CleanOptions. see TCleanOptions for more information. Some examples:

  • Clean all cells: grid.Clean([]); (the same as grid.clean)
  • Clean all non fixed cells: grid.Clean([gzNormal]);
  • Clean all cells but don't touch grid column headers: Grid.Clean[gzNormal, gzFixedRows]);

procedure Clean(StartCol,StartRow,EndCol,EndRow: integer; CleanOptions:TCleanOptions); overload;

does the same as Clean(CleanOptions:TCleanOptions) but restricted to the given StartCol,StartRow,EndCol and EndRow. Examples:

  • Clean column index 4 to 6 but don't touch grid column headers: many variations, Grid.Clean(4,Grid.FixedRows,6,Grid.RowCount-1,[]); Grid.Clean(4,0,6,Grid,RowCount-1, [gzNormal]); etc.

procedure Clean(aRect: TRect; CleanOptions: TCleanOptions); overload;

The same as Clean(StartCol,StartRow,EndCol,EndRow, CleanOptions), just taking a TRect instead of individual cell coordinates. Useful to clean the selection: grid.Clean(Grid.Selection,[]);

property Cols[index: Integer]: TStrings read GetCols write SetCols;

Get/set a list of strings from/to the given grid's column index starting from row index 0 to RowCount-1.

Beispiele
  • Set Example: Set the content of the third column in the grid from a ListBox:
Grid.Cols[2] := ListBox1.Items;
  • Get Example: Set the content of a Listbox from the grid's column index 4:
procedure TForm1.FillListBox1;
var 
  StrTempList: TStringList;
begin
  StrTempList := TStringList(Grid.Cols[4]);
  if StrTempList<>nil then begin
    ListBox1.Items.Assign(StrTempList);
    StrTempList.Free;
  end;
end;   
Anmerkungen

This property works in a different way in Lazarus than in Delphi when getting the data from the grid. In Lazarus a temporary TStringList object is created for retrieving the column content. It is the responsibility of the user to free this object after use.

This means also that changes in the returned list will not affect the grids content or layout.

See the Get Example.

property Rows[index: Integer]: TStrings read GetRows write SetRows;

Get/set a list of strings from/to the given grid's row index starting from column index 0 to column ColCount-1.

Anmerkungen

This property works in a different way in Lazarus than in Delphi when getting the data from the grid. In Lazarus a temporary TStringList object is created for retrieving the row content. It is the responsibility of the user to free this object after use.

This means also that changes in the returned list will not affect the grids content or layout.

Beispiele
  • Set Example: Set the content of the third row in the grid from a ListBox:
Grid.Rows[2] := ListBox1.Items;
  • Get Example: Set the content of a Listbox from the grid's row index 4:
procedure TForm1.FillListBox1;
var 
  StrTempList: TStringList;
begin
  StrTempList := TStringList(Grid.Rows[4]);
  if StrTempList<>nil then begin
    ListBox1.Items.Assign(StrTempList);
    StrTempList.Free;
  end;
end;  
  • Not Working Example and Fix: Retrieved string list is read only
// this will not work and will cause memory leak
// because returned StringList is not being freed
Grid.Rows[1].CommaText := '1,2,3,4,5';
Grid.Rows[2].Text := 'a'+#13#10+'s'+#13#10+'d'+#13#10+'f'+#13#10+'g'; 

// fixing the first case
Lst:=TStringList.Create;
Lst.CommaText := '1,2,3,4,5';
Grid.Rows[1] := Lst;
Lst.Free;

property UseXORFeatures;

Boolesche Eigenschaft, Vorgabewert: false;

This property controls how the dotted focus rectangle appears in the grid. When true, the rectangle is painted using the XOR raster operation. This allow us to see the focus rectangle no matter what the cells' background color is. When false, the user can control the color of the dotted focus rectangle using the FocusColor property

It also controls the look of the column/row resizing. When true, a line shows visually the size that the the column or row will have if the user ends the operation. When false, the column or row resizing takes effect just as the user drags the mouse.

Grids Howto

Customizing grids

Grid are components derived from TCustomControl class, and don't have a native widget associated to them which means that grids are not restricted by the look of current interface theme. This can be equally considered an advantage but also a disadvantage because usually programmers want to create a uniform-look application. The good news is that Lazarus grids are flexible enough to get something from both worlds, programmers can easily make grids to look like other native controls or they can customize the grid to the finest detail so they can obtain almost the same look in any platform or widget interface, that is, with the exception of scrollbars because their look is still determined by current theme.

Eigenschaften und Ereignisse für customizing grids

Some properties can affect the way the grid looks by acting when the cell is about to be painted in PrepareCanvas/OnPrepareCanvas by changing default canvas properties like brush color or font. Following is a list of such properties:

  • AlternateColor. With this the user can change the background color appears on alternated rows. This is to allow easy reading off of grid rows data.
  • Color. This sets the primary color used to draw non fixed cells background.
  • FixedColor. This is the color used to draw fixed cells background.
  • Flat. this eliminates the 3d look of fixed cells.
  • TitleFont. Font used to draw the text in fixed cells.
  • TitleStyle. This property changes the 3D look of fixed cells, there are 3 settings:
    • tsLazarus. This is the default look
    • tsNative. This tries to set a look that is in concordance with current widgetset theme.
    • tsStandard. This style is a more contrasted look, like delphi grids.
  • AltColorStartNormal. boolean, if true alternate color is always in the second row after fixed rows, the first row after fixed rows will be always color, if false default color is set to the first row as if there were no fixed rows.
  • BorderColor. This sets the grid's border color used when Flat:=True and BorderStyle:=bsSingle;
  • EditorBorderStyle. If set to bsNone under windows the cell editors will not have the border, like in delphi, set to bsSingle by default because the border can be theme specific in some widgetsets and to allow a uniform look.
  • FocusColor. The color used to draw the current focused cell if UseXORFeatures is not set, by default this is clRed.
  • FocusRectVisible. turns on/off the drawing of focused cell.
  • GridLineColor. color of grid lines in non fixed area.
  • GridLineStyle. Pen style used to draw lines in non fixed area, possible choices are: psSolid, psDash, psDot, psDashDot, psDashDotDot, psinsideFrame, psPattern,psClear. default is psSolid.
  • SelectedColor. Color used to draw cell background on selected cells.
  • UseXORFeatures. If set, focus rect is drawn using XOR mode so it should make visible the focus rect in combination with any cell color ackground. It also affects the moving columns look.
  • DefaultDrawing. boolean. Normally the grids prepare the grid canvas using some properties according to the kind of cell is being painted. If user write an OnDrawCell event handler, DefaultDrawing if set also paints the cell background, if user is drawing fully the cell is better turn off this property so painting is not duplicated. In a StringGrid if DefaultDrawing is set it draws the text in each cell.
  • AutoAdvance. where the cell cursor will go when pressing enter or tab/shift tab, or after editing.
  • ExtendedColSizing. If true user can resize columns not just at the headers but along the columns height.

Other properties that also affect the grids look.

Options. Options property is a set with some elements to enable diverse functionality but some are related directly with grid's look. This options can be set at designtime or runtime.

  • goFixedVertLine, goFixedHorzLine it draws a vertical or horizontal line respectively delimiting cells or columns in fixed area, active by default.
  • goVertLine, goHorzLine the same as previous, but for normal browseable area. A listbox can be simulated with a grid by unsetting both of this elements.
  • goDrawFocusSelected if this element is enabled a selection background is painted in focused cell in addition to focused dotted rectangle (note this doesn't work yet when goRowSelect option is set, in such case row is always painted as if goDrawFocusSelected is set)
  • goRowSelect select the full row instead of individual cells
  • goFixedRowNumbering if set, grid will do numbering of rows in first fixed column
  • goHeaderHotTracking if set, the grid will try to show a different look when the mouse cursor is overing any fixed cell. In order for this to work, desired cell zone needs to be enabled with property HeaderHotZones. Try combining this option with property TitleStyle:=tsNative to get themed hot tracking look.
  • goHeaderPushedLook if set, this element enables a pushed look when clicking any fixed cell. The zone of "pushable" cells is enabled using HeaderPusedZones property.

(write more)

Description of grid's drawing process

Like other custom controls, the grid draws itself in the paint method, in general terms the grid is drawn by painting all rows, and each row by painting it's individual cells. The process is as follow:

  • First the visible cells area is determined, each row is tested to see if it intersects the canvas clipping region, if it's ok, then visible area is painted by drawing columns of each row.
  • The column and row values are used to identify the cell that is about to be painted and again each column is tested for intersection with clippling region, if everything is ok, some additional properties like it's rectangualar extent and visual state are passed as arguments to DrawCell method.
  • As the drawing process is running, the visual state of each cell is adjusted according to grid options and position within grid. The visual state is resumed in a varible of type TGridDrawState which is a set with following elements:
    • gdSelected The cell will have a selected look.
    • gdFocused The cell will have a focused look.
    • gdFixed Cell have to be painted with fixed cell look.
    • gdHot the mouse is over this cell, so paint it with hot tracking look
    • gdPushed the cell is being clicked, paint it with pushed look
  • DrawCell. The DrawCell method is virtual and may be overriden in descendant grids to do custom drawing. The information passed to DrawCell method helps to identify the particular cell is being painted, the physical area ocuppied in screen and it's visible status. See DrawCell reference for details. For each cell following occurs:
  • PrepareCanvas. PrepareCanvas method is called, in this method, If DefaultDrawing property es set, the grid canvas is setup with default properties for brush and font based on current visual state and on several design and runtime properties, the text alignment is set to match programmer selection in custom columns if they exists. If DefaultDrawing is false, brush color is set to clWindow and Font color to clWindowText, the text alignment is set with grids defaultTextStyle property value.
  • OnPrepareCanvas. If programmer wrote a event handler for OnPrepareCanvas event, it's called at this point. This event can be used for doing simple customization like changing cell's background color, font's properties like color, fontface and style, Text layout like different combinations of left, center, top, bottom, right alignment, etc. Any change made to the canvas in this event would be lost, because the next cell drawing will reset canvas again to a default state. So it's safe doing changes only for particular cell or cells and forget about it for the rest. Using this event sometimes helps to avoid uusing OnDrawCell grid event where users would be forced to duplicate the grid's drawing code. todo: samples of what can be made and what to leave for OnDrawCell?...
  • OnDrawCell. Next if no handler for OnDrawCell event was specified, the grid calls the DefaultDrawCell method which simply paints the cell background using current canvas brush color and style, if OnDrawCell handler exists, the grid first paints the cell background but only if DefaultDrawing property was set, then it calls OnDrawCell event to do custom cell painting. Usually programmers want to do custom drawing only for particular cells, but standard drawing for others, in this case, they can restrict custom operation to certain cell or cells by looking into ACol,ARow and AState arguments, and for other cells simply call DefaultDrawCell method and let the grid to take care of it.
  • Text. At this point (only for TStringGrid) if DefaultDrawing property is true, the cell's text content is painted.
  • Grid lines. The last step for each cell is to paint the grid lines if grid options goVertLine,goHorzLine, goFixedVertLine and goFixedHorzLine are specified the cell grid is drawn at this point. Grids with only rows or only cols can be obtained by changing these options. If programmer elected to have a "themed" look it's done at this point also (see property TitleStyle).
  • FocusRect. When all columns of current row have been painted it's time to draw the focus rectangle for current selected cell or for the whole row if goRowSelect option is set.

Grid's cell selection

Grid's current (focused) cell (or row) can be changed of location using keyboard, mouse or through code, in order a cell focus can be successfully changed to another position, target position need to be tested if it's allowed to receive cell focus. When using keyboard, the property AutoAdvance takes part of the process by finding what should be the next focused cell. When using mouse by clicking or by code, the target cell needs to be allowed to receive focus or currently focused cell will not move.

The way the grid knows what cell is focusable is by calling function SelectCell, if this function returns true, then the target cell identified with arguments acol and arow is focusable, current implementation in TCustomGrid simply returns true. TCustomDrawGrid and hence TDrawGrid and TStringGrid override this method to check first if cell is any wider than 0, normally you don't want a 0 width cell selected so a cell with this characteristics is skipped automatically in the process to find a suitable cell. The other thing the overriden method SelectCell does is to call the user configurable event OnSelectCell, this event receive as arguments, the cell coordinates and a default result value of true always.

Once a cell is known to be focusable and for sure a movement will take place, first method BeforeMoveSelection is called which in turns triggers OnBeforeSelection event, this method's arguments are the coordinates the new focused cell will have, at this point any visible editor is hidden too. the "before" word means that selection is not yet changed and current focused coordinates can be accessed with grid.Col and grid.Row properties.

After that, the internal focused cell coordinates are changed and then method MoveSelection is called, this method purpose is to trigger OnSelection event if set, this is a notification that focused cell has, by this time, already changed and cell coordinates are now available through grid.row and grid.col properties.

Note that is not good to use OnSelectCell event to detect cell focus changes, this event will be triggered several times even for the same cell in the process of finding a suitable cell. Is better to use OnBeforeSelection or OnSelection events for this purpose.

Several differences with delphi have been identified

  • In Lazarus TCustomGrid.DrawCell method is not abstract and it's default implementation do basic cell background filling.
  • In delphi, the cell's text is drawn before entering the OnDrawCell event see bug report #9619).
  • SelectCell and OnSelectCell behaviour is probably different, can't really comment on the differences but in lazarus is they are used in functinality like AutoAdvance which afaik doesn't exist in delphi.

When above customizaton is not enough, derived grids

Derivd grids usually have to override following methods:
DrawAllRows: Draws all visible rows.
DrawRow: Draw All Cells in a Row.
DrawRow draws all cells in the row by first checking if cell is withing clipping region, and only draws the cell if it is.
DrawCell:
DrawCellGrid:
DrawCellText:
DrawFocusRect:
(write me).


Ablauf der Methodenaufrufe in TCustomGrid.Paint

Die folgenden Auflistungen sollen den Ablauf zum Zeichnen eines TCustomGrid-Nachkommen vereinfacht darstellen. Die verschachtelten Aufzählungen bezeichnen jeweils Methodenaufrufe innerhalb eines Grids. Bei der Entwicklung von Nachkommen von TCustomGrid, kann so die richtige Methode zum Überschreiben leichter gefunden werden.

  • DrawEdges: Zeichnet den äußeren Rahmen des Grids.
  • DrawAllRows (virtual): Hier werden alle sichtbaren Zellen des Gitters gezeichnet.
    • DrawRow (virtual): Zeichnet alle sichtbaren Zellen einer Zeile. Wird für jede Gitterzeile im aktuellen Sichtfenster einmal ausgeführt.
      • DrawCell (virtual): Wird zunächst für jede 'normale' (also nicht fixierte) Zelle der Zeile ausgeführt.
        • PrepareCanvas (virtual): Setzt die Eigenschaften der Zeichenfläche für das Zeichnen der aktuellen Zelle.
        • DrawFillRect: Zeichnet den Hintergrund der Zelle im mit PrepareCanvas eingestellten Stil.
        • DrawCellGrid (virtual): Zeichnet die Begrenzungen der Zelle.
      • DrawFocusRect (virtual): In TCustomGrid hat diese Methode keine Funktion. In abeleiteten Grid-Klassen wird hier das Focus-Rechteck innerhalb der aktiven Zelle gezeichnet.
      • DrawCell (virtual): (siehe oben) Abschließend wird DrawCell für jede fixierte Zelle im Sichtbereich der Zeile einmal ausgeführt.
  • DrawColRowMoving: Wird nur während des Verschiebens einer Zeile/Spalte ausgeführt. Es zeichnet die Linie mit welcher die neue Position der verschobenen Zeile/Spalte angedeutet wird.
  • DrawBorder: Wenn nötig (Flat=TRUE und BorderStyle=bsSingle), wird hier ein innerer Rand gezeichnet.

Weitere Methoden zum Zeichnen in TCustomGrid

Die folgenden Methoden werden zwar in TCustomGrid deklariert, hier aber nicht direkt aufgerufen. Sie werden von abgeleiteten Klassen ausgeführt um den Zelleninhalt zu zeichnen.

  • DrawCellText (virtual): Zeichnet den im Parameter übergebenen Text in die Zelle. Verwendet zur Formatierung die in Canvas.TextStyle aktiven Einstellungen (siehe PrepareCanvas).


  • DrawThemedCell (virtual): Wird nur für fixierte Zellen verwendet, wenn TitleStyle=tsNative. Zeichnet den Hintergrund der Zelle mit den Einstellungen der ThemeServices.


  • DrawColumnText (virtual): Wird nur für die Zellen der Spaltenüberschriften ausgeführt
    • DrawColumnTitleImage: Wenn eine TitleImageList zugewiesen und in Columns.Title[x].Title.ImageIndex ein gültiger Wert eingetragen ist, wird das entsprechende Icon gezeichnet.
    • DrawCellText : (siehe oben)


  • DrawTextInCell (virtual): Wird nur für 'normale' (nicht fixierte) Zellen verwendet. In TCustomGrid hat diese Methode keine Funktion. In abeleiteten Grid-Klassen wird hier der Zelleninhalt in die Zelle gezeichnet. In TStringGrid ruft diese Methode wiederum DrawCellText (siehe oben) auf.

Erweiterung des Zeichenfunktionen in TCustomDrawGrid

Wie man sieht, Zeichnet die Basisklasse TCustomGrid keinen Inhalt in das Grid. Dies geschieht in TCustomDrawGrid. Hier wird die Methode DrawCell folgendermaßen überschrieben.

  • DrawCell (override):
    • PrepareCanvas: Aufruf der von TCustomGridgeerbten Methode
    • DefaultDrawCell (virtual): Ist eine Ereignisbehandlung für OnDrawCell zugewiesen, wird diese Methode nicht ausgeführt. Sonst
      • DrawFillRect / DrawThemedCell (von TCustomGrid): Zeichnet den Hintergrund der Zelle. Ist TitleStyle=tsNative, wird der Hintergrund für fixierte Zellen mit DrawThemedCell gezeichnet.
      • DrawCellAutonumbering (virtual): Nur, wenn goFixedAutonumbering in Options wird in der ersten fixierten Spalte mit TCustomGrid.DrawCellText die Numerierung gezeichnet.
      • DrawColumnText (von TCustomGrid): Wird nur für die Zellen der Spaltenüberschriften ausgeführt. Siehe Weitere Methoden zum Zeichnen in TCustomGrid.
      • DrawTextInCell (von TCustomGrid): Wird nur für 'normale' (nicht fixierte) Zellen ausgeführt. Siehe Weitere Methoden zum Zeichnen in TCustomGrid.
    • DrawCellGrid (virtual): Zeichnet die Begrenzungen der Zelle.

Operationen

Save and Retrieve Grid Content

The SaveToFile procedure allows you save the TStringGrid format, attributes & values to a XML file. Previously you must set the SaveOptios property as follow:

soDesign:     Save & Load ColCount,RowCount,FixedCols,FixedRows,
              ColWidths, RowHeights and Options (TCustomGrid)
soPosition:   Save & Load Scroll Position, Row, Col and Selection (TCustomGrid)
soAttributes: Save & Load Colors, Text Alignment & Layout, etc. (TCustomDrawGrid)
soContent:    Save & Load Text (TCustomStringGrid)

The LoadFromFile procedure allows you to load into a StringGrid instance, attributes, formats & values, from a XML file. First, you must set some of this options of the SaveOptios property (on your TStringGrid instance) SaveOptions

 soDesign:     Save & Load ColCount,RowCount,FixedCols,FixedRows,
               ColWidths, RowHeights and Options (TCustomGrid)
 soPosition:   Save & Load Scroll Position, Row, Col and Selection (TCustomGrid)
 soAttributes: Save & Load Colors, Text Alignment & Layout, etc. (TCustomDrawGrid)
 soContent:    Save & Load Text (TCustomStringGrid)

Beispiel: 1) First Open a new project "Application". 2) Put an empty TStringGrid. 3) Put a TButton. 4) Put a TOpenDialog 5) Add the event OnCreate for the Form 5) Add the event OnClick for the Button

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Grids,
  Buttons, StdCtrls, XMLCfg;

type

  { TForm1 }
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure Form1Create(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 

var
  Form1: TForm1; 

implementation

{ TForm1 }

procedure TForm1.Form1Create(Sender: TObject);
begin
 //sets the SaveOptions at creation time of the form 
 stringgrid1.SaveOptions := [soDesign,soPosition,soAttributes,soContent];
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
 //Ask if thew Execute method of the OpenDialog was launched 
 //when this occurs, the user selects an XML file to Load
 //wich name was stored in the FileName prop.

 if opendialog1.Execute then
 Begin
   //Clear the grid 
   StringGrid1.Clear;
   //Load the XML
   StringGrid1.LoadFromFile(OpenDialog1.FileName);
   //Refresh the Grid
   StringGrid1.Refresh;
 End;
end;

initialization
  {$I unit1.lrs}

end.

Die Beispiel XML-Datei: (Kopieren sie den text unterhalb in eine .txt Datei. Vergessen sie den XML header nicht :-))

''<?xml version="1.0"?>
<CONFIG>
  <grid version="3">
    <saveoptions create="True" position="True" content="True"/>
    <design columncount="2" rowcount="5" fixedcols="1" fixedrows="1" defaultcolwidth="64" defaultRowHeight="20">
      <options>
        <goFixedVertLine value="True"/>
        <goFixedHorzLine value="True"/>
        <goVertLine value="True"/>
        <goHorzLine value="True"/>
        <goRangeSelect value="True"/>
        <goDrawFocusSelected value="False"/>
        <goRowSizing value="False"/>
        <goColSizing value="False"/>
        <goRowMoving value="False"/>
        <goColMoving value="False"/>
        <goEditing value="False"/>
        <goTabs value="False"/>
        <goRowSelect value="False"/>
        <goAlwaysShowEditor value="False"/>
        <goThumbTracking value="False"/>
        <goColSpanning value="False"/>
        <goRelaxedRowSelect value="False"/>
        <goDblClickAutoSize value="False"/>
        <goSmoothScroll value="True"/>
      </options>
    </design>
    <position topleftcol="1" topleftrow="1" col="1" row="1">
      <selection left="1" top="1" right="1" bottom="1"/>
    </position>
    <content>
      <cells cellcount="10">
        <cell1 column="0" row="0" text="Title Col1"/>
        <cell2 column="0" row="1" text="value(1.1)"/>
        <cell3 column="0" row="2" text="value(2.1)"/>
        <cell4 column="0" row="3" text="value(3.1)"/>
        <cell5 column="0" row="4" text="value(4.1)"/>
        <cell6 column="1" row="0" text="Title Col2"/>
        <cell7 column="1" row="1" text="value(1.2)"/>
        <cell8 column="1" row="2" text="value(2.2)"/>
        <cell9 column="1" row="3" text="value(3.2)"/>
        <cell10 column="1" row="4" text="value(4.2)"/>
      </cells>
    </content>
  </grid>
</CONFIG>''

--Raditz 21:06, 11 Jan 2006 (CET) from ARGENTINA

Grid Cell Editors

The grid uses cell editors to change the content of cells. For a specilized grid like TStringGrid, the editor is the habitual single line text editor control, sometimes it's desireable to have other means to enter information. For example,

to call the open file dialog to find the location of a file so the user doesn't have to type the full path manually, if 

the text in the cell represents a date, it would be more friendly if we could popup a calendar so we can choose a specific date easily. Sometimes the information the user should enter in a cell is restricted to a limited list of words, in this case typing the information directly might introduce errors and validating routines might need to be implemented, we can avoid this by using a cell editor that present the user a list with only the legal values. This is also the case of generic grids like TDrawGrid where user have to have some kind of structure to hold the data that will be shown in the grid, in this situation, the information that is entered in the cell editor updates the internal structure to reflect the changes in the grid.

Builtin cell editors

The grids.pas unit already include some of the most used cell editors ready for use in grids, there is also the posibility to create new cell editors (custom cell editors) if the builtin editors are not appropiated for a specific tasks.

The builtin cell editors are Button, Edit, and Picklist.

Using cell editors

Users can specify what editor will be used for a cell using one of two methods.

  1. Using a custom column and selecting the ButtonStyle property of column. In this method the user can select the style of

the editor that will be shown. Available values are: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn

  1. Using OnSelectEditor grid event, here the user specify in the Editor parameter which editor to use for a cell identified

for column aCol and row ARow in a TCustomDrawGrid derived grid or TColumn in TCustomDBGrid. For this purpose there is a useful public function of grids, EditorByStyle() that takes as parameter one of the following values: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn. This method takes precedence over the first one using custom columns. A Custom cell editor can be specified here. This event is also the place to setup the editor with values specific to the cell, row or column.

Description of editor styles

The following is the description of each editor style, they are enumeated values of type TColumnButtonStyle and so they are prefixed by 'cbs'. This type was used so it remains compatible with delphi's dbgrid.

  • cbsAuto
This is the default editor style for TCustomGrid derived grids. The actual editor class that will be used to edit the

cell content, depends on several factors. For TCustomGrids it uses a TStringCelleditor class derived from TCustomMaskEdit,

this editor is speciallized to edit single line strings. It is then used in TStringGrid and TDrawGrid by default. When 

using Custom Columns and programmer filled the Column's PickList property, this behaves as if cbsPickList editor style was set. For a TCustomDBGrid that have a field of type boolean, behaves as if cbsCheckBoxColumn editor style was specified. This is the recomended value for Custom Cell Editors TODO: related OnEditingDone.

  • cbsEllipsis
This editor style is the most generic one. When used, a button appears in the editing cell, programmers could use the

OnEditButtonClick grid event to detect when user has pressed the button and take any action was programmed for such cell. For example a programmer could use this editor style to pop up a calendar dialog so user can easily pick a specific date, another could be to show a file open dialog to find files, a calculator so user can enter the numeric result of calcs, etc.

OnEditButtonClick is just a notification, so to find out which cell a button has been clicked, take a look at grid.Row

and grid.Col properties.

A DbGrid has specific properties to retrieve the active column or field and because this event occurs in active record,

it could update the information in active field.

This editor style is implemented using TButtonCellEditor a direct descendant of TButton.
  • cbsNone
This editor style instruct the grid to not use any editor for a specific cell or column, it behaves then, as if the grid

is readonly for such cell or column.

  • cbsPickList
Used to present the user a list of values that can be entered, this editor style is implemented using

TPickListCellEditor a component derived from TCustomComboBox. The list of values that are shown, are filled in two ways depending of the method used to select the editor style.

  1. When using custom columns, programmers can enter a list of values using the column's PickList property. [FOR BEGINNERS:

TODO: exact procedure to edit the list]

  1. In OnSelectEditor, programmers get the TPickListCellEditor instance using the function EditorByStyle(cbsPickList), an

example would be: var Lst:TPickListCellEditor; begin [...] Lst:=TPickListCellEditor(EditorByStyle(cbsPickList)); Lst.clear; Lst.Items.add('One');lst.items.add('Two'); Editor:=Lst; end;

The value in a TStringGrid grid will automatically reflect the value selected, if necessary the programmer could detect

the moment the value is selected by writing an event handler for grid's OnPickListSelect event, so additional steps can be taken for example, to process the new value. TODO: related OnEditingDone.

  • cbsCheckboxColumn
This editor style is at the moment only available in TDbGrid. This editor style can be useful when field content

associated with the column are restricted to a pair of values, for example, yes-no, true-false, on-off, 1-0, etc. Instead of forcing the user to type the values for this kind of field in a StringCellEditor or to choose one from a list, cbsCheckboxColumn is used to modify the field content of a column by using a checkbox representation that user can toggle by using a mouse click or pressing the SPACE key.

If columns' ButtonStyle property is set to cbsAuto and DbGrid detects that the field associated to the column is a

boolean field, then the grid use this editor style automatically, this automatic selection can be disabled or enabled using dbgrid's OptionsExtra property, setting dgeCheckboxColumn element to false disable this feature.

The values that are used to recognize the checked or unchecked states are set in column's properties ValueChecked and

ValueUnchecked.

In any moment, the field value can be in one to three states: Unchecked, checked or grayed. Internally this states are

identified by the following values of type TDBGridCheckBoxState: gcbpUnChecked, gcbpChecked and gcbpGrayed.

This editor style doesn't use real TCheckbox components to handle user interaction, the visual representation is given

by three builtin bitmap images that corresponds to the possible states of checkbox. The used bitmaps can be customized by writing a handler for DBGrid event OnUserCheckboxBitmap, the handler of this event gets the state of the checkbox in parameter CheckedState of type TDbGridCheckboxState and a bitmap parameter that programmer could use to specify custom bitmaps.

Beispiel: How to set a custom cell editor

Siehe lazarus/examples/gridcelleditor/gridcelleditor.lpi

Wie scrollt man ein Grid in "Echtzeit" (während man den Scrollbalken per Maus bewegt)

Wenn man ein Grid scrollt, indem man den Scrollbalken per Maus bewegt, dann scrollt das Grid per Default nicht "in Echtzeit", sondern erst, wenn man die Maus los lässt, "springt" das Grid an seine neue Position. Man kann ein scrollen "in Echtzeit" aktivieren, in dem man Option goThumbTracking hinzufügt.

Beispiel:

 StringGrid1.Options:=StringGrid1.Options + [goThumbTracking];

Leider ist diese Option weder dokumentiert in <lazarus-installdir>\lcl\grids.pas (ver 2.0.6) noch in https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tgridoptions.html

Todo

  • TInplaceEditor Unterstützung

Bekannte Probleme

29-März-2005:

  • mouse autoedit
    • linux: clicking a selected cell doesn't trigger the autoedit function (the editor lost focus inmmediatelly)
    • windows: it should work only if the grid has the focus, if not it should focus and a second click should autoedit (cannot detect if the grid was previously focused or not)
  • ColumnWidths: linux, windows: dbgrid start with default column widths instead of calculated ones (it's disabled because early canvas creation causes strange effects if the parent is a notebook page)
  • Resizing Columns: linux, windows. Resizing a column should not hide the editor (specially in dbgrid if we are inserting)
  • MouseWheel:
    • linux: mousewheel doesn't work as it should, (seems it's calling the default mousewheel handler)
    • windows: patch was sent.
  • Double painting: Apparently dbgrid paints the cell background twice (once with fillrect and once in textRect)
  • AutoFillColumns: sometimes the clientwidth is evaluated incorrectly (sometimes there are phantom scrollbars)