[gelöst] StringGrid - Zellenhöhe laufend anpassen

Rund um die LCL und andere Komponenten
catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

[gelöst] StringGrid - Zellenhöhe laufend anpassen

Beitrag von catweasel »

Hallo

Ich bin dabei einen kleinen Kalender zu programmieren.
Für die einzelnen Tage benutze ich die Komponente "StringGrid" die mit Align=alClient Flächendeckend auf der Form liegt.

Ich möchte erreichen das wenn ich die Größe der Form ändere, sich auch die Größe der einzelnen Zellen des StringGrid ändert, damit keine weißen Flächen auf der Form sind, oder ScrollBars erscheinen wenn die Form kleiner gemacht wird.

Für die Breite der Zellen habe ich das soweit geschafft, nur die Anpassung der Höhe macht mir schwierigkeiten.
Hat jemand eine Idee wie ich das sauber lösen kann?

Gruß
Michael

Code: Alles auswählen

procedure TForm1.FormResize(Sender: TObject);
begin
  // Breite
  StringGrid1.ColWidths[0]  := Form1.Width div 12;
  StringGrid1.ColWidths[1]  := Form1.Width div 12;
  StringGrid1.ColWidths[2]  := Form1.Width div 12;
  StringGrid1.ColWidths[3]  := Form1.Width div 12;
  StringGrid1.ColWidths[4]  := Form1.Width div 12;
  StringGrid1.ColWidths[5]  := Form1.Width div 12;
  StringGrid1.ColWidths[6]  := Form1.Width div 12;
  StringGrid1.ColWidths[7]  := Form1.Width div 12;
  StringGrid1.ColWidths[8]  := Form1.Width div 12;
  StringGrid1.ColWidths[9]  := Form1.Width div 12;
  StringGrid1.ColWidths[10] := Form1.Width div 12;
  StringGrid1.ColWidths[11] := Form1.Width - (11 * (Form1.Width div 12) + 5 );

  // Höhe ????
  //StringGrid1.Font.Height:=(StringGrid1.Height div 47)+2 ; // es gibt nicht so viele Font-Größen das es fließend geht
  StringGrid1.RowHeights[StringGrid1.Height div 32];
  statusbar1.SimpleText:='div: '+inttostr(StringGrid1.Height div 32);
end;
Zuletzt geändert von catweasel am So 20. Dez 2020, 09:58, insgesamt 1-mal geändert.

sstvmaster
Beiträge: 576
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von sstvmaster »

Hi Michael,

ich weiss nicht ob du es schon wusstest, im OPM gibt es ein Paket CalLite, also ein fertiger Kalender.
Weitere Infos zur Benutzung hier: https://wiki.freepascal.org/CalLite:_Usage
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von catweasel »

sstvmaster hat geschrieben:
Fr 18. Dez 2020, 09:59
ich weiss nicht ob du es schon wusstest, im OPM gibt es ein Paket CalLite, also ein fertiger Kalender.
Weitere Infos zur Benutzung hier: https://wiki.freepascal.org/CalLite:_Usage
Hallo sstvmaster

Nein, den kannte ich tatsächlich noch nicht. :)
Allerdings ist mein Kalender ein Jahreskalender in dem alle Tage des Jahres angezeigt werden (jede Spalte ein Monat, mit allen Tagen)

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von charlytango »

Möglicherweise hilft bei einem Kalender auch die Extension "TVPlanit" weiter.

Hier ein paar Impressionen:
https://www.google.com/search?q=tvplanit
https://wiki.freepascal.org/Turbopower_Visual_PlanIt

Auch in die Bilder reinsehen, das gibt einen guten Eindruck.
Ist über den OnlinePackageManager installierbar

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von wp_xyz »

TvPlanIt ist allerdings relativ kompliziert, das ist ein kleines "Ökosystem", aus dem man nicht einfach einen Kalendertyp entnehmen kann, weil die ganze Infrastruktur mit dem "DataStores" daran hängt.

Ziemlich autark ist das JvYearGrid aus JVCL. Das ist ein Jahreskalender, allerdings sind die Monate untereinander angeordnet. Einen Screenshot habe ich im Wiki abgelegt: https://wiki.freepascal.org/JVCL_Components#JvJans. Man kann auch mit einem Doppelklick auf einem Tag eine zugehöriges Ereignis ablegen, der Tag wird dann farbig markiert.

Wenn du dir nicht alle anderen JVCL-Komponenten einfangen willst, reicht es, im Online-Package-Manager nur das Package JvJansLazD (unter JVCL) anzukreuzen. (Allerdings weiß ich nicht, ob dann das zugehörige Beispiel-Projekt mitkommt).

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von Winni »

Hallo!

Warum macht Ihr Euch das Leben so schwer.
Mit ein paar Zeilen ist alles erledigt.
Vielleicht noch die Font-Größe anpassen:

Code: Alles auswählen

procedure TForm1.FormResize(Sender: TObject);
begin
   StringGrid1.Width := self.Width;
   StringGrid1.Height := self.Height;
   StringGrid1.DefaultColWidth:= StringGrid1.Width div StringGrid1.ColCount;
   StringGrid1.DefaultRowHeight:= StringGrid1.Height div StringGrid1.RowCount;
end;
Bunter Eier wünscht
Winni

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von Michl »

catweasel hat geschrieben:
Fr 18. Dez 2020, 09:33
Für die Breite der Zellen habe ich das soweit geschafft
Wenn du nur die Breite der Cols angepasst haben hättest wollen, wäre es ausreichend die Eigenschaft AutofillColumns auf True zu stellen.

Weiter würde ich empfehlen, die Größen der einzelnen Rows und Cols im OnResize vom StringGrid1 und nicht vom Formular einzustellen. Verwendest du z.B. ein Splitter auf dem Formular, würde OnResize dann auch entsprechend richtig gefeuert.

Für die laufende Anpassung der Gitterlinien (ohne nur letzte Zelle in der Größe verändert zu haben) würde ich das so lösen (Bsp. mit 10 Cols und 10 Rows):

Code: Alles auswählen

procedure TForm1.StringGrid1Resize(Sender: TObject);
var
  ARow, UsedHeigth, AHeight, UsedWidth, ACol, AWidth: Integer;
begin
  UsedHeigth := 0;
  for ARow := 0 to 9 do
  begin
    AHeight := (StringGrid1.ClientHeight - UsedHeigth) div (10 - ARow);
    StringGrid1.RowHeights[ARow] := AHeight;
    Inc(UsedHeigth, AHeight);
  end;

  UsedWidth := 0;
  for ACol := 0 to 9 do
  begin
    AWidth := (StringGrid1.ClientWidth - UsedWidth) div (10 - ACol);
    StringGrid1.ColWidths[ACol] := AWidth;
    Inc(UsedWidth, AWidth);
  end;
end;   
Beispiel anbei.

Als letzten Hinweis noch. Für so eine Aufgabe würde ich vermutlich ein TDrawGrid nehmen.
Dateianhänge
StringGridRowHeight.zip
(1.97 KiB) 111-mal heruntergeladen
Zuletzt geändert von Michl am Sa 19. Dez 2020, 22:50, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

jwdietrich
Beiträge: 167
Registriert: Mo 20. Okt 2008, 20:50
OS, Lazarus, FPC: macOS 10.4-13.4, Windows 2000-11, Raspbian (L 2.2.6, FPC 3.2.2)
CPU-Target: PowerPC, Intel, ARM
Wohnort: Hattingen, NRW
Kontaktdaten:

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von jwdietrich »

Übrigens kann man die Breite der Spalten automatisch von der LCL anpassen lassen, indem man die Eigenschaft AutoFillColumns auf true setzt. Leider geht das aber nicht mit den Zeilen.

jwdietrich
Beiträge: 167
Registriert: Mo 20. Okt 2008, 20:50
OS, Lazarus, FPC: macOS 10.4-13.4, Windows 2000-11, Raspbian (L 2.2.6, FPC 3.2.2)
CPU-Target: PowerPC, Intel, ARM
Wohnort: Hattingen, NRW
Kontaktdaten:

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von jwdietrich »

jwdietrich hat geschrieben:
Sa 19. Dez 2020, 18:16
Übrigens kann man die Breite der Spalten automatisch von der LCL anpassen lassen, indem man die Eigenschaft AutoFillColumns auf true setzt. Leider geht das aber nicht mit den Zeilen.
Sehe gerade, dass das @Michl auch schon geschrieben hat...

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von wp_xyz »

Winni hat geschrieben:
Sa 19. Dez 2020, 16:49
Warum macht Ihr Euch das Leben so schwer.

Code: Alles auswählen

procedure TForm1.FormResize(Sender: TObject);
begin
   StringGrid1.Width := self.Width;
   StringGrid1.Height := self.Height;
   StringGrid1.DefaultColWidth:= StringGrid1.Width div StringGrid1.ColCount;
   StringGrid1.DefaultRowHeight:= StringGrid1.Height div StringGrid1.RowCount;
end;
Du machst es dir zu leicht, indem du hier eine nicht funktionierende Lösung präsentierst. Denn: was ist mit dem Rest der bei der Integer-Division übrig bleibt? Gerade diesen ungenutzten Bereich will catweasel nicht haben, und auch keinen Scrollbar.

Michl's Lösung sieht auf den ersten Blick gut aus, ist aber "geschummelt", weil er die Scrollbars permanent ausblendet (man braucht sie ja eigentlich auch nicht). Man sieht den Effekt, wenn man abwechselnd in die erste und letzte Spalte oder Zeile klickt, wie der Inhalt sich verschiebt.

Die einzige sauber funktionierende Lösung, die ich kenne, ist das AutoFillColumn im TCustomGrid (procedure InternalAutoFillColumns), und da kommen für sowas "einfaches" gleich 100 Zeilen zusammen.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von Winni »

wp_xyz hat geschrieben:
Sa 19. Dez 2020, 18:41

Du machst es dir zu leicht, indem du hier eine nicht funktionierende Lösung präsentierst. Denn: was ist mit dem Rest der bei der Integer-Division übrig bleibt? Gerade diesen ungenutzten Bereich will catweasel nicht haben, und auch keinen Scrollbar.

Hallo Erbsenzähler!

Entweder man lässt bei einem Resize nur zu, dass es Werte gibt, wo Form1.Size = String1.Size mod ColCount = 0 ist.

Oder man malt per OwnerDraw alles selbst mittels BGRAbitmap. Auf der gibt es Sub-Pixel.

Oder man sammelt die übrig gebliebenen Pixel am Rand und mal sich da einen Tannenbaum auf den Canvas.

Winni

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von wp_xyz »

Oh Mann!

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von Michl »

wp_xyz hat geschrieben:
Sa 19. Dez 2020, 18:41
Michl's Lösung sieht auf den ersten Blick gut aus, ist aber "geschummelt", weil er die Scrollbars permanent ausblendet (man braucht sie ja eigentlich auch nicht). Man sieht den Effekt, wenn man abwechselnd in die erste und letzte Spalte oder Zeile klickt, wie der Inhalt sich verschiebt.
Danke für den Hinweis!! Hatte es nur schnell, nicht allzu ausführlich, getestet :wink:

Man sollte natürlich nicht StringGrid.Width, sondern StringGrid.ClientWidth nehmen (Height dito).

Ich habe es oben geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von braunbär »

wp_xyz hat geschrieben:
Sa 19. Dez 2020, 18:41
Du machst es dir zu leicht, indem du hier eine nicht funktionierende Lösung präsentierst. Denn: was ist mit dem Rest der bei der Integer-Division übrig bleibt? Gerade diesen ungenutzten Bereich will catweasel nicht haben, und auch keinen Scrollbar.
Dadurch, dass er in jedem Schritt die Breite anhand der Restbreite (bzw, die Höhe anhand der Resthöhe) neu berechnet, bleibt kein ungenutzer Bereich übrig. Auf diese Art unterscheiden sich die Spaltenbreiten höchstens um einen Punkt, das merkt man nicht, und am Ende bleibt nichts übrig.

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: StringGrid - Zellenhöhe laufend anpassen

Beitrag von catweasel »

Hallo

Danke an alle für die rege Diskussion.
Ich habe das Beispiel von Michl bei mir umgesetzt und es funktioniert genau so wie ich es mir vorgestellt hatte :D

Bei der Umsetzung hatte ich nur übersehen das ich bei mir noch die Scrollbars auf "Auto" stehen hatte, statt auf "None" (obwohl ich sie ja gar nicht nutzen wollte). Das hat bewirkt das beim resize doch immer wieder mal eine leere Zeile erschienen ist.
Nach der Umstellung funktioniert das alles wie es soll.

Vielen Dank für die Hilfe

Gruß
Michael

Antworten