Adding Properties: The "Cache & Apply" Pattern
You must handle properties carefully due to the widget's lifecycle. When your constructor runs, the widget is in the wsCreating state, and its Handle is not yet fully initialized in the DOM. You cannot write to Handle.style at this stage.
The correct pattern is to cache the value in a private field, and then apply it when the widget is ready.
- Define your property with a private field (e.g., fMyText).
- Your setter method writes to fMyText if the widget is not ready. If it is ready (wsReady), it writes directly to the DOM Handle.
- It is also important that you give all published properties a default value, even if it's just an empty string or 0 for int32 fields, this is used by the widget inspector in the IDE to know what the default values are
- Override ApplyPropertyCache. This method is called by the TQTXWidget constructor at the exact moment the Handle is ready, but before your ObjectReady method is called. This is the place to apply all your cached values.
type
TMyWidget = class(TQTXWidget)
private
fMyText: string;
protected
procedure SetMyText(Value: string);
procedure ApplyPropertyCache; override;
public
// ... constructor ...
published
property MyText: string read fMyText write SetMyText;
end;
procedure TMyWidget.SetMyText(Value: string);
begin
if WidgetState = wsReady then
Handle.innerText := Value // Apply immediately if ready
else
fMyText := Value; // Otherwise, cache the value
end;
procedure TMyWidget.ApplyPropertyCache;
begin
inherited;
// Apply all cached values to the newly created Handle
SetMyText(fMyText);
end;
This pattern is used by all standard controls, such as TQTXCustomEdit for its fText and fReadOnly properties.