Bonjour,
Cette question refait surface de temps en temps et je voulais y répondre de façon plus appropriée que ce que j'ai pu faire jusqu'à présent.
En introduction j'écrirais que le TPanel est un vieux reflexe VCL et qu'il me semble totalement inutile en FMX, il suffit de le remplacer par un TRectangle. Toutefois un TRectangle est un composant non stylé donc des subtilités de style peuvent s'échapper ici ou là. (une de ces subtilités est dans la "couleur de fond" proposée, souvent une simple couche de transparence)
Donc, en marge de ma bagarre avec les TStyleObjects et après la découverte d'un accés à la propriété scene des composants stylés je me suis dit (hier) que je pouvais certainement répondre à la demande "Comment changer la couleur d'un Panel en FMX" afin d'en faire une FAQ ou à tout le moins un billet dans mon blog.
Et ce sera sous la forme d'un helper que je propose cette solution (ici dans une unité indépendante)
Utilisation simple, on ajoute l'unité dans la liste des uses et d'un simple Panel1.ChangeColor(TAlphaColors.Red); tous les Panels changent de couleur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 unit PanelHelper; interface uses System.SysUtils,System.UITypes, FMX.StdCtrls, FMX.Types, FMX.Controls; type TPanelHelper = class helper for TPanel procedure ChangeColor(const NewColor : TAlphaColor); end; implementation { TPanelHelper } uses FMX.Styles, FMX.Styles.Objects, FMX.Objects; procedure TPanelHelper.ChangeColor(const NewColor: TAlphaColor); var AStyle, aFMxObj: TFMXObject; stname : String; begin if assigned(self.Scene) then begin if not Assigned(self.Scene.StyleBook) then aStyle := TStyleManager.ActiveStyleForScene(Self.Scene) else aStyle := Self.Scene.StyleBook.Style; end; if stname.IsEmpty then stname := 'panelstyle'; aFMxObj := AStyle.FindStyleResource(stname); if Assigned(aFMxObj) AND (aFMxObj is TRectangle) // attention, fonction du style n'est pas forcément un Trectangle. // cela peut être un tstyleobject cas jamais détecté sur les styles testés then begin TRectangle(aFMxObj).Fill.Color := NewColor; TStyleManager.UpdateScenes; end; end; end.
Bien sûr, il y a cette remarque
mais tous les styles que j'ai scanné me donne le feu vert, à chaque fois, il s'agit d'un TRectangle// attention, fonction du style n'est pas forcément un TRectangle.
// cela peut être un tstyleobject cas jamais détecté sur les styles testés
Donc, c'est fonctionnel mais et j'en viens là à ma question, comment retrouver par la suite l'état initial et là, je séche. Sauf à mémoriser la/les* propriété/s je ne vois pas comment accéder au style de la forme et non de la scene (ce qui est ma foi assez hilarant quand on pense que je n'ai découvert la scene d'un composant que récemment !)
Jusque là mes tentatives
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 // renvoi la "couleur" du panel : OK function TPanelHelper.GetColor: TAlphaColor; var AStyle, aFMxObj: TFMXObject; stname : String; begin if assigned(self.Scene) then begin if not Assigned(self.Scene.StyleBook) then aStyle := TStyleManager.ActiveStyleForScene(Self.Scene) else aStyle := Self.Scene.StyleBook.Style; end; if stname.IsEmpty then stname := 'panelstyle'; aFMxObj := AStyle.FindStyleResource(stname); if Assigned(aFMxObj) AND (aFMxObj is TRectangle) // attention, fonction du style n'est pas forcément un Trectangle. // cela peut être un tstyleobject cas jamais détecté sur les styles testés then result:=TRectangle(aFMxObj).Fill.Color; end; // Obtenir la "couleur" du style : Pas OK function TPanelHelper.GetDefaultColor(const aStyle : TStyleBook): TAlphaColor; var aFMxObj: TFMXObject; begin aFMxObj := Self.Scene.StyleBook.Style.FindStyleResource('panelstyle'); if Assigned(aFMxObj) AND (aFMxObj is TRectangle) // attention, fonction du style n'est pas forcément un Trectangle. // cela peut être un tstyleobject cas jamais détecté sur les styles testés then result:=TRectangle(aFMxObj).Fill.Color; // il manque le else end;
ont échouées
*Les, car on pourrait jouer sur d'avantage de propriétés du TRectangle en exemple l'épaisseur du trait
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 procedure TPanelHelper.ChangeBorder(const NewColor: TAlphaColor; const NewThickness: Single); var AStyle, aFMxObj: TFMXObject; stname : String; begin if assigned(self.Scene) then begin if not Assigned(self.Scene.StyleBook) then aStyle := TStyleManager.ActiveStyleForScene(Self.Scene) else aStyle := Self.Scene.StyleBook.Style; end; if stname.IsEmpty then stname := 'panelstyle'; aFMxObj := AStyle.FindStyleResource(stname); if Assigned(aFMxObj) AND (aFMxObj is TRectangle) // attention, fonction du style n'est pas forcément un Trectangle. // cela peut être un tstyleobject cas jamais détecté sur les styles testés then begin TRectangle(aFMxObj).Stroke.Color := NewColor; TRectangle(aFMxObj).Stroke.Thickness := NewThickness; TStyleManager.UpdateScenes; end; end;
Partager