Knowledge Base Alert June, 2016






TDBAdvGrid:

Dynamically filtering lookup datasets in a TDBAdvGrid



It is easy to dynamically set a filter for a lookup dataset depending on other values for a lookup editor in the TDBAdvGrid. DB fields with a lookup relatoinship are automatically edited via a combobox. To filter the values to select from, filter the lookup dataset from the OnGetEditorProp event that is triggered just before the inplace editor becomes active. Following example filter can be applied in the ADOLookup demo for TDBAdvGrid that filters the lookup dataset for countries starting with ‘S’ when there is editing on an odd row.

procedure TForm1.DBAdvGrid1GetEditorProp(Sender: TObject; ACol, ARow: Integer;
  AEditLink: TEditLink);
begin
  if odd(arow)  then
  begin
    adotable2.Filtered := false;
    adotable2.Filter := 'COUNTRY LIKE "S%"';
    adotable2.Filtered := true;
  end
  else
  begin
    adotable2.Filtered := false;
  end;
end;


TAdvStringGrid:

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’);

TAdvStringGrid:

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;

TTMSFNCGrid:

Using a TTMSFNCRichEditor as inplace editor for the TTMSFNCGrid



It’s quite straightforward to use the TTMSFNCRichEditor as inplace editor for the grid. In the grid cell, you can display HTML formatted text and this can then be wysiwyg edited with TTMSFNCRichEditor.

All that is needed is to implement a few event handlers. Via OnGetCellEditorType, it is defined that a custom inplace editor should be used:

procedure TForm5.TMSFNCGrid1GetCellEditorType(Sender: TObject; ACol,
  ARow: Integer; var CellEditorType: TTMSFNCGridEditorType);
begin
  CellEditorType:= etCustom;
end;
Next, via the OnGetCellEditorCustomClassType, it is specified that the class to use for the custom editor is TTMSFNCRichEditor:

procedure TForm5.TMSFNCGrid1GetCellEditorCustomClassType(Sender: TObject; ACol,
  ARow: Integer; var CellEditorCustomClassType: TTMSFNCGridEditorClass);
begin
  CellEditorCustomClassType := TTMSFNCRichEditor;
end;
As an extra, a TMSFNCRichEditorFormatToolBar is associated with the TTMSFNCRichEditor when it is active for editing a cell and this is done from the OnGetCellEditorProperties:

procedure TForm5.TMSFNCGrid1GetCellEditorProperties(Sender: TObject; ACol,
  ARow: Integer; CellEditor: TWinControl);
begin
  TMSFNCRichEditorFormatToolBar1.RichEditor := (CellEditor as TTMSFNCRichEditor);
end;
Finally, we must provide the event handlers for OnCellEditGetData and OnCellEditSetData where the cell text is loaded as HTML in the TTMSFNCRichEditor and vice versa. A non-visual TMSFNCRichEditorHTMLIO component is used for this conversion.

procedure TForm5.TMSFNCGrid1CellEditGetData(Sender: TObject; ACol,
  ARow: Integer; CellEditor: TWinControl; var CellString: string);
begin
  TMSFNCRichEditorHTMLIO1.RichEditor := (CellEditor as TTMSFNCRichEditor);
  TMSFNCRichEditorHTMLIO1.LoadHTML(CellString);
end;

procedure TForm5.TMSFNCGrid1CellEditSetData(Sender: TObject; ACol,
  ARow: Integer; CellEditor: TWinControl; var CellString: string);
begin
  CellString := (CellEditor as TTMSFNCRichEditor).ContentAsHTML('');
end;
The full sample can be downloaded from: http://www.tmssoftware.net/public/GridRichEditorEditor.zip


TTMSFMXRichEditor:

How to copy content from one RichEdit to another RichEdit



It is very easy to copy the contents of a TTMSFMXRichEditor 1:1 matching to another TTMSFMXRichEditor instance with following code snippet:

var
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    TMSFMXRichEditor1.SaveToStream(ms);
    ms.Position := 0;
    TMSFMXRichEditor2.LoadFromStream(ms);
  finally
    ms.Free;
  end;
end;
From Subject Received Size Categories Bruno Fierens KB 15:14 9 KB

TTMSFMXGrid:

A technique to check checkboxes in the grid for specific rows by using a filter



In the TMSFMXGrid, data is loaded via a CSV file and an extra column of checkboxes is added. Now, we want to check checkboxes for specific rows and instead of looping through all rows to find the matching rows and check the checkbox, we use the built-in grid filtering capability and check only the rows that remain after filtering and then remove the filter:

var
  i: integer;
begin
  TMSFMXGrid1.LoadFromCSV('.\cars.csv');
  TMSFMXGrid1.ColumnCount := TMSFMXGrid1.ColumnCount + 1;
  TMSFMXGrid1.AddCheckBoxColumn(TMSFMXGrid1.ColumnCount - 1);

  TMSFMXGrid1.Filter.Clear;
  TMSFMXGrid1.Filter.Add;
  TMSFMXGrid1.Filter.Items[0].Condition := 'BMW';
  TMSFMXGrid1.Filter.Items[0].Column := 1;

  TMSFMXGrid1.ApplyFilter;

  for i := TMSFMXGrid1.FixedRows to TMSFMXGrid1.RowCount - 1 do
  begin
    TMSFMXGrid1.CheckBoxState[TMSFMXGrid1.ColumnCount - 1, TMSFMXGrid1.DisplToRealRow(i)] := true;
  end;

  TMSFMXGrid1.RemoveFilter;
end;

TTMSFMXGrid:

How to show/popup a comment by clicking on a cell



To show a Popup with the cell comments you can use following code:

procedure TForm1.FormCreate(Sender: TObject); 
begin
  TMSFMXGrid1.Comments[3, 3] := 'Hello'#13#10'World';
end;

procedure TForm1.TMSFMXGrid1CellClick(Sender: TObject; ACol, ARow: Integer);
var
  obj: TControl;
begin
  obj := TMSFMXGrid1.GetCellObject(Cell(ACol, ARow));
  if Assigned(obj) and (obj is TTMSFMXCommentGridCell) then
    (obj as TTMSFMXCommentGridCell).ShowPopup;
end;
You can also modify the arrow (up or down), the thickness of the border,... :

procedure TForm1.TMSFMXGrid1GetCellProperties(Sender: TObject; ACol,
  ARow: Integer; Cell: TFmxObject);
begin
  if Cell is TTMSFMXCommentGridCell then
  begin
    (Cell as TTMSFMXCommentGridCell).CommentPanel.CalloutPosition := TCalloutPosition.Top;
    (Cell as TTMSFMXCommentGridCell).Popup.Placement := TPlacement.BottomCenter;
    (Cell as TTMSFMXCommentGridCell).CommentText.Margins.Top := (Cell as TTMSFMXCommentGridCell).CommentPanel.CalloutLength + 2;
  end;
end;


TTMSFMXChart:

Dynamically pass an array of points



With the OnGetNumberOfPoints and the OnGetPoint there is no loop necessary, the chart internally takes care of this. You only need to pass the number of points, and return the value:

procedure TForm1.TMSFMXChart1GetNumberOfPoints(Sender: TObject; ASerie: TTMSFMXChartSerie; var ANumberOfPoints: Integer); 
 begin
  ANumberOfPoints := Length(ARRAY);
end;

procedure TForm1.TMSFMXChart1GetPoint(Sender: TObject; ASerie: TTMSFMXChartSerie; AIndex: Integer;
  var APoint: TTMSFMXChartPointVirtual); 
 begin
  APoint.YValue := ARRAY[AIndex];
end;

TTMSFMXChart:

Zooming



The zooming functionality like in the VCL version is not implemented yet. We will add this on our feature request list, but as a starting point we have included a sample that allows you to write an own implementation. To test this code below after implementation, hold the CTRL key on the keyboard, click on the chart and drag down/right to zoom in to a specific area.

private
    { Private declarations }
    FDragArea: Boolean;
    FDragDownPos, FDragMovePos: TPointF;

....

procedure TForm1.FormCreate(Sender: TObject); 
begin
  TMSFMXChart1.InteractionOptions.ScaleMode := smNone; 
end;

procedure TForm1.TMSFMXChart1AfterDrawChart(Sender: TObject; ACanvas: TCanvas; ARect: TRectF);
begin
  if FDragArea then
  begin
    ACanvas.Fill.Color := claRed;
    ACanvas.FillRect(RectF(FDragDownPos.X, FDragDownPos.Y, FDragMovePos.X, FDragMovePos.Y), 0, 0, AllCorners, 0.5);
  end;
end;

procedure TForm1.TMSFMXChart1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  FDragArea := (ssCtrl in Shift);
  FDragDownPos := PointF(X, Y);
end;

procedure TForm1.TMSFMXChart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
begin
  if FDragArea then
  begin
    FDragMovePos := PointF(X, Y);
    TMSFMXChart1.Repaint;
  end;
end;

procedure TForm1.TMSFMXChart1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
  I: Integer;
begin
  if FDragArea then
  begin
    for I := 0 to TMSFMXChart1.Series.Count - 1 do
    begin
      TMSFMXChart1.Series[I].AutoXRange := arDisabled;
      TMSFMXChart1.Series[I].AutoYRange := arDisabled;
      TMSFMXChart1.Series[I].MinX := TMSFMXChart1.Series[I].XToValue(FDragDownPos.X);
      TMSFMXChart1.Series[I].MaxX := TMSFMXChart1.Series[I].XToValue(X);
      TMSFMXChart1.Series[I].MinY := TMSFMXChart1.Series[I].YToValue(Y);
      TMSFMXChart1.Series[I].MaxY := TMSFMXChart1.Series[I].YToValue(FDragDownPos.Y);
    end;

    FDragArea := False;
  end;
end;


TTMSFMXPayPal:

How to process a test payment



The TTMSFMXPayPal control supports the Sandbox environment from the PayPal API that allows processing test payments. Make sure the APIEnvironment property is set to peSandbox and that you are using a Sandbox account. You can find/create Sandbox accounts at the PayPal developers page.



As always, we thank all users for the numerous inputs, feedback, comments and suggestions. This is an invaluable help to steer our developments here at TMS software. We continue to look forward to all your further communications to direct our team to provide you better tools and components for your needs.

Kind regards,
TMS software team
Email: info@tmssoftware.com
Web: http://www.tmssoftware.com
Support, FAQ & Manuals: http://www.tmssoftware.com/site/support.asp


Follow latest developments at tmssoftware.com




NOTICE: If you wish to unsubscribe from the TMS software Newsletter, please click here.