【问题标题】:FMX: dropping selfmade component on form duplicates subcomponentsFMX:在表单上放置自制组件会复制子组件
【发布时间】:2019-04-05 00:26:45
【问题描述】:

我创建了我自己的进度条 (TProgressBalken),它由一个 TRectangle 组成,其中还有另一个颜色不同的 TRectangle (a),其宽度随进度值 (0..100) 而变化。最后,一个 Tlabel 位于其顶部,将当前值显示为文本。 在运行时创建此组件时一切正常。

在新的多设备表单(IDE 设置为 32 位窗口)上放置它时,它也可以正常工作。 但是当将 IDE 切换到 Android 时,TRectangle(a) 和 Label 在 fmx 文件中重复,我现在看到标签绘制了两次。 Delphi 抱怨重复的项目。

本来我没有给TRectangle(a)和Label赋值,但是Delphi报错了,所以我在创建的时候给了名字,但是实际问题依旧。

知道缺少什么吗?

这是我的组件:

unit ProgressBalken;

interface
uses
  System.SysUtils, System.Classes, System.UITypes,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.StdCtrls, FMX.Graphics, FMX.Objects;

type
  TProgressBalken = class(TRectangle)
    procedure FormDestroy(Sender: TObject);
    procedure BalkenUpdate;
    procedure SizeUpdate;
    procedure SetValue(v: integer);
    procedure SetUnits(v: string);
    procedure SetBalkenColor(v: TAlphaColor);
    function  GetBalkenColor: TAlphaColor;
    procedure aResize(Sender: TObject);
  private
    Balken: TRectangle;
    labelx: Tlabel;
    fValue: integer;
    funits: string;
  public
    constructor Create(AOwner: TComponent); override;

  published
    property Value: integer read fValue write SetValue;
    property ValueUnits: string read fUnits write SetUnits;
    property BalkenColor: TAlphaColor read GetBalkenColor write SetBalkenColor; // stored IsColorStored;
  end;

  procedure Register;

implementation
uses
windows, System.Math;

constructor TProgressBalken.Create(AOwner: TComponent);
begin
  inherited;
  width:=100;
  height:= 40;
  fValue:= 1;
  fUnits:= '';
  Parent:= TForm(AOwner);
  Fill.Color:= System.UITypes.TAlphaColorRec.red; //Null;
  Balken:= TRectangle.Create(self);
  Balken.Parent:= self;
  Balken.Position.X:= 0;
  Balken.Position.Y:= 0; ;
  Balken.Fill.Color:= System.UITypes.TAlphaColorRec.Aqua;
  Balken.name:= 'balken'+name;
  labelx:= Tlabel.Create(self);
  labelx.Parent:= Balken;
  labelx.name:= 'labelx'+name;
  OnResize:= aResize;
  SizeUpdate;
end;

procedure TProgressBalken.aResize(Sender: TObject);
begin
 SizeUpdate;
end;

procedure TProgressBalken.FormDestroy(Sender: TObject);
begin
  Balken.Free;
  labelx.Free;
  inherited;
end;

procedure TProgressBalken.SizeUpdate;
var
 h, y: single;
begin
  Balken.Height:= Height;
  Balken.Width:= Width;
  h:= System.Math.min(40, Height);
  labelx.StyledSettings:= labelx.StyledSettings - [TStyledSetting.Size];
  if h>20 then
    labelx.TextSettings.Font.Size:= round(0.5 * h)
  else
    labelx.TextSettings.Font.Size:= round(0.7 * h);
  y:= (height / 2) - (labelx.TextSettings.Font.Size / 2) -2;
  labelx.Position.Y:= System.Math.max(-5, y);
  labelx.Position.X:=  Width / 4;
  BalkenUpdate;
end;

procedure TProgressBalken.BalkenUpdate;
begin
  Balken.Width:= fValue / 100 *(width - 2*Balken.Position.x);
  labelx.Text:= IntToStr(fValue) +' ' +fUnits;
end;

procedure TProgressBalken.SetValue(v: integer);
var i: integer;
begin
  v:= System.Math.max(v, -1);
  fValue:= System.Math.min(v, 100);
  BalkenUpdate;
end;

procedure TProgressBalken.SetUnits(v: string);
begin
  fUnits:= v;
  SetValue(fValue);
end;

function TProgressBalken.GetBalkenColor: TAlphaColor;
begin
 result:= Balken.Fill.Color;
end;

procedure TProgressBalken.SetBalkenColor(v: TAlphaColor);
begin
  Balken.Fill.Color:= v;
end;

procedure Register;
begin
  RegisterComponents('3s_Spezielles', [TProgressBalken]);
end;

initialization
  RegisterFmxClasses([TProgressBalken]);

end.

这是删除我的组件 TProgressBalken 后的 fmx
IDE 设置为 32 位 Windows

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 480
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 3
  object Button1: TButton
    Position.X = 56.000000000000000000
    Position.Y = 168.000000000000000000
    TabOrder = 1
    Text = 'Button1'
    OnClick = Button1Click
  end
  object ProgressBalken1: TProgressBalken
    Fill.Color = claRed
    Position.X = 40.000000000000000000
    Position.Y = 64.000000000000000000
    Size.Width = 100.000000000000000000
    Size.Height = 40.000000000000000000
    Size.PlatformDefault = False
    Value = 1
    BalkenColor = claAqua
    object balken: TRectangle
      Fill.Color = claAqua
      Size.Width = 1.000000000000000000
      Size.Height = 40.000000000000000000
      Size.PlatformDefault = False
      object labelx: TLabel
        StyledSettings = [Family, Style, FontColor]
        Position.X = 25.000000000000000000
        Position.Y = 8.000000000000000000
        TextSettings.Font.Size = 20.000000000000000000
        Text = '1 '
      end
    end
  end
end

这是将IDE设置为Android后的fmx
对象“balken”现在被插入两次

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 480
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 0
  object Button1: TButton
    Position.X = 56.000000000000000000
    Position.Y = 168.000000000000000000
    TabOrder = 1
    Text = 'Button1'
    OnClick = Button1Click
  end
  object ProgressBalken1: TProgressBalken
    Fill.Color = claRed
    Position.X = 40.000000000000000000
    Position.Y = 64.000000000000000000
    Size.Width = 100.000000000000000000
    Size.Height = 40.000000000000000000
    Size.PlatformDefault = False
    Value = 1
    BalkenColor = claAqua
    object balken: TRectangle
      Fill.Color = claAqua
      Size.Width = 1.000000000000000000
      Size.Height = 40.000000000000000000
      Size.PlatformDefault = False
      object labelx: TLabel
        StyledSettings = [Family, Style, FontColor]
        Position.X = 25.000000000000000000
        Position.Y = 8.000000000000000000
        TextSettings.Font.Size = 20.000000000000000000
        Text = '1 '
      end
    end
    object balken: TRectangle
      Fill.Color = claAqua
      Size.Width = 1.000000000000000000
      Size.Height = 40.000000000000000000
      Size.PlatformDefault = False
      object labelx: TLabel
        StyledSettings = [Family, Style, FontColor]
        Position.X = 25.000000000000000000
        Position.Y = 8.000000000000000000
        TextSettings.Font.Size = 20.000000000000000000
        Text = '1 '
      end
    end
  end
end

【问题讨论】:

    标签: delphi firemonkey


    【解决方案1】:

    在 FMX 中,对于您在构造函数中创建的任何子组件,以便在设计时和 DFM 流式处理中可用,您需要将组件的 Stored 属性设置为 False,并调用 SetSubComponent()就可以了,例如:

    constructor TProgressBalken.Create(AOwner: TComponent);
    begin
      inherited;
      ...
      Balken := TRectangle.Create(self);
      Balken.SetSubComponent(True);
      Balken.Stored := False;
      ...
      labelx := Tlabel.Create(self);
      labelx.SetSubComponent(True);
      labelx.Stored := False;
      ...
    end;
    

    Firemonkey: How to define a component that contain another component?

    【讨论】:

    • 非常感谢,现在可以了。我不知道 SetSubComponent 和 Stored,两者都是必需的。
    【解决方案2】:

    您需要在您的两个子组件上调用 SetSubComponent(True):

    constructor TProgressBalken.Create(AOwner: TComponent);
    begin
      inherited;
      width:=100;
      height:= 40;
      fValue:= 1;
      fUnits:= '';
      Parent:= TForm(AOwner);
      Fill.Color:= System.UITypes.TAlphaColorRec.red; //Null;
      Balken:= TRectangle.Create(self);
      Balken.SetSubComponent(True);
      Balken.Parent:= self;
      Balken.Position.X:= 0;
      Balken.Position.Y:= 0; ;
      Balken.Fill.Color:= System.UITypes.TAlphaColorRec.Aqua;
      Balken.name:= 'balken'+name;
      labelx:= Tlabel.Create(self);
      labelx.SetSubComponent(True);
      labelx.Parent:= Balken;
      labelx.name:= 'labelx'+name;
      OnResize:= aResize;
      SizeUpdate;
    end;
    

    【讨论】:

    • 我还需要 .Stored := False,否则我仍然会遇到问题。
    猜你喜欢
    • 2018-01-31
    • 2014-10-20
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 2022-11-15
    • 2021-07-13
    • 2019-09-05
    • 2013-05-16
    相关资源
    最近更新 更多