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; |
To do this, set grid.NarrowDownFromStart = true. Example: grid.NarrowDownFromStart := true; grid.NarrowDown(M); grid.NarrowDownFromStart := false; grid.NarrowDown(M); |
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; |
Its 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; procedure TForm5.TMSFNCGrid1GetCellEditorCustomClassType(Sender: TObject; ACol, ARow: Integer; var CellEditorCustomClassType: TTMSFNCGridEditorClass); begin CellEditorCustomClassType := TTMSFNCRichEditor; end; procedure TForm5.TMSFNCGrid1GetCellEditorProperties(Sender: TObject; ACol, ARow: Integer; CellEditor: TWinControl); begin TMSFNCRichEditorFormatToolBar1.RichEditor := (CellEditor as TTMSFNCRichEditor); end; 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; |
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; |
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; |
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; 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; |
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; |
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; |
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