Difference between revisions of "Grids Reference Page"

From Free Pascal wiki
Jump to navigationJump to search
(→‎Differences between Lazarus and Delphi grids: became a desired objective etc)
Line 55: Line 55:
 
The current grids components present several differences with respect to the delphi's grids. This is mainly because the lazarus grids were created from scratch primarily without trying to make them fully compatible.  
 
The current grids components present several differences with respect to the delphi's grids. This is mainly because the lazarus grids were created from scratch primarily without trying to make them fully compatible.  
  
At a later stage, the compatibility with delphi's grids become a desired objective and the grids starting to follow more closely the delphi grid's interface, but still without doing strong efforts to make every single property or method to match the delphi counterpart.
+
At a later stage, compatibility with delphi's grids became a desired objective and the grids starting to conform more closely the delphi grid's interface, but even then this was done without a strong effort to make every single property or method match it's delphi counterpart.
Also, because the grid's internals are much different some things are not possible or need to be done in a different way in the lazarus' grids.
+
Also, because the grid's internals are very different some things are not possible or need to be done in a different way in the lazarus' grids.
As the grids were evolved, greater compatibility becomes and is a desired.  
+
As the grids have evolved, greater compatibility has been achieved and this is desireable.  
 
=== Differences ===
 
=== Differences ===
In this place the known differences will be enumerated in no special order.
+
Here the known differences will be listed, in no special order.
 
*Cell Editors  
 
*Cell Editors  
 
*Designtime Behaviour
 
*Designtime Behaviour

Revision as of 00:18, 10 May 2007

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

Objective

This text will try to show the user some aspects of the grids components in lazarus. Also is intended to serve as a guide for users who never used grids before (as experienced users generally only need a reference for new functionality). So this text will try to reach the following objectives:

  1. To introduce the grids components to people with little or not previous delphi contact.
  2. To document the differences with respect to delphi grids components.
  3. To document the new functionality in lazarus grids.
  4. Create reference and examples for the components.

Overview

A grid is a component that provides a mean for display data in tabular format. The most obvious characteristic of grids is that they are composed of cells forming rows and columns.

The type of information that can be shown in a grid is very ample, mainly depends on what the user wants to show, generally this information is translated in text, colors, images or one combination of them.

Given the great variety of information that can be represented, a series of grids exits whose purpose is to facilitate to the user showing a specific kind of information.

Inheritence Tree

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

A Starting Example

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" example using the TStringGrid Component.

  1. Create a new application.
    • From the main menu select: project->New Project
    • In the Create New Project dialog press the "Create Button"
    • A new empty form will be shown.
  2. Place a grid on the form
    • From the component palette select the "additional" tab
    • Click over the TStringGrid icon []
    • Click over the form, near to the top left corner. A new empty grid appears.
  3. Place a button on the form
    • From the component palette select the "Standard" tab
    • Click over the TButton icon []
    • Click over a empty area of the form. A new button appears.
  4. Doubleclick the button from the step 3, and write down the following code in the click button handler:
    • Stringgrid1.Cells[1,1] := 'Hi World!';
  5. Run the program by clicking the play icon []
    • by pressing the button1, the hello world text should appear in cell column 1, row 1.

Differences between Lazarus and Delphi grids

The current grids components present several differences with respect to the delphi's grids. This is mainly because the lazarus grids were created from scratch primarily without trying to make them fully compatible.

At a later stage, compatibility with delphi's grids became a desired objective and the grids starting to conform more closely the delphi grid's interface, but even then this was done without a strong effort to make every single property or method match it's delphi counterpart. Also, because the grid's internals are very different some things are not possible or need to be done in a different way in the lazarus' grids. As the grids have evolved, greater compatibility has been achieved and this is desireable.

Differences

Here the known differences will be listed, in no special order.

  • Cell Editors
  • Designtime Behaviour

New Functionality

  • Columns
  • Events
  • Grid Editor

Adjustments for improving Delphi grids compatibility

Here is a list of properties and adjustments that can be made in order to make Lazarus grids look or behave similar to Delphi grids. These adjustments are based in a newly created grid. Entries tagged with [Code] need to be set in code, [Design] entries can be changed at design time.

  • [Design] TitleStyle:=tsStandard;
  • [Design] DefaultRowHeight:=24;
  • [Code] EditorBorderStyle:=bsNone; // this might work only on windows.
  • [Code] UseXORFatures:=true;
  • [Code] AllowOutBoundClicks:=False; (r10992 or later)
  • [Code] FastEditing:=False; (supported in dbgrid. StringGrid req. r10992 or later)
  • [Design] AutoAdvance:=aaNone;

Grids Reference

Information

The starting point for reference about TCustomGrid, TDrawGrid, TCustomDrawGrid, TCustomStringGrid and TStringGrid is the unit grids.pas reference

For TCustomDBGrid and TDBgrid is the unit dbgrids.pas reference

Currently there are not too much content in these links, due partly, to the lack of a tool that allows easily maintaining its content, but such tool is under construction and eventually the gaps will be filled.

In general, any Delphi referece about the grids should help to use Lazarus grids (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, this place will be used to document things that doesn't work the same as in Delphi or that is new functionality.

[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 serves as the base for 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.

Examples
  • 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;   
Notes.

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.

Notes.

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.

Examples
  • 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;

Boolean property, default value: 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

Look and Feel

(this is a collection of notes to write this section, is not the final format)

Customizing grids look

(some properties that will be described in this section, change format later)

LOOK:

By modifying some properties user can adapt the grids to look different than default.
properties that can be changed at design time:

AlternateColor: With this the user can change the background color appears on alternated rows. This is to allow easy lecture 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 tries a more contrasted look, like delphi grids.

at runtime we have many other possiblities:
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 draw using XOR mode so it should make visible the focus rect in any cell color background. it affects the look of moving column.

Customizing look:
(this information is <for customizing the grid without writing derived ones)

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.

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.
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.
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.

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.

(this information is for writing 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).

Customizing grids use

FEEL

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.
OnSelectCell:
(write me)

Operations

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)

Example: 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.

The sample xml file: (Copy the text below into a txt file Don't forget put the xml header :-))

''<?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
  2. 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]
  2. 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.

Example: How to set a custom cell editor

See lazarus/examples/gridcelleditor/gridcelleditor.lpi

Todo

  • TInplaceEditor Support

known problems

29-marzo-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 is painting twice the cell background (one with fillrect and one in textRect)
  • AutoFillColumns: sometimes the clientwidth is evaluated incorrectly (sometimes there are phantom scrollbars)