我正在将某些软件从Delphi 5转换为Delphi 10.2。
我们有一个TDBGrid,它链接到链接到表的数据源。 像这样:
TDBGrid.DataSource := GroupDS;
GroupDS.DataSet := MemoryTable;
MemoryTable中有1条记录。但是,无论我尝试了什么,TDBGrid都在复制单个记录。此行为仅在D10.2中发生。在D5中,它正常显示单个记录。我可以在表上调用RecordCount并验证其中是否只有1条记录。
请告知我是否还有其他信息。这都是在VCL中发生的,因此没有太多代码可显示。我不知道在IDE发行之间的20年间是否可能有所改变。
我编写了一个测试应用程序来重新创建此问题。
代码:
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
我仍然得到相同的结果。我的dbgrid最终显示4'www',它应该只显示1。我在表上执行一个.recordcount,它只显示1条记录。
答案 0 :(得分:4)
下面的最小样本项目实际上可以完全复制您的项目,除了 它使用TClientDataSet作为数据集而不是AddAim。
它只能正确显示一行。因此,问题在于使用 TACRTable的形式。因此,除非您很幸运,并且这里有人认识到 问题并知道如何解决,您需要使用AddAim来解决该问题。
代码:
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;
当然,如果您可以通过修改上述项目来复制问题, 也许值得研究。
更新要调试您的问题,请为网格的DrawCell事件设置一个处理程序,例如
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
DataCol := DataCol;
end;
在其中放置一个断点。断点跳闸时,您应该发现从其中追踪到VCL源,最终您到达了Grids.Pas中while
过程内的DrawCells
循环。检查while
的条件应该可以向您显示为什么两次显示该行。