Как получить доступ к управлению вложенными стилями

У меня есть пользовательский стиль управления FireMonkey. Его стиль содержит несколько уровней вложенных элементов управления.

Мне нужно получить доступ к этим элементам управления и изменить некоторые свойства стиля во время выполнения. Для этого я использую FindStyleResource<T> метод.

У меня нет проблем с получением первого уровня элементов управления внутри стиля. Но доступ к элементам управления на втором уровне с FindStyleResource не удается, если родительский элемент управления является потомком TStyledControl,

Вопрос в том, как получить доступ к этим вложенным элементам управления стилями независимо от их родительского типа?

Стиль:

object TStyleContainer
  object TLayout
    StyleName = 'MyHeader'
    Align = Center
    Size.Width = 100.000000000000000000
    Size.Height = 50.000000000000000000
    Size.PlatformDefault = False
    Visible = False
    TabOrder = 0
    object TLabel
      StyleName = 'title'
      Align = Client
      StyledSettings = [Style]
      Size.Width = 36.000000000000000000
      Size.Height = 50.000000000000000000
      Size.PlatformDefault = False
      TextSettings.HorzAlign = Center
      Text = 'Title'
    end
    object TLayout
      StyleName = 'green'
      Align = MostLeft
      Size.Width = 32.000000000000000000
      Size.Height = 50.000000000000000000
      Size.PlatformDefault = False
      object TPath
        StyleName = 'greenpath'
        Align = Fit
        Data.Path = {
          07000000000000000000404100000041010000000000C0400000604101000000
          B81EED405C8F76410100000000004041AE472D410100000052B884415C8F7641
          010000000000904100006041030000000000404100000041}
        Fill.Color = claGreen
        HitTest = False
        Size.Width = 32.000000000000000000
        Size.Height = 50.000000000000000000
        Size.PlatformDefault = False
        Stroke.Kind = None
        WrapMode = Fit
      end
    end
    object TSpeedButton
      StyleName = 'red'
      Align = MostRight
      Position.X = 68.000000000000000000
      Size.Width = 32.000000000000000000
      Size.Height = 50.000000000000000000
      Size.PlatformDefault = False
      object TPath
        StyleName = 'redpath'
        Align = Fit
        Data.Path = {
          07000000000000000000404100000041010000000000C0400000604101000000
          B81EED405C8F76410100000000004041AE472D410100000052B884415C8F7641
          010000000000904100006041030000000000404100000041}
        Fill.Color = claRed
        HitTest = False
        Size.Width = 32.000000000000000000
        Size.Height = 32.571426391601560000
        Size.PlatformDefault = False
        Stroke.Kind = None
        WrapMode = Fit
      end
    end
  end
end

Контроль:

type
  TMyHeader = class(TStyledControl)
  protected
    procedure ApplyStyle; override;
    function GetDefaultStyleLookupName: string; override;
   end;

procedure TMyHeader.ApplyStyle;
var
  LGreen: TLayout;
  LGreenPath: TPath;
  LRed: TSpeedButton;
  LRedPath: TPath;
begin
  inherited;
  if FindStyleResource<TLayout>('green', LGreen) then
    begin
      // following call will find greenpath control 
      if FindStyleResource<TPath>('greenpath', LGreenPath) then
        LGreenPath.Fill.Color := TAlphaColorRec.Blue;
    end;

  if FindStyleResource<TSpeedButton>('red', LRed) then
    begin 
      // following call will fail to find find redpath control  
      if FindStyleResource<TPath>('redpath', LRedPath) then
        LRedPath.Fill.Color := TAlphaColorRec.Blue;

      // this variant also fails
      if LRed.FindStyleResource<TPath>('redpath', LRedPath) then
        LRedPath.Fill.Color := TAlphaColorRec.Blue;
    end;
end;

function TMyHeader.GetDefaultStyleLookupName: string;
begin
  Result := 'MyHeader';
end;

Оригинальный стиль:

Изменен стиль (был успешно изменен только цвет зеленой стрелки)

В ApplyStyle метод я могу получить доступ greenpath от стиля и измените его цвет на синий. Однако я не могу получить redpath с помощью FindStyleResource метод.

1 ответ

Стандартный способ доступа к элементам стиля - через TFMXObject итерировать объекты стиля детей.

Попробуй это:

procedure TMyHeader.ApplyStyle;
var
  objFMX,
  inObjFMX: TFMXObject;
  LRed: TSpeedButton;
  LRedPath: TPath;
begin
  inherited;
  objFMX:=FindStyleResource('red');
  if assigned(objFMX) and (objFMX is TSpeedButton) then
  begin
    LRed:=objFMX as TSpeedButton;
    inObjFMX:=LRed.FindStyleResource('redpath');
    if assigned(inObjFMX) and (inObjFMX is TPath) then
    begin
      LRedPath:=inObjFMX as TPath;
     LRedPath.Fill.Color := TAlphaColorRec.Blue;
   end;
  end
end;

Обновленный код: FindStyleResource не работает в приведенном выше коде. Другой подход используется ниже.

procedure TMyHeader.ApplyStyle;
var
  objFMX,
  inObjFMX: TFMXObject;
  LRedPath: TPath;
begin
  inherited;
  objFMX:=FindStyleResource('red');
  if assigned(objFMX) and (objFMX is TSpeedButton) then
  begin
    for inObjFMX in objFMX.Children do
    begin
      if inObjFMX is TPath then
      begin
        LRedPath:=inObjFMX as TPath;
        LRedPath.Fill.Color:=TAlphaColorRec.Blue;
        Break;
      end;
    end;
  end;
end;

Это работает на 10.2

Другие вопросы по тегам