An ECO IV databinding gotcha
Last night while working on an ECO IV VCL.NET application I encountered some behaviour which was initially unexpected, but made perfect sense upon reflection.
I have a modal dialog which is used to edit an ECO class instance selected in a TDBGrid. This form had a TReferenceHandle which had its Element property set to the passed in class instance. There were some databound controls bound to this reference handle, as well as some non-bound controls which were used to collect data which was manually applied to the class instance. Below is the code that I was using to do the population :-
procedureTWorkItemEditForm.btnOKClick(Sender: TObject);varlWorkItem: BillableWorkItem;beginifrhRoot.State <> dsEditthenrhRoot.Edit; lWorkItem := BillableWorkItem(rhRoot.Element.AsObject); lWorkItem.StartTime := AddDateTime(dtpStartDate.Date, dtpStartTime.Time); lWorkItem.EndTime := AddDateTime(dtpEndDate.Date, dtpEndTime.Time); rhRoot.Post;end;
When testing this code, I noticed that only the attributes bound to databound controls had the changes persisted after the dialog was invoked. Any changes to the manually populated attributes were ignored.
While this behaviour was initially unexpected, this was largely due to my lack of game time with TDataset/TDatasource based VCL applications recently. The way a TDataset would normally work is to populate an internal buffer with the current data when TDataset.Edit is called, and use this buffer to persist the changes when TDataset.Post is called. Any changes made via databound controls will act on the contents of this buffer, and these changes are persisted to the Eco class attributes when TDataset.Post is called. But any changes made outside of this buffer by acting on the class instance directly will be overwritten by the contents of the buffer when the dataset is posted.
Once this has been realised, the solution to my problem was easy. Actually, there are at least two ways to solve this problem, and I’ll outline them below, starting with my current solution :-
procedureTWorkItemEditForm.btnOKClick(Sender: TObject);varlWorkItem: BillableWorkItem;beginifrhRoot.State = dsEditthenrhRoot.Post;
//Need to set the non-bound attributes after calling rhRoot.Post.lWorkItem := BillableWorkItem(rhRoot.Element.AsObject); lWorkItem.StartTime := AddDateTime(dtpStartDate.Date, dtpStartTime.Time); lWorkItem.EndTime := AddDateTime(dtpEndDate.Date, dtpEndTime.Time);end;
Because the changes are made to the ECO class after the call to TReferenceHandle.Post, we no longer have to worry about the dataset buffer overwriting our changes. Another approach would be to edit the buffer directly :-
procedureTWorkItemEditForm.btnOKClick(Sender: TObject);varlWorkItem: BillableWorkItem;beginifrhRoot.State <> dsEditthenrhRoot.Edit; rhRoot.FieldByName('StartTime').AsDateTime := AddDateTime(dtpStartDate.Date, dtpStartTime.Time); rhRoot.FieldByName('EndTime').AsDateTime := AddDateTime(dtpEndDate.Date, dtpEndTime.Time); rhRoot.Post;end;
So in summary, this was a classic case of ECO doing what it was supposed to do, rather than doing what I wanted it to. ![]()
Share This | Email this page to a friend
Posted by David Clegg on September 20th, 2007 under .NET, ECO |

RSS Feed

September 20th, 2007 at 1:34 pm
A more intuitive solution would be that ECO updates the dataset field when the object’s attribute changes. So every attribute change by code is reflected in the bound controls.
September 20th, 2007 at 1:53 pm
Hi Andreas
In general, there are the usual eco subscription mechanism that will ensure that the contents of a handle/dataset will be current if the underlying object changes. I don’t think it will change the buffers of a handle/dataset in editmode though.
September 21st, 2007 at 9:31 am
You missed a LF in the first code snippet.
Great post, Cleggy! You’re on an ECO-roll here
September 21st, 2007 at 1:20 pm
Is that better, Holger? Our WP implementation still has some (known) issues with posting code snippets.