Autor Téma: Jak správně nastavit šiřku StringGridu  (Přečteno 3400 krát)

Venca s Brna

  • Host
Jak správně nastavit šiřku StringGridu
« kdy: 20-09-2012, 07:28:34 »
Dobry den.
Delphi jsem poprvé zkusil před měsícem takže úplná lama.
Můj první pokus s komponentou StringGrid.
Takže
5 sloupců, do kterých načítám data ze souboru.
Je už 489 řádku.
Jeden  LabeledEdit , který filtruje to načítaní.
Pokud je prázdny načte vše.
Pokud zadám  třeba  A – načte jen ty řádky, kde ve sloupci 1 začínají na A .

Tím pádem je ve  StringGridu někdy jen par řádku a někdy hafo.
Pokud je řádku málo a vlezou do StringGridu tak je vše OK.
Pokud jich je však vice a zobrazí se vertikál scrollbar, tak po kliknuti na některou buňku ve 4 sloupci to dopadne takto.

http://www.fastimages.eu/images/mujtest.jpg

Prostě sloupce se posunou o 1 vlevo.
Poradíte jak to vyřešit.
Da se nějak zjistit zda je ve StringGridu zobrazen vertikál  scrollbar.

Kód: Delphi [Vybrat]
  1. procedure TForm1.AutoSizeCol(Grid: TStringGrid; Column: integer);
  2. var
  3.   i, W, WMax: integer;
  4. begin
  5.   WMax := 0;
  6.   for i := 0 to (Grid.RowCount - 1) do begin
  7.     W := Grid.Canvas.TextWidth(Grid.Cells[Column, i]);
  8.     if W > WMax then
  9.       WMax := W;
  10.   end;
  11.   Grid.ColWidths[Column] := WMax + 15;    {šiřka sloupce}
  12. end;
  13.  
  14. procedure TForm1.FormCreate(Sender: TObject);
  15. begin
  16. StringGrid1.Cells[1,1]:='Muj test';
  17. StringGrid1.Cells[2,1]:='Muj test';
  18. StringGrid1.Cells[3,1]:='Muj test';
  19. StringGrid1.Cells[4,1]:='Muj test';
  20. end;
  21.  
  22. procedure TForm1.FormShow(Sender: TObject);
  23. var sirkasloupcu:Integer;
  24. Begin
  25. StringGrid1.ColWidths[0] := 25;
  26.     AutoSizeCol(StringGrid1, 1);
  27.     AutoSizeCol(StringGrid1, 2);
  28.     AutoSizeCol(StringGrid1, 3);
  29.     AutoSizeCol(StringGrid1, 4);
  30.     StringGrid1.ColWidths[5] := 70;
  31.  
  32.     sirkasloupcu:= StringGrid1.ColWidths[0]
  33.              + StringGrid1.ColWidths[1]
  34.              + StringGrid1.ColWidths[2]
  35.              + StringGrid1.ColWidths[3]
  36.              + StringGrid1.ColWidths[4]
  37.              + StringGrid1.ColWidths[5];
  38.     StringGrid1.width:= sirkasloupcu +5;
  39.     StringGrid1.clientwidth:= sirkasloupcu +5;
  40. End;
  41.  
  42.  

Offline Jan Fiala

  • Příspěvků: 49
  • Karma: 0
    • PSPad editor
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #1 kdy: 20-09-2012, 09:27:28 »
Mas nastaven pevny prvni sloupec. Nastav property FixedCols=0, do gridu zapisuj od sloupce 0 a ne od sloupce 1.
FixedCols a FixedRows (ty sede) se pouzivaji k tomu, aby byly videt vse (treba nadpisy sloupcu).

Venca s Brna

  • Host
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #2 kdy: 21-09-2012, 06:13:44 »
Tak jsem si s tým hrál celou noc a výsledek žádný  :-\

Nastavil jsem všechny sloupce na pevno.
Nastavil FixedCols := 0
A zapisují od sloupce 0

Kód: Delphi [Vybrat]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3. StringGrid1.FixedCols := 0;
  4. StringGrid1.Cells[0,1]:='Muj test';
  5. StringGrid1.Cells[1,1]:='Muj test';
  6. StringGrid1.Cells[2,1]:='Muj test';
  7. StringGrid1.Cells[3,1]:='Muj test';
  8. StringGrid1.Cells[4,1]:='Muj test';
  9. end;
  10.  
  11. procedure TForm1.FormShow(Sender: TObject);
  12. var sirkasloupcu:Integer;
  13. Begin
  14.  
  15. StringGrid1.ColWidths[0] := 60;
  16. StringGrid1.ColWidths[1] := 60;
  17. StringGrid1.ColWidths[2] := 60;
  18. StringGrid1.ColWidths[3] := 60;
  19. StringGrid1.ColWidths[4] := 100;
  20.  
  21. sirkasloupcu:= StringGrid1.ColWidths[0]
  22.              + StringGrid1.ColWidths[1]
  23.              + StringGrid1.ColWidths[2]
  24.              + StringGrid1.ColWidths[3]
  25.              + StringGrid1.ColWidths[4];
  26.  
  27.     StringGrid1.width:= sirkasloupcu ;
  28.     StringGrid1.clientwidth:= sirkasloupcu;
  29. End;
  30.  


Výsledek je stejný.
Při kliknuti na nějakou buňku v posledním sloupci se to posune

Přestane to blbnout když přesně nastavím StringGrid1.width a StringGrid1.clientwidth
což je sirkasloupcu + 5 čar mezi buňkami
Kód: Delphi [Vybrat]
  1. StringGrid1.width:= sirkasloupcu +5 ;
  2. StringGrid1.clientwidth:= sirkasloupcu +5;
  3.  
Když se však načte do StringGridu jen par řádku a scrollbar se nezobrazí , mam za buňkami  prázdné místo kde patři scrollbar.

A znovu můj dotaz, který jsem tu už psal.
Da se nějak zjistit zda je ve StringGridu zobrazen vertikál  scrollbar ???

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2668
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #3 kdy: 21-09-2012, 09:05:42 »
Přestane to blbnout když přesně nastavím StringGrid1.width a StringGrid1.clientwidth
což je sirkasloupcu + 5 čar mezi buňkami

Ano, zalezi co od toho ocekavas. Zpravidla se urci jeden sloupec jehoz sirka se dynamicky dopocitava. Ovsem ne prictenim konstatny, ale hodnotou vypoctenou z GridLineWidth a ColCount.


A znovu můj dotaz, který jsem tu už psal.
Da se nějak zjistit zda je ve StringGridu zobrazen vertikál  scrollbar ???

Zjistuje se to stejne jako u kterehokoli jineho okna pomoci API funkce GetWindowLong s parametrem GWL_STYLE.

Venca s Brna

  • Host
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #4 kdy: 22-09-2012, 07:16:13 »
Hm.
Psal jsem, že jsem lama a delphi vidím teprve měsíc.
To asi sám nedám.
Nepomůže někdo.

Prostě aby se vždy při načtení dat zjistilo, zda je scrollbar zobrazen.

Pak bych přes IF a else mohl nastavit pro každou situaci jinou šířku.

Ono když nastavím StringGrid1.width a StringGrid1.clientwidth úplně přesně tak je to ok.
Když zmizne scrollbar tak tam je prázdna mezera.
To mi nevadí.
Mam však za těmi buňkami ještě další 3, které mají šířku -1 a načítám do nich další data, které se nemají zobrazovat.
Ve Win 7 je to OK.
Ve Win XP se při schovaní scrollbar kousek té tabulky zobrazí i když má šířku hodnotu -1
A to mi vadí.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1472
  • Karma: 36
    • Pepak.net
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #5 kdy: 22-09-2012, 07:32:59 »
Aha. Takže problém není ani tak o tom, jak zjistit, jestli je scrollbar zobrazený nebo ne, ale jak si do stringgridu přidat další data tak, aby se nezobrazovala.

Tak v první řadě, ta extra data můžeš nacpat do Objects[x,y] - každá buňka gridu má jeden asociovaný objekt, který je tvůj a můžeš si s ním dělat, co chceš. Takže si například můžeš vytvořit třídu, která bude držet všechna tvoje data, a její instanci pak vždy přiřadit do prvního sloupečku příslušného řádku.
Kód: Delphi [Vybrat]
  1. type
  2.   TTridaNaData = class
  3.     ID: integer;
  4.     Nazev: string;
  5.     JaNevimCoJeste: TDateTime;
  6.     end;
  7.  
  8. // ...
  9.  
  10. var
  11.   Data: TTridaNaData;
  12. begin
  13.   Grid.RowCount := 10; // to sis nejak spocital
  14.   Grid.ColCount := 5; // to chces zobrazovat
  15.   for i := 0 to Pred(Grid.RowCount) do
  16.     begin
  17.     Grid[0, i] := '...';
  18.     Grid[1, i] := '...';
  19.     // atd. pro dalsi sloupecky
  20.     Data := TTridaNaData.Create;
  21.     Data.ID := 1;
  22.     Data.Nazev := 'abcd';
  23.     Grid.Objects[0, i] := Data;
  24.     end;
  25. end;
Samozřejmě s tím, že si ošetříš výjimky a taky to, aby se ty objekty zase někdy uvolnily. Pak k těm uloženým datům můžeš přistupovat:
Kód: Delphi [Vybrat]
  1. function VratNazev(Radek: integer): string;
  2. var
  3.   Data: TTridaNaData;
  4. begin
  5.   Data := TTridaNaData(Grid1.Objects[0, Radek]);
  6.   Result := Data.Nazev;
  7. end;

Venca s Brna

  • Host
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #6 kdy: 22-09-2012, 09:24:45 »
Děkují moooc, hned vyzkoušim.
Stejnak by mně však zajimalo jak zjistim zda je scrollbar u StringGridu  zobrazen.
Ja myslel že je současti StringGridu a pokud jsem to tu dobře pochopil tak je to samostatna komponenta ktera se k StringGridu přiřadí.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2668
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #7 kdy: 22-09-2012, 10:04:41 »
Stejnak by mně však zajimalo jak zjistim zda je scrollbar u StringGridu  zobrazen.
Ja myslel že je současti StringGridu a pokud jsem to tu dobře pochopil tak je to samostatna komponenta ktera se k StringGridu přiřadí.
No to by byl prece nesmysl, aby se kazdy widget, ktery potrebuje rolovat s obsahem, staral o rolovatka. Ve Windows je rolovatko jako vsechno co je videt na obrazovce windows, tj. ma vlastni handle a komunikuje se s nim pres zpravy, viz treba http://msdn.microsoft.com/en-us/library/ms997557.aspx.

A jestli ma widget viditelne scrollbary se zjisti dotazem na vlastnost widgetu:
Kód: Delphi [Vybrat]
  1. styles := GetWindowLong(StringGrid1.Handle,GWL_STYLE);
Zbytek uz si snad dostudujes treba tady http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx.

A pokud budes dopocitavat sirku tak, aby to fungovalo na ruznych Windows, tak bys nemel opomenout http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).aspx

Venca s Brna

  • Host
Re:Jak správně nastavit šiřku StringGridu
« Odpověď #8 kdy: 22-09-2012, 15:55:16 »
Děkují oboum.  ;D
Zas o trochu chytřejši.
Kód: Delphi [Vybrat]
  1. if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_VSCROLL) <> 0 then
  2.