FMX:将自制组件放在表单上会复制子组件
FMX: dropping selfmade component on form duplicates subcomponents
我创建了自己的进度条(TProgressBalken),它由一个 TRectangle 组成,其中有另一个 TRectangle (a) 具有不同的颜色,它的宽度随进度值 (0..100) 而变化。最后一个 Tlabel 位于它上面,将当前值显示为文本。
在运行时创建此组件时一切正常。
将它放在新的多设备形式上时(IDE 设置为 32 位 windows),它也可以正常工作。
但是,当将 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
您需要在您的两个子组件上调用 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;
在 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;
见
我创建了自己的进度条(TProgressBalken),它由一个 TRectangle 组成,其中有另一个 TRectangle (a) 具有不同的颜色,它的宽度随进度值 (0..100) 而变化。最后一个 Tlabel 位于它上面,将当前值显示为文本。 在运行时创建此组件时一切正常。
将它放在新的多设备形式上时(IDE 设置为 32 位 windows),它也可以正常工作。 但是,当将 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
您需要在您的两个子组件上调用 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;
在 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;
见