遍历 cxgrid 上的记录并更新 field/column

Loop through records on a cxgrid and update a field/column

我有一个 cxGrid,我在其中对 select 某些记录应用过滤器。完成后,我希望能够更新网格中的 field/column 以标记要用于下一个操作的每条记录。 我还没弄明白

可能是我描述的问题不够具体。 我有 cxGrid,我在其中应用了过滤器 selecting 一些记录。 然后我需要做的是单击列标题,然后将这些记录的名为 fldselected 的字段设置为 True。

查看 https://www.devexpress.com/Support/Center/Question/Details/A1095,来自 Dev Express 的文章。不要被这篇文章已有 11 年历史的事实所蒙蔽。同样的技术仍然适用。您可以在代码或网格编辑器中进行设置。

  1. 在网格编辑器中创建列。
  2. 将列 DataBinding.ValueType 设置为布尔值(如果这是您希望复选框表示的内容)
  3. 设置数据控制器的 KeyFieldNames 属性。很重要!我花了好几个小时苦思冥想一个无法正常工作的未绑定列,结果发现没有设置 KeyFieldNames。

可以在下一个操作中使用 DataController Records 或 Values 数组引用未绑定的列,具体取决于您的设置方式。因为它是未绑定的,所以您不能通过底层数据集引用它。

你更新的 q 要求的是直接的,并且像往常一样使用 Devex 的东西,它是 只要你能找到进入它的方式,都在 OLH 中。

查找当前匹配过滤器的行的一种方法是使用

cxGrid1DBTableView1.DataController.FilteredRecordIndex[]

属性。然后您可以在数据集中找到该记录以使用

以某种方式处理它
cxGrid1DBTableView1.DataController.LocateByKey().

更新: 这个答案的原始版本假设数据集有一个整数 ID 字段。 正如 OP 所说他使用 GUID,我已经相应地对其进行了更新。

假设 TClientDataSet CDS1 具有字段 Guid:TGuidField,名称:TStringfield,大小为 32 和 Selected : TBooleanField 并连接到 一个启用过滤的 TcxGrid 的 cxDBTableView。

  • 确保 cxGrid1DBTableView1.DataController.KeyFieldNames 设置为 'Guid'。

  • 将常规 TDBGrid 添加到表单并将其指向与 TcxGrid 相同的数据源。重点 这是为了便于验证代码是否按要求工作。

  • 在单元中加入下面的代码,将cxDBTableView1的OnColumnHeaderClick指向 处理程序 cxGrid1DBTableView1ColumnHeaderClick,以及表单在 FormCreate 的 OnCreate。

编译器 & 运行

代码:

procedure TForm1.cxGrid1DBTableView1ColumnHeaderClick(Sender: TcxGridTableView;
    AColumn: TcxGridColumn);
begin
  if AColumn = cxGrid1DBTableView1Name then
    ProcessFilteredRecords;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  AGuid : TGuid;
  i : Integer;
  lResult : Longint;
begin
  CDS1.IndexFieldNames := 'Name';
  CDS1.CreateDataSet;

  for i:= 0 to 6 do begin
    lResult := SysUtils.CreateGUID(AGuid);
    CDS1.Insert;
    CDS1.FieldByName('Name').AsString := Chr(Ord('A') + i);
    CDS1.FieldByName('Guid').AsString := GuidToString(AGuid);
    CDS1.FieldByName('Selected').AsBoolean := False;
    CDS1.Post;
  end;

  CDS1.First;
end;

procedure TForm1.ProcessFilteredRecords;
var
  V : Variant;
  i,
  Index: Integer;
  BM : TBookMark;
begin

  BM := CDS1.GetBookMark;
  CDS1.DisableControls;
  try
    for i := 0 to cxGrid1DBTableView1.DataController.FilteredRecordCount - 1 do begin
      Index := cxGrid1DBTableView1.DataController.FilteredRecordIndex[i];
      // Next, get the GUID value of the row
      V := cxGrid1DBTableView1.DataController.Values[Index, 0];
      if cxGrid1DBTableView1.DataController.LocateByKey(V) then begin
        CDS1.Edit;
        CDS1.FieldByName('Selected').AsBoolean := True;
        CDS1.Post;
      end;
    end;
  finally
    CDS1.EnableControls;
    CDS1.GotoBookmark(BM);
    CDS1.FreeBookmark(BM);
  end;
end;