hcOPF - Dynamic Attribute Properties

One pending improvement in hcOPF is that mediators need to take on the responsibility to get the control to indicate in a consistent fashion that an attribute is required, read/write or readonly.  Currently this is handled using RTTI by the ThcUIObjectBinder when the object is bound.

Objects are bound only once when a form is shown, so each control is only ever updated once to reflect the properties of an attribute.  This can be a problem when you have an attribute whose value you generate a default for in new objects, but allow the user to change it, and for existing objects is ReadOnly.  The way to handle this currently in hcOPF is contrary to the way I’ve typically seen it handled in a Delphi application with non-data aware controls.  Normally the developer would interrogate the object or attribute for it’s status and change the UI control appropriately.

In hcOPF the framework does this for you, most of the time, but in this scenario it cannot.  The reason is that ThcAttributeDef.Properties contain the ReadOnly property and they were never designed to be changed dynamically.  The ThcAttributeDef has no knowledge of the attribute to which it’s attached to prevent circular references, and minimize memory usage.  All ThcAttribute instances created from the ThcAttributeDef have a pointer to the ThcAttributeDef so they can defer calls for information contained in the definition to that object, making it a many to one relationship.  I could have added a multicast event in a ThcAttributeDef.SetProperties method to notify all attributes using the ThcAttributeDef that a property change had occured, and then they could call their Modified method, but this would consume more memory and complicate things for essentially an edge case.

What’s the solution?

First of all, the ThcAttributeMediator you’re using must update the state of the control in the UpdateControl method.  None of the current mediators in the framework do so.  That’s about to change.

Then you need to update the ThcAttributeDef.Properties to include or exclude the apReadOnly property and force an update of the UI control attached to the attribute.  You can do this with a call to

hcObject.ObserverIntf.NotifyOfSubjectUpdate;

OR

UIObjectBinder.GetAttributeBinding(’SomeAttribute’).Mediator.UpdateControl;

OR

since Mediators references are stored in the Tag property of each UI control, this would also work:

(TObject(edSomeControl.Tag) as ThcAttributeMediator).UpdateControl;

The last two calls will be more efficient as it will only update a single control, where the former updates all controls attached to the subject.

In addition you will have to toggle the Enabled property of the control (if applicable) since the current implementation of ThcUIObjectBinder toggles it to False for ReadOnly attributes.

Expect some major changes in the ThcUIObjectBinder and mediators soon…

Leave a Reply