TDBGrid复制行

时间:2019-03-18 19:00:57

标签: delphi

我正在将某些软件从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条记录。

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的条件应该可以向您显示为什么两次显示该行。