- changed status to resolved
Error inside TObjectDataSet with read only property
Issue #389
resolved
The implementation of TObjectDataSet has a slight issue with read only properties.
When the following conditions are satisfied
- The type inside the ODS has at least two published properties, with the read only property not last
- The ODS has declared the fields in the dfm
- The ODS has at least one row
- The ODS is linked to a DataSource
- Some form component adds a DataLink to the DataSource which attempts to read the value of a field corresponding to a property published after the read only one
Then TObjectDataSet.InitRttiPropertiesFromItemType
will set field.ReadOnly := True
which fires the DataLink which attempts to read the property before InitRttiPropertiesFromItemType
has finished initializing the fields. This results in the exception “Property … not found”.
See my attached project for a working example.
My suggested fix is pretty simple, basically just delay the setting of ReadOnly until fProperties has been fully initialized.
procedure TObjectDataSet.InitRttiPropertiesFromItemType(AItemTypeInfo: PTypeInfo);
var
itemType: TRttiType;
prop: TRttiProperty;
field: TField;
readOnlyFields: TArray<TField>;
begin
if AItemTypeInfo = nil then
Exit;
fProperties.Clear;
itemType := TType.GetType(AItemTypeInfo);
for prop in itemType.GetProperties do
begin
if not (prop.Visibility in [mvPublic, mvPublished]) then
Continue;
if Fields.Count > 0 then
begin
field := Fields.FindField(prop.Name);
if Assigned(field) and (field.FieldKind = fkData) then
begin
fProperties.Add(prop);
if not prop.IsWritable then
// Delay setting of field property to prevent event handlers from accessing fields in a partially-initialized state.
System.Insert(field, readOnlyFields, Length(readOnlyFields));
end;
Continue;
end;
if Assigned(fColumnAttributeClass) then
begin
if prop.HasCustomAttribute(fColumnAttributeClass) then
fProperties.Add(prop);
end
else
if prop.Visibility = mvPublished then
fProperties.Add(prop);
end;
for field in readOnlyFields do
field.ReadOnly := True;
end;
Comments (2)
-
repo owner -
reporter Thanks Stefan, yes this does look like a duplicate of
#314and I was reporting this against 1.2.x (sorry for missing the version in the report). - Log in to comment
Thanks for reporting.
However I cannot reproduce this with 2.0 (develop) and the code you posted looks different from the code in develop, thus I assume you are reporting this against 1.2.x (you could have selected the version when reporting to leave no doubt).
I assume the added DisableControls/EnableControls in develop is what fixes this - so probably this is kind of a duplicate of
#314