I am converting some software from Delphi 5 to Delphi 10.2.
We have a TDBGrid that is linked to a datasource that is link to a table. So something like this:
TDBGrid.DataSource := GroupDS;
GroupDS.DataSet := MemoryTable;
The MemoryTable has 1 record in it. However, no matter what I've tried the TDBGrid is duplicating the single record. This behavior only happens in D10.2. In D5 it shows the single record normally. I can call RecordCount on the table and verify that there is only 1 record present in it.
Please let me know if there is any other info I can provide. This is all taking place in VCL stuff so there isn't much code to show. I don't know if maybe something changed in the 20 years between the releases of the IDEs.
I wrote a test app to recreate this issue.
Code:
EmpGrpMember := InitializeACRTable;
EmpGrpMember.InMemory := True;
EmpGrpMember.IndexDefs.Add('GroupGUID', 'GroupGUID', [ixPrimary, ixUnique]);
EmpGrpMember.IndexDefs.Add('GroupName', 'GroupName', [ixUnique]);
EmpGrpMember.IndexName := 'GroupName';
EmpGrpMember.FieldDefs.Add('GroupGUID', ftString, 40);
EmpGrpMember.FieldDefs.Add('GroupName', ftString, 100);
EmpGrpMember.TableName := 'EmpGrpMember';
EmpGrpMemberDS.DataSet := EmpGrpMember;
DBGrid1.DataSource := EmpGrpMemberDS;
EmpGrpMember.Open;
EmpGrpMember.Insert;
EmpGrpMember.FieldByName('GroupGUID').AsString := '123';
EmpGrpMember.FieldByName('GroupName').AsString := 'wwww';
EmpGrpMember.Post;
dfm:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 336
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 144
Top = 96
Width = 225
Height = 121
Options = [dgTitles, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect, dgAlwaysShowSelection, dgConfirmDelete, dgCancelOnExit]
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
Columns = <
item
Expanded = False
FieldName = 'GroupName'
Title.Caption = 'Member of Groups'
Width = 191
Visible = True
end>
end
object EmpGrpMemberDS: TDataSource
Left = 488
Top = 216
end
end
I still get the same results. My dbgrid ends up showing 4 'www' and it should only be showing 1. I do a .recordcount on the table and it only shows 1 record.
The minimal sample project below virtually exactly replicates your project except that it uses a TClientDataSet as the dataset instead of the AddAim one.
It correctly shows only a single row. Ergo the problem lies with the use of a TACRTable. So, unless you get lucky and someone here recognises the problem and knows how to fix it, you'll need to take the problem up with AddAim.
Code:
type
TForm1 = class(TForm)
DataSource1: TDataSource;
DBGrid1: TDBGrid;
EmpGrpMember: TClientDataSet;
procedure FormCreate(Sender: TObject);
public
end;
[...]
procedure TForm1.FormCreate(Sender: TObject);
var
AField : TField;
begin
AField := TStringField.Create(Self);
AField.FieldKind := fkData;
AField.FieldName := 'GroupGUID';
AField.Size := 255;
AField.DataSet := EmpGrpMember;
AField := TStringField.Create(Self);
AField.FieldKind := fkData;
AField.Size := 255;
AField.FieldName := 'GroupName';
AField.DataSet := EmpGrpMember;
EmpGrpMember.IndexDefs.Add('GroupGUID', 'GroupGUID', [ixPrimary, ixUnique]);
EmpGrpMember.IndexDefs.Add('GroupName', 'GroupName', [ixUnique]);
EmpGrpMember.IndexName := 'GroupName';
EmpGrpMember.CreateDataSet;
EmpGrpMember.InsertRecord(['123', 'www']);
end;
Of course, if you can replicate your problem by modifying the above project, there may be something worth looking into.
Update To debug your problem, set up a handler for the DrawCell event of the grid, like this
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
DataCol := DataCol;
end;
Put a breakpoint in it. When the breakpoint trips, you should find that tracing into the VCL source from it, you eventually arrive at a while
loop inside the DrawCells
procedure in Grids.Pas. Inspecting the while
's condition should show you why you are getting the row displayed twice.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.