Firemonkey:为继承样式名的FMXObject触发级联样式刷新
Alright, let's tackle this FMX style refresh scenario you're working with. You've got a TLabel called BaseStyleLabel (with StyleName set to 'BaseStyle') using styles like 'BaseStyle1', 'BaseStyle2', etc., plus a dependent TLabel named MyTextLabel—and you want all these components to update their styles automatically when BaseStyleLabel's StyleLookup changes.
Here are two solid approaches to make this work:
1. Quick & Direct: Manual Refresh via StyleLookupChanged Event
The simplest way is to hook into the OnStyleLookupChanged event of your BaseStyleLabel, then explicitly refresh all related components when the style changes.
Step-by-Step Implementation:
- First, assign the
OnStyleLookupChangedevent to yourBaseStyleLabel(either in the form designer or code). - Add this event handler to refresh both the base label and all dependent labels:
procedure TYourForm.BaseStyleLabelStyleLookupChanged(Sender: TObject); var I: Integer; CurrentComponent: TComponent; begin // Refresh the base style label first (Sender as TLabel).ApplyStyleLookup; (Sender as TLabel).Repaint; // Refresh all dependent MyTextLabel components (adjust the condition to match your setup) for I := 0 to ComponentCount - 1 do begin CurrentComponent := Components[I]; if (CurrentComponent is TLabel) and (CurrentComponent.Name = 'MyTextLabel') then begin (CurrentComponent as TLabel).ApplyStyleLookup; (CurrentComponent as TLabel).Repaint; end; end; end;
Key Notes:
ApplyStyleLookuptells the component to reload its style from the resource based on the currentStyleLookupvalue.Repaintforces the component to redraw immediately—without this, the style change might not show up right away.- If your dependent components are nested inside containers (like
TPanelorTScrollBox), you'll need a recursive function to traverse all child components instead of just the form's direct components.
2. Scalable: Use a Style Manager Class
If you have more than a couple dependent components, a dedicated style manager keeps your code clean and maintainable. This class will handle listening for style changes and refreshing all registered components automatically.
Style Manager Code:
type TStyleManager = class private FBaseStyleComp: TControl; FRegisteredComponents: TList<TControl>; procedure OnBaseStyleLookupChanged(Sender: TObject); public constructor Create(BaseStyleComponent: TControl); destructor Destroy; override; procedure RegisterDependentComponent(Comp: TControl); procedure UnregisterDependentComponent(Comp: TControl); procedure SwitchStyle(const NewStyleName: string); end; constructor TStyleManager.Create(BaseStyleComponent: TControl); begin inherited Create; FBaseStyleComp := BaseStyleComponent; FRegisteredComponents := TList<TControl>.Create; // Hook into the base component's style change event FBaseStyleComp.OnStyleLookupChanged := OnBaseStyleLookupChanged; end; destructor TStyleManager.Destroy; begin FRegisteredComponents.Free; inherited; end; procedure TStyleManager.OnBaseStyleLookupChanged(Sender: TObject); var Comp: TControl; begin // Refresh the base component FBaseStyleComp.ApplyStyleLookup; FBaseStyleComp.Repaint; // Refresh all registered dependent components for Comp in FRegisteredComponents do begin Comp.ApplyStyleLookup; Comp.Repaint; end; end; procedure TStyleManager.RegisterDependentComponent(Comp: TControl); begin if not FRegisteredComponents.Contains(Comp) then FRegisteredComponents.Add(Comp); end; procedure TStyleManager.UnregisterDependentComponent(Comp: TControl); begin FRegisteredComponents.Remove(Comp); end; procedure TStyleManager.SwitchStyle(const NewStyleName: string); begin FBaseStyleComp.StyleLookup := NewStyleName; end;
How to Use It:
// Initialize the manager in your form's OnCreate event procedure TYourForm.FormCreate(Sender: TObject); var StyleMgr: TStyleManager; begin StyleMgr := TStyleManager.Create(BaseStyleLabel); // Register your dependent component(s) StyleMgr.RegisterDependentComponent(MyTextLabel); // Store StyleMgr as a form field if you need to switch styles later end; // To switch styles anywhere in your code: StyleMgr.SwitchStyle('BaseStyle3');
This approach is great if you plan to add more dependent components later—just call RegisterDependentComponent for each new one, and the manager handles the rest.
内容的提问来源于stack exchange,提问作者soddoff Baldrick

