• Delphi cxGrid 选择速度优化


    表格有一个选择列,用来选择数据后。提取选中的记录做某些事,这种是很常见的。

    现有以下需求:

    右键全选 、反选(支持选择过滤后的数据)

    如果全部采取DB感知的方式 ,数据多的时候很卡。测试1000多条就很卡了

    解决方案:

     //改成智能新
       cxGridDB.DataController.DataModeController.SyncMode := True;
       cxGridDB.DataController.DataModeController.SmartRefresh := True;
       //设置key 这个是关键,查询出来的数据要有ID 唯一
       cxGridDB.DataController.KeyFieldNames := 'id';
       //选择列改成非绑定的
       CxCol_xz.DataBinding.FieldName := '';
       CxCol_xz.DataBinding.ValueType := 'Boolean';
       CxCol_xz.PropertiesClassName := 'TcxCheckBoxProperties';
       TcxCheckBoxProperties(CxCol_xz.Properties).NullStyle := nssUnchecked;

    全选 、反选:

    //要加beginupdate 、endupdate 速度会很快
    //直接操作ViewData 的数据就可以了
     cxGridDB.BeginUpdate();
      for i := 0 to cxGridDB.ViewData.RowCount -1 do
       cxGridDB.ViewData.Rows[i].Values[CxCol_xz.Index] := xz;
      cxGridDB.EndUpdate;

    获取选择的数据:思路是过滤出选择=True的 循环去修改ADO 里的数据。也可不用修改,但是要过滤后去取值。这里看应用场景

    procedure DocxGridViewChoose(var View:TcxGridDBTableView; idColumn, AChooseColumn :TcxGridDBColumn; AChooseFieldName:string='xz');
    var
     Ds:TADOQuery;
     OrgFocusRow ,i: integer;
     mStream:TMemoryStream;
     OrgFiltered:Boolean;
     idFieldName:string;
    begin
     Ds := TADOQuery(View.DataController.DataSource.DataSet);
     if Ds= nil then
      Exit;
     if not Ds.IsEmpty then
        View.DataController.Post();
      OrgFocusRow := View.Controller.FocusedRowIndex;
      idFieldName := idColumn.DataBinding.FieldName;
      Ds.DisableControls;
      if not Ds.IsEmpty then
       SetQryFilter(Ds, AChooseFieldName+'=True');
      with Ds do
      begin
       if not IsEmpty then
       begin
        First;
        while not eof do
        begin
         Ds.Edit;
         Ds.FieldByName(AChooseFieldName).Value := False;
         Ds.post;
        end;
       end;    
      end;
      ClearQryFilter(Ds);
      try
       mStream := TMemoryStream.Create;
       mStream.Position:=0;//流指针指向开始位
       View.DataController.Filter.Root.Criteria.SaveToStream(mStream);//将过滤状态存入流
       OrgFiltered := View.DataController.Filter.Active;
       View.DataController.Filter.Root.Clear; //过滤出选择的
       View.DataController.Filter.Root.AddItem(View.Columns[AChooseColumn.Index],foEqual,'True','');
       View.DataController.Filter.Active:=True;//激活过滤
       if View.DataController.FilteredRecordCount>0 then
       begin
        for i := 0 to View.DataController.RowCount-1 do
        begin
         if Ds.Locate(idFieldName,View.ViewData.Rows[i].Values[idColumn.Index], []) then
         begin
          Ds.Edit;
          Ds.FieldByName(AChooseFieldName).Value := True;
          Ds.Post;
         end;
        end;
       end;
      finally
       //恢复原来的过滤
       View.DataController.Filter.Root.Clear;
       mStream.Position:=0;
       View.DataController.Filter.Root.Criteria.LoadFromStream(mStream);
       View.DataController.Filter.Active:=OrgFiltered;
       mStream.Free;
       ds.EnableControls;
       View.Controller.FocusedRowIndex :=  OrgFocusRow;
      end;
    end;

    重新打开窗口时,如何把选择的数据恢复:

    退出时先保存一下对应选中的数据的ID

    //要加beginupdate 、endupdate 速度快很多
    cxGridDB.BeginUpdate();
    if cxGridDB.DataController.LocateByKey(ID) then
            cxGridDB.ViewData.Rows[cxGridDB.DataController.FocusedRowIndex].Values[0] := True;
    cxGridDB.EndUpdate;
  • 相关阅读:
    gbk与utf-8转换
    gdb注意事项
    Ubuntu导入证书
    Ubuntu 修改hosts
    GDB配置与.gdbinit的编写
    linux中用户的主目录~
    关于C++构造函数初始化顺序
    C++中的static关键字的总结
    Flutter移动电商实战 --(2)建立项目和编写入口文件
    Flutter移动电商实战 --(1)项目学习记录
  • 原文地址:https://www.cnblogs.com/BTag/p/16415695.html
Copyright © 2020-2023  润新知