Adding component to Firemonkey custom styles at runtime - delphi

I am making a custom list box for firemonkey.There I have customized a TSeachBox. In my custom style there is a TRectangle where i need to add TLabel at runtime.
I can add Lables at design time. But I can not see all the lables which are added at design time in this TRectangle. I've properly set the parent and owners of all the lables.
Any idea ?
below is the code :
procedure TCustomListBox.ColumnsChanged(Sender: TObject);
var
lPanel : TPanel;
lLabel: TLabel;
iCount : Integer;
begin
if Assigned(FSearchBox) then
Begin
if FSearchBox.FindStyleResource('headerstyle') <> nil then
lPanel := FSearchBox.FindStyleResource('headerstyle') as TPanel;
if Assigned(lPanel) and (lPanel is TPanel) then
begin
//Clear all the columns except whose Tag = 1
for iCount := lPanel.ChildrenCount - 1 downto 0 do
begin
if Assigned(lPanel.Children[iCount]) then
begin
if (lPanel.Children[iCount]).Tag = 0 then
lPanel.Children[iCount].Free;
end;
end;
iXPosition := 45;
//FColumns1 is columns which needs to be added.
for iCount := 0 to FColumns1.Count - 1 do
begin
FLabel := TLabel.Create(lPanel);
FLabel.Parent:= lPanel;
FLabel.Name := 'Col' + IntToStr(iCount);
FLabel.Visible := True;
FLabel.Position.X := iXPosition;
FLabel.Align := TAlignLayout.alLeft;
FLabel.Text := FColumns1[iCount].ColumnHeaderText;
FLabel.Width := FColumns1[iCount].ColumnWidth;
iXPosition := iXPosition + FColumns1[iCount].ColumnWidth;
end;
end;
End;
end;

Related

How to get text from found component?

I have a problem with Text inside of a found TEdit.
This is my code:
function TfrmGenerateExam.zlicz_liczby(Component: TControl): integer;
var
i, j: integer;
begin
Result := 0;
for i := 0 to Component.ComponentCount - 1 do
begin
for j := 0 to Panel.ComponentCount - 1 do
begin
if Components[j] is TEdit then
begin
Result := Result + ???;
end;
end;
end;
end;
In a nutshell:
I create dynamic panels with ComboBoxes, Edits, Buttons etc.
When I have some panels, I want to count the edits which are in panels, which are in ScrollBox:
What do I need to put here?
if Components[j] is TEdit then
begin
Result := Result + ???;
end;
The code provided does not match the screenshot shown. What is being passed as the Component parameter to zlicz_liczby()? Is it the Form itself? The ScrollBox? A specified Panel?
Let's just iterate the Panels in the ScrollBox directly. Try something more like this:
function TfrmGenerateExam.zlicz_liczby: Integer;
var
i, j: integer;
Panel: TPanel;
begin
Result := 0;
for i := 0 to ScrollBox1.ControlCount - 1 do
begin
Panel := ScrollBox1.ControlCount[i] as TPanel;
for j := 0 to Panel.ControlCount - 1 do
begin
if Panel.Controls[j] is TEdit then
Result := Result + StrToIntDef(TEdit(Panel.Controls[j]).Text, 0);
end;
end;
end;
That being said, as #AndreasRejbrand stated in comments, you should use an array instead. When you create a new TPanel with a TEdit on it, put its TEdit into a TList<TEdit>, for instance. If you destroy the TPanel, remove its TEdit from the list. And then you can simply loop through that list whenever needed, without having to hunt for the TEdit controls at all. For example:
private
Edits: TList<TEdit>;
procedure TfrmGenerateExam.FormCreate(Sender: TObject);
begin
Edits := TList<TEdit>.Create;
end;
procedure TfrmGenerateExam.FormDestroy(Sender: TObject);
begin
Edits.Free;
end;
function TfrmGenerateExam.FillScrollBox;
var
Panel: TPanel;
Edit: TEdit;
begin
...
Panel := TPanel.Create(Self);
Panel.Parent := ScrollBox1;
...
Edit := TEdit.Create(Panel);
Edit.Parent := Panel;
...
Edits.Add(Edit);
...
end;
function TfrmGenerateExam.zlicz_liczby: Integer;
var
i: integer;
begin
Result := 0;
for i := 0 to Edits.Count - 1 do
Result := Result + StrToInt(Edits[i].Text);
end;

Delphi XE6 firemonkey component alignment problems when added at runtime

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;

Creating buttons from database table on runtime in Delphi

I want to create buttons from Database on runtime.
For example I have a table lets say users.
I need to create as many buttons as the user table contains.
The following code does that. But I have a problem,
it gives me the last button only or it puts all buttons on top of other and I see only last button.
I need to get the buttons one next to other.
procedure TForm1.Button2Click(Sender: TObject);
var
Bt: TButton;
i: Integer;
begin
Query1.First;
while not Query1.Eof do
begin
i:=0;
Bt := TButton.Create(Self);
Bt.Caption := Query1.Fields[0].AsString;
Bt.Parent := Self;
Bt.Height := 23;
Bt.Width := 100;
Bt.Left := 10;
Bt.Top := 10 + i * 25;
i:= i+1;
Query1.Next;
end;
end;
what should I change or add?
You reset the i counter with every loop iteration. Initialize it once before you enter the loop:
procedure TForm1.Button2Click(Sender: TObject);
var
i: Integer;
Bt: TButton;
begin
Query1.First;
i := 0; // initialize the counter before you enter the loop
while not Query1.Eof do
begin
Bt := TButton.Create(Self);
Bt.Caption := Query1.Fields[0].AsString;
Bt.Parent := Self;
Bt.Height := 23;
Bt.Width := 100;
Bt.Left := 10;
Bt.Top := 10 + i * 25;
i := i + 1;
Query1.Next;
end;
end;

Resetting a program in delphi

I am doing this program in Delphi 7 and using a Page-Control do any of you have a quick way of resetting the Check Boxes and Combo Boxes that is op the page ? With out calling each Check Box and changing its Properties ? Because their is about 150 Check Boxes in the program and don't want to type every ones name out to reset it to unchecked ?
I Tried to use the following code :
var
i : Integer;
cb : TCheckBox;
cbx : TComboBox;
begin
ADOQuery1.SQL.Clear;
for i := 1 to (ComponentCount) do
Begin
if Components[i] is TCheckBox then
begin
cb := TCheckBox(Components[i]);
cb.checked := false;
end;
if Components[i] is TComboBox then
begin
cbx := TComboBox(Components[i]);
cbx.ItemIndex := -1;
end;
end;
End;
But I get a error List out od Bounds ? Any ideas why ?
Off the top of my head....This should run.
procedure ResetControls(aPage:TTabSheet);
var
loop : integer;
begin
if assigned(aPage) then
begin
for loop := 0 to aPage.controlcount-1 do
begin
if aPage.Controls[loop].ClassType = TCheckBox then
TCheckBox(aPage.Controls[loop]).Checked := false
else if aPage.Controls[loop].ClassType = TComboBox then
TComboBox(aPage.Controlss[loop]).itemindex := -1;
end;
end;
end;
edit: Corrected as pointed out by Remy
You could do something like this within the form:
for i := 0 to ComponentCount-1 do
if Components[i] is TCheckBox then begin
cb := TCheckBox(Components[i]);
cb.checked := false;
end;
end;
procedure ResetControls(Container: TWinControl);
var
I: Integer;
Control: TControl;
begin
for I := 0 to Container.ControlCount - 1 do
begin
Control := Container.Controls[I];
if Control is TCheckBox then
TCheckBox(Control).Checked := False
else
if Control is TComboBox then
TComboBox(Control).ItemIndex := -1;
//else if ........ other control classes
ResetControls(Control as TWinControl); //recursive to process child controls
end;
end;

Delete TLabel created in run-time

How to delete created labels. I tried FindComponent but failed , what I have to do? should I set there parent to other component like TPanel or what?
procedure TForm1.Button1Click(Sender: TObject);
var
lblLink: TLabel;
begin
for i := 0 to stringtList.Count-1 do
begin
lblLink := TLabel.create(self);
with lblLink do
begin
name:='lblLink'+inttostr(i);
caption:inttostr(i);
Parent := self;
font.style := [fsUnderline];
cursor := crHandPoint;
color := clBlue;
font.Color := clBlue;
end;
end;
end;
You can iterate over the Components property, then check for the name of the component and finally free the component.
Var
LIndex : Integer;
LComponent : TComponent;
begin
for LIndex := ComponentCount-1 downto 0 do
if StartsText('lblLink',Components[LIndex].Name) then
begin
LComponent:=Components[LIndex];
FreeAndNil(LComponent);
end;
end;
You don't have to free it. You gave the responsibility to free it to the form with lblLink := TLabel.create(self);. The form will free the label when the form is freed.
However, with that being said, you can free it by looping through the form's Components array:
procedure TForm1.DeleteLabel(const LabelName: string);
var
i: Integer;
begin
for i := ComponentCount - 1 downto 0 do
begin
if Components[i] is TLabel then
if Components[i].Name = LabelName then
begin
Components[i].Free;
Break;
end;
end;
end;
You assigned both an Owner and a Parent to each TLabel, so techncally you do not need to free them at all. Both the Owner and the Parent will handle that for you. However, if you wanted to free them earlier, you could loop through the Owner's Components list or the Parent's Controls list, hunting for the labels manually. A better option is to keep your own list of the labels you create, then you can loop through that list when needed, eg:
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
...
private
Labels: TList;
procedure FreeLabels;
...
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Labels := TList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Labels.Free;
end;
procedure TForm1.FreeLabels;
var
I: Integer;
begin
for I := 0 to Labels.Count-1 do
TLabel(Labels[I]).Free;
Labels.Clear;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
lblLink : TLabel;
...
begin
...
for I := 0 to StringList.Count-1 do
begin
lblLink := TLabel.Create(Self);
try
with lblLink do
begin
Name := 'lblLink' + IntToStr(i);
Parent := Self;
Caption := IntToStr(i);
Font.Style := [fsUnderline];
Cursor := crHandPoint;
Color := clBlue;
Font.Color := clBlue;
end;
Labels.Add(lblLink);
except
lblLink.Free;
raise;
end;
end;
end;

Resources