Tips and Frequently Asked Questions
Property FilterType
The grid has a new property FilterType that can be set to ftHide (default setting) or ftSuppress.
With the default setting, during a filter operation the filtered rows are effectively hidden/removed from the grid, affecting the row indexes of all rows.
When the FilterType is set to ftSuppress, the filtered rows are just made invisible and are not affecting the row indexes.
So, if you want to keep accessing grid cells with row indexes independent of filtering, the new option FilterType = ftSuppress can be used.
RowSelectCount and SelectedRowCount
RowSelectCount returns the nr. of disjunct selected rows.
SelectedRowCount returns the nr. of selected rows, irrespective of disjunct selection or normal selection or just cell selection.
Auto filtering in a grid with dynamically formatted cell values based on real cell values
Suppose a grid filled with numbers loaded from a database for example but these numbers are dynamically formatted via the OnGetDisplText event.
If we want to perform auto filtering via a filter dropdown, the filtering typically needs to be performed on the real cell data and not the formatted cell text.
In this case, the formatting that is done is to add a currency suffix €.
In the filter condition we also want to display the currency suffix but we still want the filtering to be applied on the real cell value with real value filter conditions.
The grid is filled with randome numbers between 0 and 100 and the formatting is applied via OnGetDisplText to append the currency suffix €:
procedure TForm1.FormCreate(Sender: TObject);
begin
advstringgrid1.RandomFill(false);
advstringgrid1.FilterDropDownCheck := true;
end;
procedure TForm1.AdvStringGrid1GetDisplText(Sender: TObject; ACol,
ARow: Integer; var Value: string);
begin
if (arow > 0) and (acol > 0) then
Value := Value +''€'';
end;
The filter dropdown is filled with 3 conditions and these conditions include the currency suffix:
procedure TForm1.AdvStringGrid1GetColumnFilter(Sender: TObject; Column: Integer;
Filter: TStrings);
begin
Filter.Add(''>10€ & <20€'');
Filter.Add(''>20€ & <50€'');
Filter.Add(''>50€'');
end;
First thing that needs to be done is set the real filter condition based on numbers only from the OnFilterCheck event:
procedure TForm1.AdvStringGrid1FilterCheck(Sender: TObject; Column,
ItemIndex: Integer; FriendlyName: string; var FilterCondition: string;
CheckList: TCheckListBox);
begin
//
caption := inttostr(advstringgrid1.Filter.Count);
case ItemIndex of
0: FilterCondition := ''>10 & <20'';
1: FilterCondition := ''>20 & <50'';
2: FilterCondition := ''>50'';
end;
end;
Then we need to instruct for the filter condition to take the real cell value and not the formatted value in account:
This can be done in two ways in the OnBeforeFilter event that is triggered when the filter conditions are all built-up and just before these will be applied.
Either set the filter instructions to use the real grid value or to specify the suffix:
Method 1:
procedure TForm1.AdvStringGrid1BeforeFilter(Sender: TObject);
var
i:integer;
begin
for i := 0 to advstringgrid1.Filter.Count - 1 do
advstringgrid1.Filter.Items[i].Data := fcNormal;
end;
Method 2:
procedure TForm1.AdvStringGrid1BeforeFilter(Sender: TObject);
var
i:integer;
begin
for i := 0 to advstringgrid1.Filter.Count - 1 do
advstringgrid1.Filter.Items[i].Suffix := ''€'';
end;
How to configure the grid so that a clipboard copy of a single cell value can be pasted at once to multiple cells
Initialize a default grid with:
begin
advstringgrid1.Navigation.AllowClipboardAlways := true;
advstringgrid1.Navigation.AllowClipboardShortCuts := true;
advstringgrid1.Navigation.AllowSmartClipboard := true;
advstringgrid1.Cells[1,1] := ''1'';
end;
Select cell 1,1 and select a different range of cells and paste to see it in use.
Getting checked rows in a filtered grid
In a filtered grid with a checkbox column, when you want to retrieve the rows with a selected checkbox, you need to use the real row index to get the selected state, not the display row index.
This sample code applied to a default TAdvStringGrid demonstrates this:
// initialize the grid
procedure TForm1.FormCreate(Sender: TObject);
begin
AdvStringGrid1.SaveFixedCells := false;
AdvStringGrid1.LoadFromCSV(''e:\tms\temp\cars.csv'');
AdvStringGrid1.FilterDropDownAuto := true;
AdvStringGrid1.FixedCols := 0;
AdvStringGrid1.AddCheckBoxColumn(0);
AdvStringGrid1.Options := AdvStringGrid1.Options + [goEditing];
end;
// loop through all rows and for rows with a checked checkbox, add the 2nd column cell value to a listbox:
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
state: boolean;
begin
for I := 1 to AdvStringGrid1.RowCount - 1 do
begin
AdvStringGrid1.GetCheckBoxState(0,AdvStringGrid1.RealRowIndex(i),state);
if state then // add value of cell in column 2 for selected rows to the listbox
listbox1.Items.Add(AdvStringGrid1.Cells[2,i]);
end;
end;
Associating a unique ID with search list items for TAdvSearchEdit used in TAdvStringGrid
When a TAdvSearchEdit is used as inplace editor in the grid via TAdvSearchEditEditLink, it is often desirable to have associated an unique ID with each item in the searchedit and retrieve this ID upon selection.
The following code demonstrates this for a TAdvSearchEdit used as inplace editor where the unique ID is set via the SearchListItem.Tag property and retrieved when editing ends in the grid.OnCellValidate event:
procedure TForm1.FormCreate(Sender: TObject);
var
si: TSearchListItem;
begin
// initialize the search edit
AdvSearchEditEditLink1.Columns.Add;
AdvSearchEditEditLink1.CategoryButton.Visible := false;
AdvSearchEditEditLink1.SearchButton.Visible := false;
// tag holds the unique value
si := AdvSearchEditEditLink1.Items.Add;
si.Captions[0] := ''BMW'';
si.Tag := 1;
si := AdvSearchEditEditLink1.Items.Add;
si.Captions[0] := ''Mercedes'';
si.Tag := 2;
si := AdvSearchEditEditLink1.Items.Add;
si.Captions[0] := ''Audi'';
si.Tag := 3;
end;
// use the OnGetEditorType event to specify the TAdvSearchEditEditLink as inplace editor:
procedure TForm1.AdvStringGrid1GetEditorType(Sender: TObject; ACol,
ARow: Integer; var AEditor: TEditorType);
begin
AEditor := edCustom;
AdvStringGrid1.EditLink := AdvSearchEditEditLink1;
end;
// retrieve the unique ID of the selected item in the OnCellValidate event:
procedure TForm1.AdvStringGrid1CellValidate(Sender: TObject; ACol,
ARow: Integer; var Value: string; var Valid: Boolean);
var
index,t: integer;
begin
index := (AdvSearchEditEditLink1.GetEditControl as TAdvSearchEdit).SearchList.ItemIndex;
t := (AdvSearchEditEditLink1.GetEditControl as TAdvSearchEdit).Items[index].Tag;
// the t variable holds the unique ID of the selected item via the TAdvSearchEdit
end;
How to draw text with end ellipsis when it is too long to fit in a cell
The grid has a built-in capability to draw text with end ellipsis when it is too long to fit in a cell. This is enabled for non word wrapped text when grid.EnhTextSize = true.
Example:
begin
advstringgrid1.WordWrap := false;
advstringgrid1.EnhTextSize := true;
advstringgrid1.Cells[1,1] := ''this is some long text'';
end;
Result:
How to control that at specific column positions, no column can be dropped.
With the OnAllowColumnDrop event, it is possible to control that at specific column positions, no column can be dropped.
Example:
With a TAdvGridColumnPicker connected to a grid and the code:
procedure TForm1.AdvGridColumnPicker1AllowColumnDrag(Sender: TObject;
ACol: Integer; var Allow: Boolean);
begin
Allow := ACol > 2;
end;
procedure TForm1.AdvGridColumnPicker1AllowColumnDrop(Sender: TObject;
ACol: Integer; var Allow: Boolean);
begin
Allow := ACol > 2;
end;
the first 2 normal columns cannot participate in the drag & drop to a column picker, effectively making just these 2 normal columns locked.
Programmatically show the filter dropdown for a grid column
When auto filtering is enabled, the filter is shown with: grid.ShowFilterDropDown(Column).
This way it is possible to hook-up the filter dropdown also to a hotkey for example instead of having it shown only when the mouse clicks the filter icon.
This code snippet how the Ctrl-F5 hotkey can show the filter dropdown for example:
procedure TForm1.AdvStringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (ssCtrl in Shift) and (Key = VK_F5) then
AdvStringGrid1.ShowFilterDropDown(AdvStringGrid1.Col);
end;
property grid.ControlLook.RadioRange: Boolean
Settings this property to true allows a shortened display of a radiogroup where the first radiobutton text value is shown left from the radiobutton and the last one right from the button. This allows to have only the minimum text left and right of the radiobutton group.
Code snippet:
var
sl: TStringList;
begin
AdvStringGrid1.Cells[1,0] :=''Score'';
AdvStringGrid1.Alignments[1,0] := taCenter;
sl := TStringList.Create;
sl.Add(''0'');
sl.Add('''');
sl.Add('''');
sl.Add('''');
sl.Add('''');
sl.Add(''5'');
AdvStringGrid1.ControlLook.RadioRange := true;
AdvStringGrid1.ColWidths[1] := 120;
AdvStringGrid1.AddRadio(1,1,1,0,sl);
end;
This results in:
Image drag & drop
Here you can download a demo that shows how you can
- Drag and drop of an image from one TAdvStringGrid to another TAdvStringGrid
- Drag and drop of an image from Windows Explorer to TAdvStringGrid
Changing the font color of a part of the text in a grid cell using rich text
Example:
begin
AdvStringGrid1.Cells[1,1] := ''Hello world'';
AdvStringGrid1.CellToRich(1,1, AdvStringGrid1.RichEdit);
AdvStringGrid1.RichEdit.SelStart := 6;
AdvStringGrid1.RichEdit.SelLength := 5;
AdvStringGrid1.RichEdit.SelAttributes.Color := clRed;
AdvStringGrid1.RichToCell(1,1, AdvStringGrid1.RichEdit);
end;
Using the OnHoverButtonsShow event to configure different hover buttons for different columns
To do this, enable HoverButtons and implement the OnHoverButtonsRow event that is triggered when the mouse hovers a cell. Here it is possible to control whether hover buttons are shown with the Allow event parameter and from this event, the grid.HoverButtons property can be used to customize hover buttons per cell.
The code to show different hover buttons only for column 4 and 6 is therefore:
procedure TForm1.AdvStringGrid1HoverButtonsShow(Sender: TObject; X, Y: Integer;
var Allow: Boolean);
var
c,r: integer;
begin
AdvStringGrid1.MouseToCell(x,y,c,r);
if c = 4 then
begin
// configure hover buttons here for column 4
AdvStringGrid1.HoverButtons.Buttons[0].Caption := ''A'';
AdvStringGrid1.HoverButtons.Buttons[1].Caption := ''B'';
AdvStringGrid1.HoverButtons.Column := 4;
end
else
if c = 6 then
begin
// configure hover buttons here for column 6
AdvStringGrid1.HoverButtons.Buttons[0].Caption := ''C'';
AdvStringGrid1.HoverButtons.Buttons[1].Caption := ''D'';
AdvStringGrid1.HoverButtons.Column := 6;
end
else
Allow := false;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
AdvStringGrid1.HoverButtons.Enabled := true;
AdvStringGrid1.HoverButtons.Buttons.Clear;
AdvStringGrid1.HoverButtons.Buttons.Add.Caption := ''0'';
AdvStringGrid1.HoverButtons.Buttons.Add.Caption := ''1'';
AdvStringGrid1.AutoNumberRow(0);
AdvStringGrid1.LinearFill(false);
end;
Result:
Set a different XY offset for different cells in the grid
You can change the X,Y offset dynamically for each cell via the OnGetCellColor event and call from there grid.UpdateXYOffset.
Example to set an XY offset different from the floating footer configured to display the last row of the grid:
procedure TForm1.AdvStringGrid1GetCellColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
begin
if arow = advstringgrid1.RowCount - 1 then
advstringgrid1.UpdateXYOffset(0,-2)
else
advstringgrid1.UpdateXYOffset(2,2);
end;
Using NarrowDown but perform narrow down only for cells matching the search text from first character.
To do this, set grid.NarrowDownFromStart = true.
Example:
grid.NarrowDownFromStart := true;
grid.NarrowDown(‘M’);
Whereas with the default setting of NarrowDownFromStart = false, this returns all cells that contain the character ‘M’
grid.NarrowDownFromStart := false;
grid.NarrowDown(‘M’);
Customizing the inplace editor for fixed cells in TAdvStringGrid
In fixed cells, it is possible to define an inplace editor for fixed cells with grid.MouseActions.FixedColsEdit / grid.MouseActions.FixedColsEditor.
It is possible to further customize this inplace editor or assign extra event handlers to it via grid.FixedEdit and grid.FixedComboBox that provide access to these control instances.
Example:
This sets the background color for the fixed cell regular editor:
TEdit(AdvStringgrid1.FixedEdit).Color := clRed;
This assigns a custom OnClick handler for the fixed cell combobox inplace editor:
TComboBox(AdvStringGrid.FixedComboBox).OnClick := MyHandler;
Dealing with floating point number precision in TAdvStringGrid
When wanting to keep floating point numbers with high precision in the grid but display with less precision, the OnGetFloatFormat event can be used.
In this code snippet, the grid cell value is set with a floating point number with 8 digits but is displayed with only 3 digits precision. Internally, we can keep calculating with values with 8 digits.
Sample:
// Set float value with full precision
begin
advstringgrid1.FloatFormat := ''%g'';
advstringgrid1.Floats[1,1] := 1.23456789;
advstringgrid1.Floats[1,2] := 9.87654321;
end;
// ensure floating point number is only displayed with 3 digits
procedure TForm4.AdvStringGrid1GetFloatFormat(Sender: TObject; ACol,
ARow: Integer; var IsFloat: Boolean; var FloatFormat: string);
begin
FloatFormat := ''%.3f'';
end;
// do calculation at full precision
begin
advstringgrid1.Floats[1,3] := advstringgrid1.Floats[1,1] + advstringgrid1.Floats[1,2];
end;
This displays the rounded numbers in the grid:
1.235
9.877
but the displayed result is
11.111
as the sum calculated is based on full precision.
Remove the context menu at right mouse click
When the inplace editor is active in the TAdvStringGrid, a menu appears when you right click the mouse. This is the default Windows context menu for an edit control.
You also see this when dropping a standard VCL TEdit on the form. If you want to remove this, drop a new (empty) TPopupMenu on the form and use the event handler:
procedure TForm4.AdvStringGrid1GetEditorProp(Sender: TObject; ACol,
ARow: Integer; AEditLink: TEditLink);
begin
advstringgrid1.NormalEdit.PopupMenu := PopupMenu1;
end;
Raw sort compare with virtual grid
Here you can download the raw sort compare with virtual grid sample.
How to customize colors in the dropdown color cube
You can customize the colors of each cell in the color cube selection of TAdvColorPickerDropDown by implementing the OnDropDown event and in this event handler write the code:
procedure TForm4.AdvColorPickerDropDown1DropDown(Sender: TObject;
var acceptdrop: Boolean);
begin
AdvColorPickerDropDown1.CubePanel.CubeCellColor[0] := clred;
AdvColorPickerDropDown1.CubePanel.CubeCellColor[1] := clgreen;
AdvColorPickerDropDown1.CubePanel.CubeCellColor[2] := clblue;
AdvColorPickerDropDown1.CubePanel.CubeCellColor[3] := clblack;
end;
How to have 2 different font colors for text within 1 cell
TAdvStringGrid supports the HTML as described at:
https://www.tmssoftware.com/site/minihtml.asp
As such, to have different font colors, background colors,... in 1 cell, you can write:
procedure TForm4.FormCreate(Sender: TObject);
begin
AdvStringGrid1.Cells[1,1] := ''<P>Here is <FONT bgcolor="clBlue" color="clWhite">some</FONT> text</P>'';
AdvStringGrid1.Cells[1,2]:= ''<P>Have <FONT color="clGreen">green</FONT> and <FONT color="clRed">red</FONT> text</P>'';
AdvStringGrid1.Cells[1,3] := ''<P>This is a <FONT face="Arial" size="12" color="#FF0000">test</FONT></P>'';
end;
How to programmatically set focus to the search box in the grid search footer
You can do this with:
grid.SearchPanel.EditControl.SetFocus;
How to initialize the TAdvGridHeaderList with hidden columns
To allow an easy customization of what columns to show in a grid by the user, an often used user
interface is a list holding the available columns and allowing the user to drag & drop from the grid
the columns that should be hidden or drag columns that should be displayed from the list to the
grid. To achieve this functionality, a component is offered that integrate much of this
functionality: TAdvGridHeaderList. The TAdvGridHeaderList is a
listbox-style control that holds indexes of available (hidden) columns. By means of drag & drop from the column header to the
list and vice versa, it is possible to define what columns to show or not show in the grid.
Here you can download a demo that shows how you can initialize a TAdvGridHeaderList with hidden columns
How to handle the event of changing the combobox from the TColumnComboEditLink component in a TAdvStringGrid
Following code with a TAdvStringGrid and a TColumnComboEditLink on the form demonstrates how you can handle the ComboChange event:
procedure TForm1.AdvStringGrid1GetEditorProp(Sender: TObject; ACol,
ARow: Integer; AEditLink: TEditLink);
begin
ColumnComboEditLink1.Combo.OnChange := ComboChange;
end;
procedure TForm1.AdvStringGrid1GetEditorType(Sender: TObject; ACol,
ARow: Integer; var AEditor: TEditorType);
begin
AEditor := edCustom;
AdvStringGrid1.EditLink :=ColumnComboEditLink1;
end;
procedure TForm1.ComboChange(Sender: TObject);
var
cc: TColumnComboBox;
begin
cc := Sender as TColumnComboBox;
advstringgrid1.Cells[0,0] := inttostr(cc.ItemIndex) + ':'+ cc.ComboItems.Items[cc.ItemIndex].Strings[0];
end;
How to add multiline comments
You can add multiline comments with:
AdvStringGrid1.SHowHint := true;
AdvStringGrid1.AddComment(1,1,''this is line1''#13#10''and here line 2'');
The hint normally auto sizes, the max. width can be set via:
AdvStringGrid1.ControlLook.HintMaxWidth := 50;
When using xlsexport, you can also save the comment when you set:
AdvGridExcelIO.Options.ExportCellProperties = true
How to export to PDF
Drop a TAdvgridPDFIO component on the form and connect the TAdvStringGrid to this nonvisual component''s TAdvStringGrid property.
Then simply call:
AdvgridPDFIO.Save(FileName);
After you called Save(FileName) you can call ShellExecute(0,''open'',Char(FileName),nil,nil,SW_NORMAL)
to automatically open this PDF after having it produced. TAdvgridPDFIO comes with settings for header and footer as well as metadata. Header and footer can as such be optionally generated for the PDF file independently from the TAdvStringGrid content.
No caret is visible when editing a cell in the grid
When there is no caret visible when editing a cell in the grid, this is because the font size is too high in relationship to the height of the cell.
This is a behavior that is actually something in Windows and not specific to our component. When in a Windows multiline edit control, the font size in relationship to the editor height is too large, it won't display the caret. This can be easily simulated by dropping a TMemo on the form and decrease its height. At some point the caret will disappear.
To avoid this, either decrease the font size or keep increase the row height.
Inserting grid data into an existing sheet in an existing XLS file with TAdvGridExcelIO
The last parameter of the XLSExport() call determines what do with the grid data during export to an existing XLS file in an existing sheet. Default, the value is InsertInSheet_InsertClear, meaning it will clear the sheet first before exporting the grid data. If the value is set to: InsertInSheet_InsertRows, it will insert the number of rows in the existing sheet needed for the grid data.
Sample:
begin
AdvStringGrid1.RandomFill(false);
AdvGridExcelio1.AdvStringGrid := AdvStringGrid1;
AdvGridExcelio1.Options.ExportOverwrite := omNever;
AdvGridExcelio1.XLSExport('c:\my documents\myexcel.xls','MYSHEET',-1,1,InsertInSheet_InsertRows);
end;
How to format Dates?
The date is formatted with the global date format setting (that is picked up from the operating system) You can override this by setting the global variable ShortDateFormat: string for this.
How to disable scrolling with mousewheel and arrow keys
Disable the mousewheel with:
BinningGrid.EnableWheel := false;
Disable scrolling with arrow keys with:
procedure TForm1.BinningGridTopLeftChanged(Sender: TObject);
begin
BinningGrid.TopRow := 0;
end;
How to change the margin between the cell border and the text
You can control the text offset from top/left corner with the property:
Default, the offset is applied both left and right, to apply the offset only left of the cell, set
AdvStringGrid.XYOffsetTopLeftOnly := true;
This applies to all cells. For example:
AdvStringGrid.XYOffset := point(0,0);
Results in:
AdvStringGrid.XYOffset := point(6,0);
Results in:
How to set hints on images in the grid
When "<" is in a cell text, the text in front of the "<" is always doubled when you click into the cell
Set grid.EditWithTags = true to edit this type of text.
How to make certain columns editable
Please set goEditing = true and do this with the event OnCanEditCell:
procedure TForm4.AdvStringGrid1CanEditCell(Sender: TObject; ARow, ACol:Integer; var CanEdit: boolean);
begin
CanEdit := ACol = 1;
end;
How to turn off the gradient and override the fixed column color
This code snippet shows how you can turn off the gradient and override the fixed column color:
procedure TForm4.AdvStringGrid1GetCellColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
begin
if Acol = 0 then
ABrush.Color := clRed;
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
advstringgrid1.look :=glSoft;
end;
How to add a sheet to an existing Excel workbook using TAdvGridExcelIO.XLSExport
The 2nd parameter of the XLSExport() call is the sheetname. You can specify a new sheet name, a sheet name different from the default sheetname and it will save the data in the specified sheet.
Copy a row with cell values & properties from one grid to another grid
This code snippet that can be applied to two default TAdvStringGrid instances shows how all cell values & cell properties within a rectangle can be copied from one grid to another grid via a memory stream:
procedure TForm4.FormCreate(Sender: TObject);
var
st: TMemoryStream;
begin
advstringgrid1.Colors[1,1] := clred;
advstringgrid1.Colors[2,1] := clYellow;
advstringgrid1.RandomFill(false,100);
st := TMemoryStream.Create;
try
advstringgrid1.SaveRectToBinStream(Rect(0,1,advstringgrid1.ColCount - 1, 1), st);
st.Position := 0;
advstringgrid2.LoadAtPointFromBinStream(Point(0,1),st);
finally
st.Free;
end;
end;
How to prevent navigation to specific cells
If you want to prevent navigation to specific cells,
please implement the OnSelectCell event and set the parameter CanSelect = false
for cells you want to prevent to be selected.
Using balloons
- Only when theming is enabled in the project options, the balloon will be visible.
- If you reparent the grid, the balloon should only be enabled AFTER the final grid's parent is set.
- Balloon hints are an API from Microsoft Windows and this does not support HTML formatted text. This is a limitation of the Microsoft Windows balloon API.
- There is a limitation to the number of characters in a balloon. This is also a limitation of the Microsoft Windows balloon API
that we cannot workaround. For a regular cell comment, there is no such length limitation.
- From TAdvStringGrid version v4.5, several new balloon notification capabilities have been added. See example 76:
https://www.tmssoftware.com/site/asg76.asp
- When using AddBalloon& AddImageIdx on the same cell , the AddBalloon will not work. These 2 features are mutually exclusive, only one type per call can be added.
- When grid. Balloon.Enable = true, it will automatically show a balloon when a cell contains text, i.e. it will show the text of the cell in the balloon. To prevent this, add the following event handler:
procedure TForm4.AdvStringGrid1CellBalloon(Sender: TObject; ACol, ARow: Integer;
var ATitle, AText: string; var AIcon: Integer);
begin
if not advstringgrid1.HasBalloon(acol,arow) then
begin
atitle := '';
atext := '';
end;
end;
I am having problems with the sorting order of special characters in other languages
Please specify the ssAnsiAlphaCase sort type with following event handler:
procedure TForm18.AdvStringGrid1GetFormat(Sender: TObject; ACol: Integer;var AStyle: TSortStyle; var aPrefix, aSuffix: string);
begin
AStyle := ssAnsiAlphaCase;
end;
The OnGetFormat event is used to instruct the grid which compare method it should use during the
sorts for each column in the grid. By default, the grid is using an automatic format guess. Although this auto
format guess can be convenient, for sorting large and complex amounts of data it is not
recommended. When mixed numeric and alphabetic data is available in a column, this auto format
guess is easily confused and the extra checks for guessing the format take extra time. With the
OnGetFormat event, the compare methods to use can be specified for each column.
This is also explained at page 19 of the
TAdvStringGrid Developers Guide.
How to programmatically start inplace editing
Make sure to FIRST set the grid.col/grid.row to the cell that must be edited and make sure the grid has focus.
Then you can programmatically start inplace editing with grid.ShowInplaceEdit;
grid.Col := yourcolumn;
grid.Row := yourrow;
grid.SetFocus;
grid.ShowInplaceEdit;
How to force the user to edit an empty cell.
Implement the OnCellValidate event like:
procedure TForm4.AdvStringGrid1CellValidate(Sender: TObject; ACol,
ARow: Integer; var Value: string; var Valid: Boolean);
begin
Valid := Value <> '';
end;
Printing tips
How to print colored, bold, italic, ... text:
Assign your OnGetCellColor event handler also to grid.OnGetCellPrintColor()
How to print images, a company logo, ...:
Set grid.PrintSettings.PrintGraphics = true
How to print a particular row in bold:
You can do this via the event OnGetCellPrintColor, for example:
procedure TForm2.AdvStringGrid1GetCellPrintColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont); begin
if arow = 7 then
afont.Style := [fsBold]
else
afont.Style := [];
end;
How to print multiple grids on a page:
Please see sample 25:
https://www.tmssoftware.com/site/asg25.asp
How to filter on checkbox state
If you wish to filter rows that have the checkbox selected, use a datacheckbox, i.e. a checkbox representing its state depending on the value of the cell being grid.CheckTrue / grid.CheckFalse. You can perform the filter on these grid.CheckTrue / grid.CheckFalse values.
How to set the dropdown width
You can set the width of the dropdown with:
grid.DropDownControlName.DropDownWidth
Example for memo dropdown:
procedure TForm4.FormCreate(Sender: TObject);
begin
advstringgrid1.DefaultEditor := edMemoDropDown;
advstringgrid1.Options := advstringgrid1.Options + [goEditing];
advstringgrid1.MemoDropDown.DropDownWidth := 400;
end;
How to use TAdvColumnSetter
TadvColumnSetter is a component that is used in TAdvGridImportDialog. Please drop this component on a form, assign a grid and a filename and you'll see this component appear on top of the grid. It is used to interactively set where columns start/end in an ASCII file.
How to change the TAdvGridPrintSettingsDialog to another language
Open ASGPREV.PAS and you can edit the DFM file to change it to the desired language.
How to display special chars in a cell
Example: to have arrows displayed in a cell, you can use:
begin
advstringgrid1.FontNames[1,1] := 'Wingdings 3';
advstringgrid1.Cells[1,1] := #33;
advstringgrid1.FontNames[1,2] := 'Wingdings 3';
advstringgrid1.Cells[1,2] := #34;
advstringgrid1.FontNames[2,1] := 'Wingdings 3';
advstringgrid1.Cells[2,1] := #35;
advstringgrid1.FontNames[2,2] := 'Wingdings 3';
advstringgrid1.Cells[2,2] := #36;
end;
Result:
Using the HTMLSettings dialog at runtime
Drop AdvGridHTMLSettingsDialog on the form , assign the grid and call
AdvGridHTMLSettingsDialog1.execute;
Using the grid gallery picker at runtime
This code snippet demonstrates how you can invoke the TAdvStringGrid gallery picker at runtime:
uses
AsgGallery;
procedure TForm1.Button1Click(Sender: TObject);
var
gg: TGridGallery;
begin
gg := TGridGallery.Create(Application);
if gg.ShowModal = mrOK then
AdvStringGrid1.LoadVisualProps(gg.GalleryFile);
gg.Free;
end;
Creating a grid at runtime in C++
Creating a grid at runtime in C++ is done with:
{
TAdvStringGrid *asg;
asg = new TAdvStringGrid(this);
asg->Parent = this;
}
How to add a TAdvGlowButton in a grid
Any TWinControl descendent can be hosted inside TAdvStringGrid. This is done by assigning the control to the grid.CellControls[col,row]: TWinControl property.
Example: to have a TadvGlowButton displayed in cell 2,3 you can use:
AdvStringGrid1.CellControls[2,3] := AdvGlowButton1;
Result:
If you want to move the control to another place on the form, destroy it, etc... that should happen from application code.
To destroy the control, use following code:
var
ctrl: TControl;
ctrl := grid.CellControls[x,y];
if Assigned(ctrl) then
begin
FreeAndNil(ctrl);
grid.CellControls[x,y] := nil;
end;
The article that discusses cell controls can be found here:
https://www.tmssoftware.com/site/asg57.asp
Specifying a filter in C++
Follow code specifies a filter in C++ code:
TFilterData *fd;
AdvStringGrid->Filter->Clear();
fd = AdvStringGrid->Filter->Items->Add();
fd->Condition = “BMW”;
fd->Column = 1;
AdvStringGrid->FilterActive = true;
Customizing the TAdvStringGrid Find Dialog
A customization of this dialog have to be done by opening & editing ASGREPLACE.PAS.
This is where the dialog is defined.
Show inplace editor in a special color
By design, the background color of the inplace editor is shown in the same color as the cell background color. This way, the inplace editor looks transparent wrt the grid. If there is a need to show the inplace editor with a different background color, to draw attention for example, following code can be used:
procedure TForm4.AdvStringGrid1GetCellColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
begin
if (AdvStringGrid1.EditMode) and (ARow = AdvStringGrid1.Row) and (ACol = AdvStringGrid1.Col) then
ABrush.Color := clRed
else
ABrush.Color := clWhite;
end;
Importing data with TAdvGridExcelIO in a grid that already contains data
With AdvGridExcelIO.GridStartCol / AdvGridExcelIO.GridStartRow, you can set the top left corner from where the import starts.
Allowing multiline text & using the Enter key to start a new line
To allow to enter multiline text in a cell, set grid.MultiLineCells := true.
By default the key to start a new line in the inplace editor is Ctrl-Enter ('Enter' stops editing).
If you want to use the Enter key to start a new line instead, set grid.Navigation.LineFeedOnEnter = true
How to use TAdvGridReplaceDialog
Drop a TAdvGridReplaceDialog on the form and a TAdvStringGrid.
Add the code:
begin
AdvGridReplaceDialog1.Grid := AdvStringGrid1;
AdvGridReplaceDialog1.Execute;
end;
Fill in the dialog a value that can be found in a grid cell and
a value it should replace and press "Replace All".
TAdvGridReplaceDialog is not applicable for TDBAdvGrid, only for TAdvStringGrid.
This is because, to change values in the TDBAdvGrid, values should be changed on dataset level, via DBField,
not just with grid.Cells[].
Persisting grids with images to file
The functions grid.SaveToBinFile / grid.LoadFromBinFile persist grid cell data including cell properties. This can also include objects created in cells. If you want to persist an image set in a cell, make sure to use grid.CreatePicture() as this creates the object managed by the grid. All objects managed by the grid will also be saved when calling grid.SaveToBinFile().
Example:
begin
AdvStringGrid1.CreatePicture(1,1,false,noStretch,4,haLeft,vaTop).Assign(image1.Picture);
AdvStringGrid1.SaveToBinFile('.\advgrid.bin');
end;
This will save the image created in cell 1,1 to the file and this image will be reloaded when calling grid.LoadFromBinFile()
How to change the size of the find next / previous / highlight buttons in the search bar
The text of the buttons is exposed via grid.SearchFooter and the recommended way
is to use the grid.SearchFooter.* properties.
The button width is not exposed, therefore it should be set via grid.SearchPanel.
You can access the buttons in code with:
advstringgrid.SearchPanel.ForwardButton: TButton
advstringgrid.SearchPanel.BackwardButton: Tbutton
Make sure to set this after the searchfooter was created.
Exporting numbers as text with TAdvGridExcelIO
By default, when a cell contains text like "000123" and exporting this to Excel, Excel will display this as "123". This is because by default, "000123" is recognized as a number and Excel will be default show numbers without any zero prefixes. If it is required that similar text is shown in the Excel as-is, it should be specified that TAdvGridExcelIO should export the number as text. This can be done with:
1) global setting: AdvGridExcelIO.Options.ExportCellFormats = false
2) dynamically by using the OnExportColumnFormat event
Example:
procedure TForm1.AdvGridExcelIO1ExportColumnFormat(Sender: TObject; GridCol,
GridRow, XlsCol, XlsRow: Integer; const Value: WideString;
var ExportCellAsString: Boolean);
begin
if GridCol = 2 then
ExportCellAsString := true;
end;
This will treat all cells in column 2 as text cells for the generated Excel sheet.
I want to override the popup menu of the default grid inplace editor
You can assign a custom popup menu to the default grid inplace editor with following code:
procedure TForm2.AdvStringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: string);
begin
AdvStringGrid.NormalEdit.PopupMenu :=PopupMenu1;
end;
Delphi can't find definition for TFlxFormat when using TAdvGridExcelIO
This type is defined in the unit tmsUFlxFormats. Add the unit tmsUFlxFormats to the uses clause and the problem should be solved.
Using TAdvStringGrid printer settings dialog combined with printer selection.
This code snippet shows how you can show the print setup dialog for users after which the printer selection is done.
procedure TForm1.PrintGrid;
begin
AdvGridPrintSettings.Form.Caption := 'Print overview';
AdvStringGrid.PrintSettings.FitToPage := fpAlways;
AdvStringGrid.PrintSettings.Orientation := poLandscape; // initialize to default poLandscape
if AdvGridPrintSettings.Execute then
begin
Printer.Orientation := AdvStringGrid.PrintSettings.Orientation;
if PrinterSetupDialog.Execute then
begin
AdvStringGrid.PrintSettings.Orientation := Printer.Orientation;
AdvStringgrid.Print;
end;
end;
end;
Vertical bottom or center alignment in the grid
Vertical alignment and wordwrap are mutually exclusive. This is due to a limitation in the Microsoft Windows text drawing API that does not allow to have wordwrapped text with other vertical alignment than top alignment. To enable vertically centered or bottom alignment, make sure to set grid.WordWrap to false.
Using TAdvStringGrid with Multilizer
In order to automatically translate applications that use TAdvStringGrid with Multilizer, exclude the class TAdvRichEdit in Multilizer. TAdvRichEdit is an internal class only used in TAdvStringGrid as inplace editor for rich text editing.
Copying a grid as image on the clipboard
Following code copies TAdvStringGrid as an image on the clipboard:
var
bmp: TBitmap;
clip: TClipboard;
begin
bmp := tbitmap.create;
bmp.Width := advstringgrid1.Width;
bmp.Height := advstringgrid1.Height;
AdvStringGrid1.PaintTo(bmp.Canvas,0,0);
clip := TClipboard.Create;
clip.Assign(bmp);
bmp.Free;
clip.Free;
end;
Saving TAdvStringGrid to a JPEG file
With code below, the output of TAdvStringGrid is sent to a JPEG file:
var
pBitmap: TBitmap;
jp: TJPEGImage;
R: TRect;
begin
pBitmap := TBitmap.Create; //create a new instance of a bitmap
jp := TJPEGImage.Create; //create new instance of a jpg file
R := Rect(0,0,950,760); //parameters for rectangle
pBitmap.Height := 622; //set bmp height
pBitmap.Width := 812; //set bmp width
AdvStringGrid1.PrintPreview(pBitmap.Canvas,R); //call Preview to paint to BMP canvas
jp.Assign(pBitmap); //get picture from bitmap for JPG Image
jp.SaveToFile('c:\temp\Grid.jpg'); //save picture as JPG File
pBitmap.Free;
jp.Free;
end;
Setting different max. edit lengths for the inplace editor
If the max. number of characters for editing should be limited, this can be done with then LengthLimit property of the inplace editor. When LengthLimit is 0, there is no limitation to the nr. of characters that can be typed in the editor.
To set a different max. nr of characters per column, following code can be used in the OnGetCellEditor event :
procedure TForm1.AdvStringGrid1GetEditorType(Sender: TObject; ACol,
ARow: Integer; var AEditor: TEditorType);
begin
if Assigned(AdvStringGrid1.NormalEdit) then
begin
case acol of
1:AdvStringGrid1.NormalEdit.LengthLimit := 4;
2:AdvStringGrid1.NormalEdit.LengthLimit := 8;
else
AdvStringGrid1.NormalEdit.LengthLimit := 0
end;
end;
end;
This sets the max. edit length for column 1 to 4 characters, for column 2 to 8 eight characters and unlimited for all other columns.
Printing only selected rows in disjunct row select mode
The disjunct row select mode is flexible to let the user select several non contiguous rows in a grid. When you want to print only the selected rows, the Print functions do not provide a possibility these rows. Thanks to the grid's row hiding capabilities this can be easily done by temporarily hide the non-selected rows, print the grid and then unhide these rows again. The code to hide only the not selected rows is :
var
i,j: Integer;
begin
i := 1;
with AdvStringGrid do
begin
j := RowCount;
while (i < j) do
if not RowSelect[DisplRowIndex(i)] then
HideRow(i);
Inc(i);
end;
end;
To unhide the rows again after the print, the method UnHideRowsAll can be called.
Setting an hourglass cursor during lengthy sort operations
Before the sort starts, the OnCanSort event is called. In this event, the crHourGlass cursor can specified either for the grid or for your application.
When sorting is completed, the OnClickSort event is called, where you can set the cursor back to normal.
Forcing a visible cell editor when the form is displayed in the grid
In the FormShow event, add these 2 methods :
grid.SetFocus;
grid.ShowInplaceEdit;
When using RowSelect, the first cell of the row is not highlighted as the other cells.
This can be easily solved by setting the option goDrawFocusSelect to true in the Options property.
Use a different inplace editor color than the cell color
Normally, the inplace edit control gets the same color as the cell color. Sometimes this behaviour is not wanted, especially when the cell that is edited must be highlighted. This can be down in the following way :
procedure TForm1.FormCreate(Sender: TObject);
begin
AdvStringGrid1.Color := clSilver;
end;
procedure TForm1.AdvStringGrid1GetCellColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
begin
if (acol = AdvStringGrid1.Col) and
(arow = AdvStringGrid1.Row) then
begin
if Assigned(AdvStringGrid1.NormalEdit) then
if (AdvStringGrid1.NormalEdit.Visible) then
ABrush.Color := clWhite;
end;
end;
Still using the 3D style inplace combobox editor
Use following code in the OnGetCellEditor :
grid.ComboBox.Flat:=false;
I use OnGetEditorType to specify a checkbox but it only displays when editing
Use a permanently visible checkbox that can be added with the AddCheckBox method
I use row selection, but the first column has a different color
Set goDrawFocusSelected = true in the Options property
Why do rotated fonts do not print correct ?
Toggle the value of the public property PrinterDriverFix: Boolean
I want to use rotated font but the font does not show rotated
Make sure to use a truetype font. Only truetype font can be rotated.
Why do my printouts do not have colors or fonts set as displayed ?
Assign the OnGetCellColor event to the OnGetCellPrintColor event as well.
Copy and paste does not seem to work ?
Make sure that Navigation.AllowClipboardShortCuts is true and the grid is either editable or Navigation.AllowClipboardAlways is true
I want to select multiple rows with Ctrl - mouseclick and Shift - mouse click
In the Options property set goRowSelect = true and set MouseActions.DisjunctRowSelect = true. The desired selection capabilities are enabled now.
How can the copyright notice be removed from the grid ?
The registered version of TAdvStringGrid does not show this copyright notice
I am not sure if the latest version of TAdvStringGrid is installed. How can I check this ?
At design time, right click on the grid and select About. At runtime, show the version with : ShowMessage(Grid.GetVersionString);
With the registered version of TAdvStringGrid, do we need to pay additional royalties for application distribution ?
With license for commercial use of the registered version, no additional royalties need to be paid
How can I set text in a cell ? How do I programmatically change a column width or row height ?
Setting text in a cell is done with the grid.Cells[col,row]: string propert. Setting the column width is done with grid.ColWidths[col]: Integer and setting a row height with grid.RowHeights[row]: Integer. Note that TAdvStringGrid inherits ALL methods and properties of TStringGrid. As such, refer to the Borland documentation for TStringGrid for help on the basic grid functions
How can I get the state of a checkbox added with grid.AddCheckBox ?
var
state: Boolean;
grid.GetCheckBoxState(col,row,state);
if state then
ShowMessage('CheckBox is checked')
else
ShowMessage('CheckBox is not checked');
I get an exception 'invalid column' during export to Excel
The maximum number of columns supported in Excel itself is 255. As such, it is not possible to export more columns than the Excel limit.
I have added a button on the grid with AddButton but the OnButtonClick event is not triggered ?
If you add a button to a non editable cell (or grid without editing enabled) the button is treated as disabled by default. To override this behaviour, set grid.ControlLook.NoDisabledButtonLook = true
I try to set VAlignment to vtaCenter or vtaBottom but this is not working
By default, wordwrap is enabled in the grid and it is a limitation of the Microsoft text drawing API's that wordwrapped text is always top aligned. To use the VAlignment capability, set WordWrap = false
Can I load a gallery file programmatically at runtime ?
Yes, call grid.LoadVisualProps(GalleryFileName);
I am having problems with grid.SortByColumn, it is slow or behaves incorrect
SortByColumn is a deprecated method, use grid.QSort instead with settings as defined under grid.SortSettings
Users of older operating systems have an error message on application startup related to a missing gdiplus.dll
Either redistribute the Microsoft GDIPLUS.DLL (explained in README.TXT) or remove the gdiplus.dll dependency by commenting the line {$DEFINE TMSGDIPLUS} in TMSDEFS.INC
When exporting to Excel file with the method grid.SaveToXLS() I get the error : "Excel OLE server not found"
The method grid.SaveToXLS() uses OLE automation to export to Excel file and thus requires Excel to be installed on the machine. To avoid this requirement, you can use the component TAdvGridExcelIO to export to Excel.
When try to install TAdvStringGrid, I get an error that TAdvStringGrid is compiled with a different version of PictureContainer
Most likely another TMS component has been installed that is also using the PictureContainer. Due to strict binary compatibility checks of Delphi & C++Builder, it is causing problems to install multiple binary distributed components that share a unit. For using the binary versions, the only workaround is to install the packages alternatingly for evaluation. Registered versions that come with full source do not have this problem.
When I run my application I get an error "property does not exist"
An older version of ADVGRID.DCU might be in your library path. When upgrading from an older version, make sure to first open all forms in your application that use the grid, ignore property errors on opening, save form files and then rebuild your application.
When I try to install the package, it asks for AdvGrid.pas
Make sure the correct version of ADVGRID.DCU and other DCU files are in your library path, that your library path contains the directory where ADVGRID.DCU is installed and that no other versions of ADVGRID.DCU are in your library path. Note that the binary version of TAdvStringGrid cannot be used with Delphi or C++Builder trial versions.