Gustav Schubert 27 Posted yesterday at 09:26 PM FMX: What is the recommended way to load example data into TStringGrid? I have this, but it no longer works: unit FrmMain; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, FMX.Types, FMX.Controls, FMX.Forms, Data.Bind.EngExt, FMX.Bind.DBEngExt, FMX.Bind.Editors, Data.Bind.Components, Data.Bind.DBScope, Data.Bind.DBLinks, Fmx.Bind.DBLinks, FMX.Layouts, FMX.Grid, Data.DB, Datasnap.DBClient, FMX.Edit, System.Bindings.Outputs, FMX.StdCtrls, System.Rtti, FMX.Grid.Style, FMX.Controls.Presentation, FMX.ScrollBox; type TFormMain = class(TForm) StringGrid: TStringGrid; TestBtn: TButton; procedure FormCreate(Sender: TObject); procedure TestBtnClick(Sender: TObject); private ClientDataSet: TClientDataSet; DataSource: TDataSource; BindScope: TBindScopeDB; BindingsList: TBindingsList; gl: TBindDBGridLink; Counter: Integer; end; var FormMain: TFormMain; implementation {$R *.fmx} procedure TFormMain.FormCreate(Sender: TObject); var dn: string; fn: string; pn: string; ML: TStringList; begin TestBtn.Enabled := False; ReportMemoryLeaksOnShutdown := True; dn := 'C:\Users\Public\Documents\Embarcadero\Studio\37.0\Samples\Data\'; fn := 'country.xml'; pn := dn + fn; if FileExists(pn) then begin ClientDataSet := TClientDataSet.Create(self); BindingsList := TBindingsList.Create(self); ML := TStringList.Create; ML.LoadFromFile(pn); ClientDataSet.Active := False; ClientDataSet.XMLData := ML.Text; ClientDataSet.Active := True; ML.Free; DataSource := TDataSource.Create(self); DataSource.AutoEdit := False; DataSource.DataSet := ClientDataSet; BindScope := TBindScopeDB.Create(self); BindScope.DataSet := ClientDataSet; BindScope.DataSource := DataSource; TestBtn.Enabled := True; end; end; procedure TFormMain.TestBtnClick(Sender: TObject); begin if (gl <> nil) then gl.Active := False; gl.Free; gl := TBindDBGridLink.Create(BindingsList); gl.AutoBufferCount := False; gl.Category := 'DB Links'; gl.DataSource := BindScope; gl.GridControl := StringGrid; // <-- Exception in D13 // in D12.3: ok // in D13: Crash because Position = nil in TControl.GetBoundRect { function TControl.GetBoundsRect: TRectF; begin // if Position = nil then // result := TRectF.Create(0, 0, 0, 0) // else Result := TRectF.Create(Position.X, Position.Y, Position.X + Width, Position.Y + Height); end; } gl.Active := True; Inc(Counter); Caption := IntToStr(Counter); end; end. Share this post Link to post
Dave Nottage 634 Posted yesterday at 09:28 PM 2 minutes ago, Gustav Schubert said: <-- Exception in D13 What is the exception? Please run it in the debugger and show the callstack at that point. Share this post Link to post
Gustav Schubert 27 Posted yesterday at 09:44 PM 12 minutes ago, Dave Nottage said: What is the exception? FMX.Controls.TControl.GetBoundsRect FMX.ScrollBox.TScrollContent.IsVisibleChild($CB85650) FMX.Controls.TControl.RecalcUpdateRect FMX.Controls.TControl.InternalSizeChanged FMX.Controls.TControl.HandleSizeChanged FMX.Controls.TControl.SizeChanged(???) FMX.Controls.TControl.RecalcSize FMX.ScrollBox.Style.TStyledCustomScrollBox.RealignContent FMX.Grid.Style.TStyledGrid.MMInvalidateContentSize(???) FMX.Presentation.Messages.TMessageSender.SendMessage(???) FMX.Grid.TGridModel.InvalidateContentSize FMX.Grid.TGridModel.RemoveColumn(???) FMX.Grid.TCustomGrid.ContentBeforeRemoveObject(???) FMX.ScrollBox.TScrollContent.DoRemoveObject($CB85650) FMX.Types.TFmxObject.RemoveObject(???) FMX.Types.TFmxObject.Destroy FMX.Controls.TControl.Destroy FMX.Grid.TColumn.Destroy System.TObject.Free Fmx.Bind.DBLinks.TBindDBStringGridColumnCreator.ClearColumns Data.Bind.DBLinks.TBaseBindDBGridLink.ClearColumns(TBindDBStringGridColumnCreator($CB95270) as IBindDBGridLinkControlManager) Fmx.Bind.DBLinks.TCustomBindDBGridLink.ClearColumns(TBindDBStringGridColumnCreator($CB95270) as IBindDBGridLinkControlManager) Fmx.Bind.DBLinks.TCustomBindDBGridLink.ClearGeneratedExpressions(???) Fmx.Bind.DBLinks.TCustomBindDBGridLink.UpdateColumns Data.Bind.DBLinks.TInternalBindGridLink.ApplyComponents Data.Bind.Components.TActivatedContainedBindComponent.UpdateControlChanged Data.Bind.Components.TCommonBindComponent.SetControlComponent($62A29B0) Fmx.Bind.DBLinks.TBaseBindDBGridControlLink.SetControl(???) FrmMain.TFormMain.TestBtnClick($4EC7280) FMX.Controls.TControl.Click FMX.StdCtrls.TCustomButton.Click FMX.Controls.TControl.MouseClick(???,???,45,14) FMX.Forms.TCommonCustomForm.MouseUp(mbLeft,[ssLeft],141,38,???) FMX.Platform.Win.WndProc(460274,514,0,2490509) FMX.Platform.Win.TPlatformWin.HandleMessage FMX.Forms.TApplication.HandleMessage FMX.Platform.Win.TPlatformWin.Run FMX.Forms.TApplication.Run SG02.SG02 I get access violation, Position is nil in TControl.GetBoundsRect. Share this post Link to post
david berneda 65 Posted 10 hours ago I had a similar bug but I couldn't reproduce it anymore. Looks like RemoveColumn triggers some calls that act too late, when Position etc are already destroyed (use-after-nil). I did submit a QC issue but never was activated as I couldn't add reproduceable steps. Share this post Link to post
david berneda 65 Posted 10 hours ago As an alternative, this is our free api that can load data into grids (Vcl and Fmx), just doing this: uses BI.Xml; BIGrid1.Data := TBIXml.FromFile('country.xml') https://github.com/Steema/TeeBI Share this post Link to post
Gustav Schubert 27 Posted 6 hours ago I now have a workaround: Need to unload the Presentation before attempting the critical assignment. procedure TFormMain.TestBtnClick(Sender: TObject); begin StringGrid.UnloadPresentation; // to avoid problems later if (gl <> nil) then gl.Active := False; gl.Free; gl := TBindDBGridLink.Create(BindingsList); gl.AutoBufferCount := False; gl.Category := 'DB Links'; gl.DataSource := BindScope; gl.GridControl := StringGrid; // <-- critical line gl.Active := True; StringGrid.LoadPresentation; // now it is safe to have a presentation Inc(Counter); Caption := IntToStr(Counter); end; Depending on who the Owner is of these databinding components, Form or Application, it may be necessary to do the same (unloading the presentation of the string grid) when the application closes down. I needed to do this in FormClose, FormDestroy would be tool late. Share this post Link to post
david berneda 65 Posted 4 hours ago Thanks for the unload tip ! I'll check with our grids if the bug happen. Share this post Link to post