表格有一个选择列,用来选择数据后。提取选中的记录做某些事,这种是很常见的。
现有以下需求:
右键全选 、反选(支持选择过滤后的数据)
如果全部采取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;