Accessing Style Objects with FindStyleResource - FireMonkey Guide

Back to Styles.

Having a style is no use if you can’t access the objects which make them up. For instance if you are creating a button you will want to be able to set the text.

There are two places you can put code to do this. If you are developing a custom component you can override the ApplyStyle method which is covered in Creating Custom Controls. If you have an existing control you want to modify you can hook into the OnApplyStyleLookup event, which is called after the ApplyStyle methods have run.

In either case the actual process for accessing the style objects is the same. Here we use the OnApplyStyleLookup event to change the text appearance.

procedure TForm1.Button1ApplyStyleLookup(SenderTObject);
var 
OTFMXObject;
begin
  
if Sender is TButton then
  begin
    O 
:= TButton(Sender).FindStyleResource('text');
 if 
O is TText then
   TText
(O).Font.Family := 'Baskerville';
  
end;
end

How This Works

The Sender parameter is, of course, the button whose OnApplyStyleLookup event has fired. After verifying this we call FindStyleResource. This method of TStyledControl searches the style for the styling object with the given StyleName. We know that in the current style the object displaying the caption will be called ‘text’ and be of type TText. (See Style Files and Style Names for more on naming style objects).

We then verify that what is returned is what we where expecting (a TText) and modify it’s properties as appropriate by casting it to the appropriate class.

Gotchas

It may be tempting place code such as the above at random locations within your code, for example when a user clicks a button, and set the changes immediately in the style.

This is perfectly acceptable, but you need to be aware that in FireMonkey components are styled on demand and styles can also be removed on demand. This is done to save memory space by only styling components which are actually visible. E.g. the items in a list box may only be styled as they are scrolled into view and their styles may be removed when they scroll out of view.

Thus,

  • There might not be a style loaded even though a valid style is available. You therefore must verify that the values returned by FindStyleResource are non-nil before using them.
  • The style may be unloaded (and reloaded) at any time. If you are setting style data at odd moments you need to cache the data and set it again when the style is applied (using OnStyleLookup or ApplyStyle).
  • It’s tempting to cache items from the style. E.g. in the example above you could keep a copy of the TText object returned to save further calls to FindStyleResource. But, as and when the style is unloaded the reference will become invalid. If you have a custom control and have cached the object from ApplyStyle then you must override FreeStyle and nil the reference. If you are using OnStyleLookup, there is no matching event when the style is unloaded and therefore you mustn’t cache style objects.

Categories:

div title=