delphi - Updating field in cxGrid acting strange -
i have function update cxgrid made answers loop through records on cxgrid , update field/column
but acting bit strange. if open form cxgrid , click columnheader without doing else, records updateted ok. if 'selectorbar' moved away top, record marked not updated. sure property needs changed, one.
the variable fselected set false @ formshow , ther user can unselect records well.
procedure tfrmcontactsselect.colcontactselectedheaderclick(sender: tobject); var i: integer; index: integer; bookmark : tbookmark; contact: variant; begin if fmulti = true begin screen.cursor := crhourglass; fselected := not fselected; bookmark := qrycontacts.getbookmark; qrycontacts.disablecontrols; try := 0 grdcontactsview1.datacontroller.filteredrecordcount - 1 begin index := grdcontactsview1.datacontroller.filteredrecordindex[i]; contact := grdcontactsview1.datacontroller.values[index, 4]; if grdcontactsview1.datacontroller.locatebykey(contact) begin qrycontacts.edit; qrycontacts.fieldbyname('fldcontact_selected').asboolean := fselected; qrycontacts.post; end; end; qrycontacts.enablecontrols; qrycontacts.gotobookmark(bookmark); qrycontacts.freebookmark(bookmark); end; screen.cursor := crdefault; end; end; delphi xe7, devexpress 14.2.2, unidac 5.5.12 db access
comment: have ended following solution based on answer , input martyna
procedure tfrmcontactsselect.colcontactselectedheaderclick(sender: tobject); var i: integer; index: integer; markedrecord: variant; currentrecord: variant; begin if fmulti = true begin screen.cursor := crhourglass; fselected := not fselected; index := grdcontactsview1.datacontroller.focusedrecordindex; markedrecord := grdcontactsview1.datacontroller.values[index, colcontactguid.id]; try := 0 grdcontactsview1.datacontroller.filteredrecordcount - 1 begin index := grdcontactsview1.datacontroller.filteredrecordindex[i]; currentrecord := grdcontactsview1.datacontroller.values[index, colcontactguid.id]; if grdcontactsview1.datacontroller.locatebykey(currentrecord) begin grdcontactsview1.datacontroller.edit; grdcontactsview1.datacontroller.seteditvalue(colcontactselected.id, fselected, evstext); grdcontactsview1.datacontroller.post; end; end; grdcontactsview1.datacontroller.locatebykey(markedrecord); end; screen.cursor := crdefault; end; end;
i can reproduce problem using sample project posted in answer other q.
try this: add tmemo form, , inside 'if grdcontactsview1.datacontroller.locatebykey(contact) then' block, write value of row-unique datafield , selected datafield value memo.
then, when row other top row selected 1 row listed twice in memo, selected both false , true, , 1 of rows in filter isn't listed @ all, think accounts behaviour you're seeing. if comment out .edit .. .post lines, correctly lists rows in filter.
so evidently doing selected field changes inside block iterated filteredrecordindex property of dbtableview what's causing problem.
personally, find goes bit against grain modify dataset rows in code via db-aware control (because end fighting db-awareness of control), in case, it's straightforward processing via dbtableview of cxgrid.
procedure tform1.processfilteredrecords; var prevv, v : variant; i, index: integer; s : string; begin // first, pick reference current record // can return afterwards index := cxgrid1dbtableview1.datacontroller.focusedrecordindex; prevv := cxgrid1dbtableview1.datacontroller.values[index, 0]; try := 0 cxgrid1dbtableview1.datacontroller.filteredrecordcount - 1 begin index := cxgrid1dbtableview1.datacontroller.filteredrecordindex[i]; v := cxgrid1dbtableview1.datacontroller.values[index, 0]; if cxgrid1dbtableview1.datacontroller.locatebykey(v) begin cxgrid1dbtableview1.datacontroller.edit; // 2 index of selected column in grid if cxgrid1dbtableview1.datacontroller.seteditvalue(2, true, evstext) caption := 'ok' else caption := 'failed'; cxgrid1dbtableview1.datacontroller.post; end; end; if cxgrid1dbtableview1.datacontroller.locatebykey(prevv) caption := 'ok' else caption := 'failed'; end; end; another way avoid problem change selected states in 2 steps:
iterate filteredrecordindex build list of rows change - in case list of guids
then, iterate list of rows , update selected states.
code:
procedure tform1.processfilteredrecords; var v : variant; i, index: integer; bm : tbookmark; s : string; tl : tstringlist; begin memo1.lines.clear; tl := tstringlist.create; try := 0 cxgrid1dbtableview1.datacontroller.filteredrecordcount - 1 begin index := cxgrid1dbtableview1.datacontroller.filteredrecordindex[i]; v := cxgrid1dbtableview1.datacontroller.values[index, 0]; if cxgrid1dbtableview1.datacontroller.locatebykey(v) begin if cds1.fieldbyname('selected').asboolean s := 'true' else s := 'false'; s := cds1.fieldbyname('name').asstring + ' ' + s; memo1.lines.add(s); tl.add(cds1.fieldbyname('guid').asstring); end; end; try bm := cds1.getbookmark; cds1.disablecontrols; := 0 tl.count - 1 begin if cds1.locate('guid', tl[i], []) begin cds1.edit; cds1.fieldbyname('selected').asboolean := true; cds1.post; end end; cds1.enablecontrols; cds1.gotobookmark(bm); cds1.freebookmark(bm); end; tl.free; end; end; like you, expecting changing property or 2 of cxgrid might avoid problem without code, haven't been able find does.
Comments
Post a Comment