1

I try to set the property of an object when filling a ListBox with ListBoxItems. The object is an ellipse added to the style used by the ListBox. The line of code below raises an exception:

ListBoxItem.StylesData['ellipsestyle.fill.Gradient.Points.Points[0].Color'] := newAlphaColor;

As a workaround, I tried to reach the property by getting the ellipsestyle object with ListBoxItem.FindStyleRessource, but the function returns nil.

Thank you !

  • Please, show part of .style file, where new object added. Starting from parent listboxitem style object. – kami Feb 13 '16 at 16:12
  • The object is added by dragging a TEllipse into structure tree when editing default style of listboxitembottomdetail. I can change Fill.Color property (kind=solid) without problem, but I got a access violation if I try to change color property of gradient point (kind=Gradient). – Régent Beaulieu Feb 13 '16 at 17:01

1 Answers1

2

StylesData can`t provide access to 'complex' properties. you can do next workaround:

var
  Obj: TObject;
  myListBoxItem: TListBoxItem;
begin
  // create new item
  myListBoxItem:=TListBoxItem.Create(nil);
  ListBox1.AddObject(myListBoxItem);
  myListBoxItem.StyleLookup:='listboxitembottomdetail';

  myListBoxItem.StylesData['ellipsestyle.fill.Kind']:=TValue.From<TBrushKind>(TBrushKind.Gradient);

  // access to GradientPoints collection 
  Obj:=myListBoxItem.StylesData['ellipsestyle.fill.Gradient.Points'].AsObject;
  if not (Obj is TGradientPoints) then
    Exit;

  TGradientPoints(Obj).Points[0].Color:=TAlphaColorRec.Blanchedalmond;
  TGradientPoints(Obj).Points[1].Color:=TAlphaColorRec.Alpha;

About FindStyleResource:

First place, where you can get access to style object - OnApplyStyleLookup event of specified ListBoxItem. Before OnApplyStyleLookup (for example - immediatelly after creating Listboxitem) you cannot get access to style.

So, move your code to ListBoxItem.OnApplyStyleLookup and change it like this:

procedure TForm2.ListBoxItem1ApplyStyleLookup(Sender: TObject);
var
  FMXObj: TFmxObject;
  Ellipse: TEllipse;
begin
  if not (Sender is TFmxObject) then
    Exit;
  FMXObj:=TFMXObject(Sender).FindStyleResource('ellipsestyle');// get object by it`s "StyleName".
  if not (FMXObj is TEllipse) then
    Exit;

  Ellipse:=TEllipse(FMXObj);
  Ellipse.Fill.Kind:=TBrushKind.Gradient;
  Ellipse.Fill.Gradient.Points.Points[0].Color:=TAlphaColorRec.Blueviolet;
  Ellipse.Fill.Gradient.Points.Points[1].Color:=TAlphaColorRec.Greenyellow;
end;

Also, you can force load style (this is not recommended way - by default, style for object loaded at the time of first painting):

var
  FMXObj: TFmxObject;
  Ellipse: TEllipse;
  myListBoxItem: TListBoxItem;
begin
  myListBoxItem:=TListBoxItem.Create(nil);
  ListBox1.AddObject(myListBoxItem);
  myListBoxItem.StyleLookup:='listboxitembottomdetail';

  // force load style
  myListBoxItem.NeedStyleLookup;
  myListBoxItem.ApplyStyleLookup; // this method also call OnApplyStyleLookup event

  FMXObj:=myListBoxItem.FindStyleResource('ellipsestyle');
  if not (FMXObj is TEllipse) then
    Exit;

  Ellipse:=TEllipse(FMXObj);
  Ellipse.Fill.Kind:=TBrushKind.Gradient;
  Ellipse.Fill.Gradient.Points.Points[0].Color:=TAlphaColorRec.Blanchedalmond;
  Ellipse.Fill.Gradient.Points.Points[1].Color:=TAlphaColorRec.Alpha;
kami
  • 1,438
  • 1
  • 16
  • 23
  • Very interesting. The line Obj:=myListBoxItem.StylesData['ellipsestyle.fill.Gradient.Points'].AsObject always returne nil (myListBoxItem.StylesData['ellipsestyle].AsObject also). I can't move my code in OnApplyStylelookUp because my colors come from dataset and the creation of ListItem is in "while not EOF" loop. – Régent Beaulieu Feb 14 '16 at 13:43
  • @RégentBeaulieu again - please, show part of .style file, where new object added. If you dont change anything after drop TEllipse - the new object get name `ellipse1style`. You must change `StyleName` of ellipse to needed. – kami Feb 14 '16 at 15:41
  • Here the part of .style file (Jet.style modified) object TEllipse StyleName = 'ellipsestyle' Fill.Color = xFFFFC800 Position.X = 6.000000000000000000 Position.Y = 18.000000000000000000 Size.Width = 9.000000000000000000 Size.Height = 9.000000000000000000 Size.PlatformDefault = False Stroke.Kind = None end – Régent Beaulieu Feb 14 '16 at 22:18
  • The line "myListBoxItem.StylesData['ellipsestyle.fill.Kind']:=TValue.From(TBrushKind.Gradient);" as the result attended and I can see the object fill.kind change to gradient in my list. But still have nil returned from "myListBoxItem.StylesData['ellipsestyle.fill.Gradient.Points'].AsObject". I use Delphi Seattle updtate 1 version. – Régent Beaulieu Feb 14 '16 at 22:22
  • @RégentBeaulieu Hmmmm... strange. I use same Delphi version and my code (all variants) works fine both on Windows and iOS. Ok, can you try following steps: 1. in StyleBook editor add destination platform and load Jet style for this platform from corresponding folder. 2. Add `TEllipse` to `listboxitembottomdetail` and change it's `StyleName` to `ellipsestyle`. 3. Launch on specified platform. – kami Feb 15 '16 at 10:16