Delphi XE6 firemonkey component alignment problems when added at runtime - ios

i wanto dynamic add 5 TLable in my iOS app.
like this
Procedure Form1.FormCreate(Sender: TObject)
var
I: Integer;
begin
for I := 1 to 5 do
begin
with TLabel.Create(Self) do
begin
Parent := self;
Align := TAlignLayout.Top;
Height := 50;
Text := IntToStr(I);
end;
end;
end;
i think the order is 12345, but I get 15432.
What can I do to get the desired results?

You must give a chance to the aligning algorithm to do what you want.
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 5 do
begin
with TLabel.Create(Self) do
begin
Parent := self;
Align := TAlignLayout.alTop;
Height := 50;
Position.Y := I*Height; //add this line
Text := IntToStr(I);
end;
end;
end;

Related

Creating custom button in Delphi with different actions [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am creating a custom component, a button-switch like this :
In my "form activate" function, I wrote a for loop in which I call 3 times the button function with a different position parameter like : SwitchButton(30); where 30 is the top position.
What I want to do is assign at these 3 buttons different actions, here some code.
Code for button creation :
procedure TFMain.SwitchButton(posPulsante: Integer);
var
i: Integer;
posDescrizionePulsante: Integer;
strDescrizione: String;
begin
posDescrizionePulsante := 32;
lastPressed := 1;
Pulsante := TPanel.Create(FMain);
BordoPulsante := TShape.Create(self);
LevaPulsante := TPanel.Create(self);
DescrizionePulsante := TLabel.Create(self);
//Proprietà Descrizione
with DescrizionePulsante do
begin
Parent := PComandi;
Top := posDescrizionePulsante;
Left := 100;
Caption := 'Visualizza finestra utenti';
Font.Name := 'Tahoma';
Font.Size := 12;
Font.Style := [fsBold];
Font.Color := clWhite;
end;
//Proprietà Pulsante
with Pulsante do
begin
Parent := PComandi;
ParentColor := false;
ParentBackground := false;
BevelOuter := bvNone;
Color := clWhite;
Width := 57;
Height := 25;
Top := posPulsante;
Left := 20;
Visible := true;
end;
//Proprietà Bordo
with BordoPulsante do
begin
Parent := Pulsante;
Align := alClient;
Brush.Style := bsClear;
Brush.Color := RGB(122,136,201);
Pen.Color := clWhite;
Pen.Style := psSolid;
Pen.Width := 3;
end;
//Proprietà Leva
with LevaPulsante do
begin
Parent := Pulsante;
ParentBackground := false;
ParentColor := false;
BevelOuter := bvNone;
Color := clWhite;
Cursor := crHandPoint;
Width := 23;
Height := 13;
Top := 6;
Left := 28;
LevaPulsante.OnClick := SwitchState;
end;
end;
Code for creating Button object :
procedure TFMain.FormActivate(Sender: TObject);
var
i: Integer;
posPulsante: Integer;
begin
posPulsante := 30;
for i := 1 to 3 do
begin
SwitchButton(posPulsante);
posPulsante := posPulsante + 50;
end;
end;
Would be nice to have some : if SwitchButton 1 is clicked then do something. if SwitchButton 2 is clicked then do something else.
I think this is an acceptable use of the Tag property. You can specify some number, for example the index of the for loop, in each of the panels:
procedure TFMain.FormActivate(Sender: TObject);
var
i: Integer;
posPulsante: Integer;
begin
posPulsante := 30;
for i := 1 to 3 do
begin
SwitchButton(posPulsante, i {For example, add the tag as extra parameter});
posPulsante := posPulsante + 50;
end;
end;
And then set that tag in the button, here using the added parameter indexPulsante.
procedure TFMain.SwitchButton(posPulsante: Integer; indexPulsante: Integer);
var
i: Integer;
posDescrizionePulsante: Integer;
strDescrizione: String;
begin
...
LevaPulsante.Tag := indexPulsante;
end;
And then, in the event handler (which I think you called SwitchState), you'll have the Sender, which is the control that was clicked (the panel, in your case).
procedure TFMain.SwitchState(Sender: TObject);
begin
case (Sender as TComponent).Tag of
1: ShowMessage('You clicked the first. Do something.')
2: ShowMessage('Do something else.')
else
ShowMessage('You clicked another button than 1 or 2');
end;
end;
NB: Tag is introduced in TComponent and therefore also available in TPanel. In the code above I only typecast to TComponent, because it doesn't matter that it's a panel to get the tag, but if you want to use other properties, a more specific cast may be needed. I like to keep the cast generic, to make it easier to make changes like switching to another type than TPanel, for instance when you actually gonna make a component out of this (inherited from TCustomControl?), or use a third party component.

DBGRID with Row Height variable

I would like to show in a DBGRID as follows:
Imagine "Grid" as follows:
ID - DESCRIPTION
1 - Line 1 of the grid
2 - Line 2 of the grid
3 - Line 3 of the grid
Now, suppose the size of the DESCRIPTION column is changed and no longer appear the words "GRID";
I would like to stay as well DBGRID
ID - DESCRIPTION
1 - Line 1 of the
grid
2 - Line 2 of the
grid
3 - Line 3 of the
grid
is there any possibility that ??
Not what you're asking, but might help... I once used this code to show complete Memo fields in the standard DBGrid:
TMyForm = class(TForm)
...
private
FormMemoRect: TRect;
MemoGrid: TDBGrid;
BMemo: TBitBtn;
...
Procedure TMyForm.FormMemoDeactivate(Sender: TObject);
Begin
(Sender As TForm).Close;
Sender.Free;
End;
Procedure TMyForm.BMemoClick(Sender: TObject);
Var FormMemo: TForm;
Begin
MemoGrid.SetFocus;
FormMemo := TForm.Create(Self);
With TMemo.Create(FormMemo) Do Begin
Parent := FormMemo;
Align := alClient;
ReadOnly := True;
WordWrap := True;
ScrollBars := ssVertical;
Lines.Text := MemoGrid.DataSource.DataSet.Fields[TComponent(Sender).Tag].AsString;
End;
With FormMemo Do Begin
OnDeactivate := FormMemoDeactivate;
Left := FormMemoRect.Left;
Top := FormMemoRect.Top;
Width := Max(FormMemoRect.Right - FormMemoRect.Left, 300);
Height := FormMemoRect.Bottom - FormMemoRect.Top;
BorderStyle := bsNone;
Show;
End;
End;
Procedure TMyForm.GrdMemoDrawColumnCell(Sender: TObject; Const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
Begin
If (gdFocused In State) Then Begin
If Column.Field.DataType In [ftBlob, ftMemo] Then Begin
{Desenha botão para visualização do Memo}
FormMemoRect.Left := TWinControl(Sender).ClientToScreen(Rect.TopLeft).X;
FormMemoRect.Right := TWinControl(Sender).ClientToScreen(Rect.BottomRight).X;
FormMemoRect.Top := TWinControl(Sender).ClientToScreen(Rect.BottomRight).Y;
FormMemoRect.Bottom := FormMemoRect.Top + 100;
If Not Assigned(BMemo) Then
BMemo := TBitBtn.Create(Self);
BMemo.Parent := TWinControl(Sender).Parent;
BMemo.Width := 16;
BMemo.Height := 16;
BMemo.Caption := '...';
BMemo.OnClick := BMemoClick;
BMemo.Tag := Column.Field.Index;
BMemo.Left := TWinControl(Sender).Left + Rect.Right - BMemo.Width + 1;
BMemo.Top := TWinControl(Sender).Top + Rect.Top + 2;
MemoGrid := TDBGrid(Sender);
End
Else
FreeAndNil(BMemo);
End;
End;
For Blob/Memo Fields, you may also find it useful to do some custom GetText to show something directly in the Grid:
Procedure TMyForm.DataSetMemoGetText(Sender: TField; var Text: String; DisplayText: Boolean);
Begin
Text := Copy(Sender.AsString, 1, 50);
If Text <> Sender.AsString Then
Text := Text + '...';
End;
This is how the result looks like.
PS: Sorry for non-standard code style.

Change THeader font size in FMX TStringGrid

I've searched this question and found this.
so, I wrote a OnApplyStyleLookup event handler like this:
procedure TForm1.StringGrid1ApplyStyleLookup(Sender: TObject);
var
Header: THeader;
I: Integer;
begin
Header := THeader((Sender as TStringGrid).FindStyleResource('header'));
if Assigned(Header) then
begin
for I := 0 to Header.Count - 1 do
with Header.Items[I].Font do
begin
Header.Items[I].TextSettings.HorzAlign := TTextAlign.Center;
Size := 100;
Style := [TFontStyle.fsBold];
// SetSettings('Arial', 100, [TFontStyle.fsBold]);
end;
Header.Height := 48;
end;
// TStringGrid(Sender).Realign;
end;
text align is changed, but font size and style are not applied.
I'm using XE7.
For apply changed text style, you must set StyledSettings property for changed object.
So, final code looks like this (i dont like with operator)
procedure TForm1.StringGrid1ApplyStyleLookup(Sender: TObject);
var
Header: THeader;
HeaderItem: THeaderItem;
I: Integer;
begin
Header := THeader((Sender as TStringGrid).FindStyleResource('header'));
if Assigned(Header) then
begin
for I := 0 to Header.Count - 1 do
begin
HeaderItem := Header.Items[I];
HeaderItem.Font.Size := 100;
HeaderItem.Font.Style := [TFontStyle.fsBold];
HeaderItem.TextSettings.HorzAlign := TTextAlign.Center;
// new code line:
HeaderItem.StyledSettings := HeaderItem.StyledSettings - [TStyledSetting.Size, TStyledSetting.Style];
end;
Header.Height := 48;
end;
end;

Delphi 7 edit component creation

I have a problem according to run-time creation of edit components in Delphi 7.
So when I create TEdit components after the program ran for "some" time it perfectly works.
However, when I create TEdit elements at the Forms OnCreate event, they have a wrong height.
Furthermore the (almost) simultaneously created Shapes have the right height.
Edit:
procedure TTPLVisorForm.CreateZeichen(ZShape : TShape; ZEdit : TEdit; VLeft : integer);
begin
with ZShape do
begin
Width := 50;
Height := 50;
Left := VLeft;
Top := 25;
Shape := stRectangle;
Parent := self.Band;
SendToBack();
end;
with ZEdit do
begin
Text := '#';
Left := VLeft+1;
Top := 26;
Parent := self.Band;
Font.Height := 48;
Width := 48;
Height := 48;
SendToBack;
end;
end;
Getting called by:
procedure TZeichen.Anzeigen(Form : TObject; Left : integer);
begin
self.Form := Form;
self.ZShape := TShape.Create(TTPLVisorForm(self.Form).Band);
self.ZEdit := TEdit.Create(TTPLVisorForm(self.Form).Band);
TTPLVisorForm(Form).CreateZeichen(self.ZShape, self.ZEdit, Left);
end;
Getting called by:
procedure TMagnetband.ErweitereRechts;
var
Zeichen : TZeichenKette;
begin
Zeichen := TZeichenKette.Create;
self.LetztesZeichen.Naechstes := TZeichenKette(Zeichen);
Zeichen.Vorheriges := self.LetztesZeichen;
Zeichen.Zeichen.Anzeigen(self.Form,
self.LetztesZeichen.Zeichen.ZShape.Left +
self.LetztesZeichen.Zeichen.ZShape.Width +
self.Padding);
self.LetztesZeichen := Zeichen;
self.Laenge := self.Laenge+1;
end;
Getting again called by:
procedure TTuringmaschine.ZeichenAnfuegen;
begin
self.Magnetband.ErweitereRechts;
end;
Getting called by:
procedure TTuringmaschine.PanelResize(Sender: TObject);
begin
while self.Magnetband.GetRechtsMax < self.Panel.Width do
self.ZeichenAnfuegen;
end;
Finally gets called by:
Constructor TTuringmaschine.Create(Form : TObject);
var
Breite : integer;
begin
self.Zustand := 0;
self.Form := TTPLVisorForm(Form);
self.Panel := TTPLVisorForm(self.Form).Band;
self.Magnetband := TMagnetband.Create(self.Form);
TTPLVisorForm(Form).Band.OnResize := self.PanelResize;
self.PanelResize(Nil);
//self.CreateMagnetkopf;
end;
And the Constructor is either called at the OnCreate event or on another event.
There's a margin around the text in TEdit control, so if you set the Font.Height to 48, the height of the control won't be exactly 48 if the control has the AutoSize property set to True. I would personally decrease height of the font, and for being sure turn the AutoSize off. Your CreateZeichen method would then look like this:
procedure TTPLVisorForm.CreateZeichen(ZShape: TShape; ZEdit: TEdit;
VLeft: Integer);
begin
with ZShape do
begin
Width := 50;
Height := 50;
Left := VLeft;
Top := 25;
Shape := stRectangle;
Parent := Self.Band;
SendToBack;
end;
with ZEdit do
begin
AutoSize := False;
Text := '#';
Left := VLeft + 1;
Top := 26;
Parent := Self.Band;
Font.Height := 40;
Width := 48;
Height := 48;
SendToBack;
end;
end;

Change text size in Firemonkey StringGrid

How to change text size in stringgrid header?
You could write an OnApplyStyleLookup event handler similar to this:
procedure TForm1.StringGrid1ApplyStyleLookup(Sender: TObject);
var
Header: THeader;
I: Integer;
begin
Header := THeader((Sender as TStringGrid).FindStyleResource('header'));
if Assigned(Header) then
begin
for I := 0 to Header.Count - 1 do
with Header.Items[I].Font do
begin
Size := 32;
Style := [TFontStyle.fsBold];
end;
Header.Height := 48;
end;
TStringGrid(Sender).Realign;
end;

Resources