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)
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.
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.

Bien sûr, il y a cette remarque
// 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
mais tous les styles que j'ai scanné me donne le feu vert, à chaque fois, il s'agit d'un TRectangle

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;