Sign in Join
Wiki copytemporary

TECGrid: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Overview
22
33**TECGrid** ![](/wiki-images/8/8c/Ecgrid.png) is a lightweight grid component. It does not contain any strings, it has no [[TDataSource|DataSource]] connection and its is not possible to custom-draw each cell. Therefore it's not alternative to [[TStringGrid]], [[TDBGrid]] nor [[TDrawGrid]]. It is designed to show content of any data structure and all displayed strings are taken from OnGetHeaderText and OnGetDataCellText events. It features bi-directional mode, fixed columns, fixed rows, column moving, column sizing, various fixed-cell styles and many others, described below.
44
55![](/wiki-images/1/19/Tecgrid.png)
66
77TECGrid is part of [[Eye-Candy Controls]] (shortly ECControls or EC-Controls) set of visual controls written for Lazarus. Their design is based on Themes, therefore its look is very native everywhere, no matter what widgetset you use.
88
99TECGrid is installed to the tab EC-C on the Lazarus component palette.
1010
1111Each release is announced on Lazarus Forum in section Third Party Announcements. There are always attached files `README.txt` (list of all known issues) and `CHANGELOG.txt` (list of all changes from previous release).
1212
1313### License
1414
1515GNU Lesser General Public License 2.0 with linking exception (a.k.a. Modified LGPL). File ectabctrl.pas contains license header. Also, files `COPYING.modifiedLGPL.txt` and `COPYING.LGPL.txt` are bundled to each archive.
1616
1717### Author
1818
1919This component is written by Blaazen. Copyright notice and real name is mentioned in the header of the unit. You can contact author on Lazarus Forum (nickname: Blaazen) in any thread about EC-Controls. If you are logged in to forum, you can get author's e-mail or send him private message.
2020
2121### Download and Install
2222
2323See [[Eye-Candy Controls|Eye-Candy Controls#Install]]
2424
2525## Options
2626
2727### Property Options
2828
2929| Option | Description |
3030|----|----|
3131| egoAlwaysShowEditor | Editor is shown always; Grid and Column must not be egoReadOnly/ecoReadOnly |
3232| egoColMoving | Columns can be moved by mouse; 1) Except fixed columns 2) Columns can be always moved by code |
3333| egoColSizing | Columns can be resized by mouse; Column must be ecoSizing |
3434| egoDottedGrid | Grid line is dotted |
3535| egoEnlargeAlways | Column is enlarged even if Editor is not opened |
3636| egoHeaderPushedLook | Column header has pushed look when clicked |
3737| egoHilightCol | Whole column is highlighted |
3838| egoHilightRow | Whole row is highlighted |
3939| egoHorizontalLines | Show horizontal lines of grid |
4040| egoReadOnly | Grid is ReadOnly, it never opens Editor |
4141| egoScrollKeepVisible | Selection remains visible while scrolling (scrollbars/mouse wheel) |
4242| egoSortArrow | Sorting arrow in title is visible; 1) Column must be ecoSorting 2) Grid must have FixedRows\>=1 |
4343| egoTabs | Tab key goes through cells instead of other components |
4444| egoUseOrder | Array OrderedCols is defined; flag excfOrder for Load/SaveColumnsToXML is available |
4545| egoVerticalLines | Show vertical lines of grid |
4646| egoWheelScrollsGrid | Mouse wheel scrolls the grid, selection does not change (i.e. it rolls away) |
4747
4848### Other Grid Properties
4949
5050| | |
5151|----|----|
5252| AlternateColor | Color of even data rows |
5353| AlternateTint | Tint of even data rows in percents, 0 = normal color, 100 = AlternateColor |
5454| Columns | Collection of columns |
5555| FixedCols | Number of fixed columns |
5656| FixedRowHeight | Height of fixed (header) rows |
5757| FixedRows | Number of fixed (header) rows |
5858| GridLineColor | Color of grid lines (data area only) |
5959| GridLineWidth | Width of grid lines (data area only) |
6060| Images | ImageList for column headers; see Column.Title.ImageIndex property |
6161| RowHeight | Height of data rows |
6262| Style | Style of cells of fixed rows and/or fixed columns |
6363
6464### Property Column.Option
6565
6666| Option | Description |
6767|----|----|
6868| ecoCellToHint | Content of data cell is shown as a Hint (tooltip) |
6969| ecoEnlargePixels | Property EnlargeWidth means pixels, otherwise means percents |
7070| ecoReadOnly | Column is ReadOnly (never shows editor) |
7171| ecoSizing | Column can be resized by mouse; Grid must be egoColSizing |
7272| ecoSorting | Sorting arrow in title is visible; Grid must be egoSortArrow and must have FixedRows\>=1 |
7373| ecoVisible | Column is visible |
7474
7575### Property Column.Title
7676
7777| Option | Description |
7878|----|----|
7979| Alignment | Text alignment of the column header; bi-directional mode is respected |
8080| FontOptions | Font differences of the column header to Grid.Font |
8181| ImageIndex | Image displayed in the column header; taken from Grid.Images |
8282| Text | Caption of the column header; the only text that is not taken from events |
8383
8484### Other Column Properties
8585
8686| Option | Description |
8787|----|----|
8888| Alignment | Text alignment of the column; bi-directional mode is respected |
8989| Color | Background color of the column |
9090| ColorTint | Tint of background color in percents, 0 = Grid.Color/Grid.AlternateColor, 100 = Column.Color |
9191| EnlargeWidth | Increment to the column width; value means pixels or percents, depend on option ecoEnlargePixels |
9292| FontOptions | Font differences to Grid.Font |
9393| MaxWidth | Maximal width of the resizable column |
9494| MinWidth | Minimal width of the resizable column |
9595
9696## Using the Component
9797
9898### Mouse
9999
100100Left button
101101
102102Click on a data-cell always selects it and possibly opens editor (depends on options egoAlwaysShowEditor, egoReadOnly, ecoReadOnly and implementation of OnSelectEditor event).
103103
104104Click on a cell of fixed columns changes row, which in turn changes selection and possibly opens editor (see above).
105105
106106Click on a cell of fixed rows changes SortIndex if option ecoSorting of Column is set. It happens even if option egoSortArrow is not set (arrow is invisibe).
107107
108108Middle button
109109
110110Does nothing.
111111
112112Right button
113113
114114Opens context menu. Note that Grid, Column and Column.Title can have different context menu.
115115
116116Dragging and Resizing
117117
118118Dragging is realized by left mouse button. Dragging moves column on the new position (egoColMoving must be set). Fixed columns cannot be moved. Data columns cannot be moved in front of fixed columns. Shape of the mouse cursor shows if the column can be moved to the new position or not.
119119
120120Resizing is realized by left mouse button. Mouse must be pushed on the right edge of the column header (or the left edge in right-to-left BiDiMode) - when mouse cursor changes its shape. Column width can be resized between MinWidth and MaxWidth. Both Options egoColSizing and ecoSizing must be set.
121121
122122Mouse Wheel
123123
124124Wheel moves selection up/down.
125125
126126Wheel + CTRL key (exactly ssModifier) scrolls grid.
127127
128128Option egoWheelScrollsGrid reverses this behaviour.
129129
130130### Keyboard
131131
132132(Grid must be focused).
133133
134134Arrow keys change selection.
135135
136136Arrow keys + CTRL key (exactly ssModifier) scroll grid.
137137
138138Home/End keys skip to the first/last data column.
139139
140140Home/End keys + CTRL key (exactly ssModifier) skip to the first/last data row.
141141
142142PageUp/PageDown keys skip up/down by the number of visible rows.
143143
144144PageUp/PageDown keys + CTRL key (exactly ssModifier) scroll up/down by the number of visible rows.
145145
146146If option egoTabs is set, Tab key skips to the next data cell. If selection reaches the last column, it skips to the first column and the next row. Shift + Tab skips in the opposite direction.
147147
148148Enter, Space, F2, BackSpace and Delete keys open Editor (Grid/Column must not be egoReadOnly/ecoReadOnly).
149149
150150Keys 0..9 and A..Z also open Editor.
151151
152152CTRL+C copies content of the selection to the clipboard.
153153
154154### Code
155155
156-`procedure BeginUpdate; override;`
156+``` pascal
157+procedure BeginUpdate; override;
158+```
157159
158160Reduces number of calculations and repaints when multiple properties change.
159161
160-`function CellRect(ACol, ARow: Integer): TRect;`
162+``` pascal
163+function CellRect(ACol, ARow: Integer): TRect;
164+```
161165
162166Returns rectangle of the specified cell.
163167
164-`function CellRectEditor(ACol, ADataRow: Integer): TRect;`
168+``` pascal
169+function CellRectEditor(ACol, ADataRow: Integer): TRect;
170+```
165171
166172Returns corrected rectangle of the specified cell, it takes care of the GridLineWidth. Recommended for opening Editor.
167173
168-`procedure EndUpdate; override;`
174+``` pascal
175+procedure EndUpdate; override;
176+```
169177
170178Each call of BeginUpdate; must be followed by EndUpdate. All changes will be processed.
171179
172-`function IsCellFullyVisible(ACol, ARow: Integer): Boolean;`
180+``` pascal
181+function IsCellFullyVisible(ACol, ARow: Integer): Boolean;
182+```
173183
174184Returns True if specified cell is fully visible.
175185
176-`function IsCellVisible(ACol, ARow: Integer): Boolean;`
186+``` pascal
187+function IsCellVisible(ACol, ARow: Integer): Boolean;
188+```
177189
178190Returns True if specified cell is at least partially visible.
179191
180-`function IsColFullyVisible(ACol: Integer): Boolean;`
192+``` pascal
193+function IsColFullyVisible(ACol: Integer): Boolean;
194+```
181195
182196Returns True if AColl is fully visible.
183197
184-`function IsColVisible(ACol: Integer): Boolean;`
198+``` pascal
199+function IsColVisible(ACol: Integer): Boolean;
200+```
185201
186202Returns True if ACol is at least partially visible.
187203
188-`function IsRowFullyVisible(ARow: Integer): Boolean;`
204+``` pascal
205+function IsRowFullyVisible(ARow: Integer): Boolean;
206+```
189207
190208Returns True if ARow is fully visible.
191209
192-`function IsRowVisible(ARow: Integer): Boolean;`
210+``` pascal
211+function IsRowVisible(ARow: Integer): Boolean;
212+```
193213
194214Returns True if ARow is at least partially visible.
195215
196-`procedure LoadColumnsFromXML(AColumnsNode: TDOMNode; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;`\
197-`procedure LoadColumnsFromXML(AFileName: string; AColumnsNode: DOMString; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;`
216+``` pascal
217+procedure LoadColumnsFromXML(AColumnsNode: TDOMNode; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;
218+procedure LoadColumnsFromXML(AFileName: string; AColumnsNode: DOMString; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;
219+```
198220
199221Loads parameters of columns. Option egoUseOrder must be set for using the Order properties.
200222
201-`function MakeCellFullyVisible(ACol, ARow: Integer; AForceColVisible: Boolean): Boolean;`
223+``` pascal
224+function MakeCellFullyVisible(ACol, ARow: Integer; AForceColVisible: Boolean): Boolean;
225+```
202226
203227Makes specified cell visible (without selecting it). If column is invisible, it can be forced to show by AForce parameter.
204228
205-`procedure MouseToCell(AMouse: TPoint; out ACol, ARow: Integer);`
229+``` pascal
230+procedure MouseToCell(AMouse: TPoint; out ACol, ARow: Integer);
231+```
206232
207233Returns indexes of a cell placed on the coordinates AMouse.
208234
209-`procedure SaveColumnsToXML(AXMLDoc: TXMLDocument; AColumnsNode: TDOMNode; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;`\
210-`procedure SaveColumnsToXML(AFileName: string; AColumnsNode: DOMString; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;`
235+``` pascal
236+procedure SaveColumnsToXML(AXMLDoc: TXMLDocument; AColumnsNode: TDOMNode; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;
237+procedure SaveColumnsToXML(AFileName: string; AColumnsNode: DOMString; AXMLFlags: TXMLColFlags = cXMLColFlagsAll); overload;
238+```
211239
212240Saves parameters of columns.
213241
214-`procedure SaveToCSVFile(AFileName: string; ADelimiter: Char = ',';  AHeaders: Boolean = True; AVisibleColsOnly: Boolean = False);`
242+``` pascal
243+procedure SaveToCSVFile(AFileName: string; ADelimiter: Char = ','; AHeaders: Boolean = True; AVisibleColsOnly: Boolean = False);
244+```
215245
216246Saves content of the grid to the text file.
217247
218-`procedure SelectCell(ACol, ARow: Integer; ASelectEditor: TEditorSelection; AForce: Boolean = False);`
248+``` pascal
249+procedure SelectCell(ACol, ARow: Integer; ASelectEditor: TEditorSelection; AForce: Boolean = False);
250+```
219251
220252Changes selection to the cell specified by ACol and ARow. If column is invisible, it can be forced to show by AForce parameter. ASelectEditor specifies whether Editor will be opened (esNative depends on the egoAlwaysShowEditor).
221253
222-`procedure UpdateCell(ACol, ARow: Integer);`
254+``` pascal
255+procedure UpdateCell(ACol, ARow: Integer);
256+```
223257
224258Updates single cell.
225259
226-`procedure UpdateColumn(ACol: Integer; AHeader: Boolean = False; AData: Boolean = True);`
260+``` pascal
261+procedure UpdateColumn(ACol: Integer; AHeader: Boolean = False; AData: Boolean = True);
262+```
227263
228264Updates cells in column.
229265
230-`procedure UpdateRow(ARow: Integer; AFixedCols: Boolean = False; AData: Boolean = True);`
266+``` pascal
267+procedure UpdateRow(ARow: Integer; AFixedCols: Boolean = False; AData: Boolean = True);
268+```
231269
232270Updates visible cells in row.
233271
234-`procedure UpdateRowCount;`
272+``` pascal
273+procedure UpdateRowCount;
274+```
235275
236276Call if you need to change number of data rows immediately. That's because RowCount is taken from OnGetDataRowCount event.
237277
238278## Workflow
239279
240280ECGrid itself does not contain any data (except column titles) and does not provide any built-in editor. All columns must be defined, setting ColCount (as it is with TStringGrid and TDrawGrid) is not enough, this property is read-only here.
241281
242282### Displaying data
243283
244284Lets assume that data are stored in any general structure, for example TFPGObjectList. For displaying all desired data is necessary:
245285
246286- Create corresponding number of columns
247287- Implement OnGetDataCellText event for each cell (for fixed columns too)
248288- Implement OnGetDataRowCount event. Implementation of this event will return TFPGObjectList.Count (ADataRowCount parameter)
249289
250290Note: It is also possible to implement only one OnGetDataCellText event and assign it to all columns. This event has parameter AColumn, so it is possible to use **`case`**` AColumn.Index `**`of`** construction.
251291
252292### Editing data
253293
254294- Create corresponding editors
255295- Implement OnSelectEditor event
256296- Implement OnChange or OnEditingDone events of the editors
257297
258298Editing:
259299
260300- Select cell and open editor (TEdit, TSpinEdit etc.). Example of implementation of the OnSelectEditor event:
261301
262-`procedure TForm1.SelectEditor(Sender: TObject; ACol, ARow: Integer; var AEditor: TWinControl; AKey: Word);`\
263-`begin`\
264-`  SpinEdit1.Value:=``{ fill appropriate value here }``;`\
265-`  SpinEdit1.BoundsRect:=TECGrid(Sender).CellRectEditor(ACol, ARow);`\
266-`  AEditor:=SpinEdit1;`\
267-`end;`
302+``` pascal
303+procedure TForm1.SelectEditor(Sender: TObject; ACol, ARow: Integer; var AEditor: TWinControl; AKey: Word);
304+begin
305+ SpinEdit1.Value:=<span style="color: blue">{ fill appropriate value here }</span>;
306+ SpinEdit1.BoundsRect:=TECGrid(Sender).CellRectEditor(ACol, ARow);
307+ AEditor:=SpinEdit1;
308+end;
309+```
268310
269311- Change value of the editor (text, number)
270312- Editor triggers OnChange or OnEditingDone event
271313- Event will change the data
272314- Call Grid.Invalidate to repaint, new data will appear
273315
274316Note: If number of items in list is changed (some items was added or deleted), it is necessary to call Grid.UpdateRows to display changes.
275317
276318### Order of columns
277319
278320**Important:** Option egoUseOrder must be enabled for proper use of Orders. Do not change egoUseOrder during lifetime of the component.
279321
280322There are properties to get the relation of Indexes and Orders.
281323
282324Property
283325
284-`Columns[i].Order;`
326+```text
327+Columns[i].Order;
328+```
285329
286330stores initial order of each column (column with Index=i in this case), while property
287331
288-`ColOrd[i];`
332+```text
333+ColOrd[i];
334+```
289335
290336returns Index of column with Order=i.
291337
292-`CellOrd[i, j];`
338+```text
339+CellOrd[i, j];
340+```
293341
294342is the same as
295343
296-`Cell[ColOrd[i], j];.`
344+```text
345+Cell[ColOrd[i], j];.
346+```
297347
298348Example
299349
300350Lets assume that grid has three columns and their are movable (option egoColMoving is enabled).
301351
302352| Index | 0 | 1 | 2 |
303353|-------|------|----------|-------|
304354| Title | Name | Category | Count |
305355| Order | 0 | 1 | 2 |
306356
307357If the first column (Name) is edited, grid will trigger event OnSelectEditor with parameter ACol=0.
308358
309359Now assume that user will move the first column to the third position.
310360
311361| Index | 0 | 1 | 2 |
312362|-------|----------|-------|------|
313363| Title | Category | Count | Name |
314364| Order | 1 | 2 | 0 |
315365
316366If the same column is edited again, grid will trigger event OnSelectEditor, but parameter ACol=2 now, which may be difficult to maintain.
317367
318368Even more, user wants to save defined order of columns when session is over and load it back in the next session (for example restart of an application).
319369
320370For this use case, there are properties ColOrd and CellOrd.
321371
322372If we use:
323373
324-`procedure TForm1.SelectEditor(Sender: TObject; ACol, ARow: Integer; var AEditor: TWinControl; AKey: Word);`\
325-`begin`\
326-`  case ACol of`\
327-`    0: ``{ set editor for column Name }``;`\
328-`    1: ``{ set editor for column Category }``;`\
329-`    2: ``{ set editor for column Count }``;`\
330-`  end;`\
331-`end;`
374+``` pascal
375+procedure TForm1.SelectEditor(Sender: TObject; ACol, ARow: Integer; var AEditor: TWinControl; AKey: Word);
376+begin
377+ case ACol of
378+ 0: <span style="color: blue">{ set editor for column Name }</span>;
379+ 1: <span style="color: blue">{ set editor for column Category }</span>;
380+ 2: <span style="color: blue">{ set editor for column Count }</span>;
381+ end;
382+end;
383+```
332384
333385This code works well as long as the columns are in their initial order.
334386
335387But we need to select the right editors for all columns, regardless of their new poitions. We must modify the code:
336388
337-`procedure TForm1.SelectEditor(Sender: TObject; ACol, ARow: Integer; var AEditor: TWinControl; AKey: Word);`\
338-`begin`\
339-`  case ColOrd[ACol] of`\
340-`    0: ``{ set editor for column Name }``;`\
341-`    1: ``{ set editor for column Category }``;`\
342-`    2: ``{ set editor for column Count }``;`\
343-`  end;`\
344-`end;         `
389+``` pascal
390+procedure TForm1.SelectEditor(Sender: TObject; ACol, ARow: Integer; var AEditor: TWinControl; AKey: Word);
391+begin
392+ case ColOrd[ACol] of
393+ 0: <span style="color: blue">{ set editor for column Name }</span>;
394+ 1: <span style="color: blue">{ set editor for column Category }</span>;
395+ 2: <span style="color: blue">{ set editor for column Count }</span>;
396+ end;
397+end;
398+```
345399
346400There are methods LoadColumnsFromXML and SaveColumnsToXML which can store and refresh previous order of columns, but also their width and visibility (property Width and option ecoVisible).
347401
348402**Note:** When option egoUseOrder is disabled it reduces some calculations. Switch this property off if you extensively add and delete columns and/or if you disabled moving of columns (egoColMoving).
349403
350404---
351405*From the Free Pascal wiki, page "TECGrid", as it stood on 2017-03-29 after a change by Blaazen, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
352406Category: Components

Back to history