No to może TStringGrid
z tworzonymi w jego komórtkach odpowiednimi komponentami, jak potrzebne TButton
i w komórce obok potrzebny TEdit
. Oprogramujesz wszystko dynamicznie. Poniżej wycinek kodu z programu, który pisałem kiedyś na zlecenie. A poniżej efekt wizualny na dołączonym zrzucie ekranu. Jak widać są tutaj i TUpDown
, a także oczywiście TEdit
i TButton
. Ważne, że sobie pobieram TRect
potrzebnej komórki i na podstawie niego określam położenie dodatkowych kontrolek na TStringGrid'ach
.
procedure TMainForm.PrepareBothSG;
var
R : TRect;
Btn : TButton;
LI : TListItem;
UpDn : TUpDown;
Edt : TStatsEdit;
ASG : TStringGrid;
I, J, ArrIdx : Byte;
SGArr : array[1..2] of TStringGrid;
begin
HomeOnFieldCnt := 0;
AwayOnFieldCnt := 0;
Self.Visible := False;
for I := Low(SGArr) to High(SGArr) do
begin
SGArr[I] := TStringGrid(Self.FindComponent(SGNamePrefix + IntToStr(I)));
SGArr[I].OnMouseMove := SGMouseMove;
SGArr[I].Tag := I;
with ChooseTeamsForm do
begin
case I of
1 : SGArr[I].RowCount := HomeSquadLV.Items.Count + 1;
2 : SGArr[I].RowCount := AwaySquadLV.Items.Count + 1;
end;
end;
end;
for I := Low(SGArr) to High(SGArr) do
begin
SGArr[I].Height := (FirstRowHeight + ((SGArr[I].RowCount - 1) * StatsRowHeight) + (SGArr[I].RowCount - 1)) + 4;
end;
SGArr[2].Top := SGArr[1].Top + SGArr[1].Height + 8;
for ArrIdx := Low(SGArr) to High(SGArr) do
begin
ASG := SGArr[ArrIdx];
ASG.OnDrawCell := SGDrawCell;
ASG.Font.Size := 8;
ASG.FixedRows := 1;
ASG.ColCount := Length(ColsTitleArr);
ASG.FixedCols := 2;
for I := Low(ColsTitleArr) to High(ColsTitleArr) do
begin
ASG.Cells[I, 0] := ColsTitleArr[I];
ASG.ColWidths[I] := ColsWidthArr[I];
end;
ASG.RowHeights[0] := FirstRowHeight;
for I := 1 to ASG.RowCount - 1 do
begin
ASG.RowHeights[I] := StatsRowHeight;
with ChooseTeamsForm do
begin
case ASG.Tag of
1 : LI := HomeSquadLV.Items[I - 1];
2 : LI := AwaySquadLV.Items[I - 1];
else
begin
LI := nil;
end;
end;
end;
if LI <> nil then
begin
ASG.Cells[0, I] := LI.Caption;
ASG.Cells[1, I] := LI.SubItems[0];
end;
PlayerStats := TPlayerStats.Create;
with PlayerStats do
begin
Number := StrToInt(ASG.Cells[0, I]);
WholeName := ASG.Cells[1, I];
IsOnField := False;
B := 0;
A := 0;
SC := 0;
SNC := 0;
PC := 0;
PNC := 0;
Steals := 0;
TurnOvers := 0;
UD := 0;
CZG := 0;
FPlus := 0;
FMinus := 0;
end;
ASG.Objects[0, I] := PlayerStats;
ASG.Cells[PlayOnFieldColumnIndex, I] := Secs2Time(PlayerStats.CZG);
R := ASG.CellRect(StartStopBtnColumnIndex, I);
R.Left := R.Left + ASG.Left;
R.Right := R.Right + ASG.Left;
R.Top := R.Top + ASG.Top;
R.Bottom := R.Bottom + ASG.Top;
Btn := TButton.Create(Self);
with Btn do
begin
OnMouseMove := StatsControlMouseMove;
OnClick := StartStopButtonClick;
Cursor := crHandPoint;
Left := R.Left + 2;
Top := R.Top + 4;
Height := 16;
Width := ColsWidthArr[StartStopBtnColumnIndex];
SGStatsObj := TSGStatsObj.Create;
SGStatsObj.RowIndex := I;
SGStatsObj.AParent := ASG;
SGStatsObj.Started := False;
Caption := StartStopBtn_Caption[SGStatsObj.Started];
Tag := Integer(TObject(SGStatsObj));
Name := ButtonNamePrefix + IntToStr(ArrIdx) + '_' + IntToStr(I);
Parent := Self;
end;
for J := 2 to ASG.ColCount - 1 do
begin
if (J <> PlayOnFieldColumnIndex) and (J <> StartStopBtnColumnIndex) then
begin
R := ASG.CellRect(J, I);
R.Left := R.Left + ASG.Left;
R.Right := R.Right + ASG.Left;
R.Top := R.Top + ASG.Top;
R.Bottom := R.Bottom + ASG.Top;
Edt := TStatsEdit.Create(Self);
with Edt do
begin
OnMouseMove := StatsControlMouseMove;
PopupMenu := EmptyPopupMenu;
Left := R.Left;
Top := R.Top + 4;
ReadOnly := True;
Text := IntToStr(0);
Height := 12;
SGStatsObj := TSGStatsObj.Create;
SGStatsObj.ColIndex := J;
SGStatsObj.RowIndex := I;
SGStatsObj.AParent := ASG;
SGStatsObj.Started := False;
Tag := Integer(TObject(SGStatsObj));
Name := EditNamePrefix + IntToStr(ArrIdx) + '_' + IntToStr(J) + '_' + IntToStr(I);
Parent := Self;
end;
UpDn := TUpDown.Create(Self);
with UpDn do
begin
OnMouseMove := StatsControlMouseMove;
OnClick := StatsControlClick;
Cursor := crHandPoint;
Enabled := False;
Min := 0;
Max := MaxStatsvalue;
Position := 0;
Orientation := udHorizontal;
Height := 12;
Width := 26;
SGStatsObj := TSGStatsObj.Create;
SGStatsObj.ColIndex := J;
SGStatsObj.RowIndex := I;
SGStatsObj.AParent := ASG;
SGStatsObj.Started := False;
Tag := Integer(TObject(SGStatsObj));
Name := LeftAndRightNamePrefix + IntToStr(ArrIdx) + '_' + IntToStr(J) + '_' + IntToStr(I);
Parent := Self;
Associate := Edt;
end;
Edt.Width := ASG.ColWidths[J] - UpDn.Width;
end;
end;
if LI.Checked then
begin
Btn.Click;
end;
end;
end;
Self.ClientHeight := SGArr[2].Top + SGArr[2].Height + 8;
Self.Position := poScreenCenter;
Self.Visible := True;
end;