Sign in Join
Wiki copytemporary

Grids Reference Page/pl: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Strona referencyjna siatek Grid
22
3-## Contents
4-
5- * 1 Intencje
6- * 2 Wprowadzenie
7- * 3 Drzewo dziedziczenia
8- * 4 Pierwszy przykład
9- * 5 Różnice pomiędzy komponentami siatki Lazarusa i Delphi
10- * 5.1 Różnice
11- * 5.2 Nowe funkcje
12- * 5.3 Sposoby na to, by siatka Lazarus była bardziej zgodna z Delphi
13- * 6 Charakterystyka siatek
14- * 6.1 Informacja
15- * 6.2 TCustomGrid
16- * 6.2.1 Właściwość AllowOutboundEvents
17- * 6.2.2 Właściwość Columns
18- * 6.2.3 Właściwość AutoFillColumns
19- * 6.2.4 Procedura SaveToFile(AFileName: String)
20- * 6.2.5 Procedura LoadFromFile(AFileName: String)
21- * 6.3 TCustomDBGrid
22- * 6.3.1 Procedura AutoAdjustColumns
23- * 6.3.2 Procedura InplaceEditor
24- * 6.4 TCustomStringGrid
25- * 6.4.1 Procedura AutoSizeColumn(aCol: Integer)
26- * 6.4.2 Procedura AutoAdjustColumns lub AutoSizeColumns
27- * 6.4.3 Procedura Clean; overload;
28- * 6.4.4 Procedura Clean(CleanOptions: TGridZoneSet); overload;
29- * 6.4.5 Procedura Clean(StartCol,StartRow,EndCol,EndRow: integer; CleanOptions:TGridZoneSet); overload;
30- * 6.4.6 Procedura Clean(aRect: TRect; CleanOptions: TGridZoneSet); overload;
31- * 6.4.7 Procedura SaveToCSVFile(AFileName: string; ADelimiter:Char=','; WithHeader:boolean=true);
32- * 6.4.8 Procedura LoadFromCSVFile(AFileName: string; ADelimiter:Char=','; WithHeader:boolean=true);
33- * 6.4.9 Właściwość Cols[index: Integer]: TStrings read GetCols write SetCols;
34- * 6.4.9.1 Przykłady
35- * 6.4.9.2 Uwagi
36- * 6.4.10 Właściwość Rows[index: Integer]: TStrings read GetRows write SetRows;
37- * 6.4.10.1 Uwagi
38- * 6.4.10.2 Przykłady
39- * 6.4.11 Właściwość UseXORFeatures
40- * 6.5 TValueListEditor
41- * 6.5.1 Właściwość DisplayOptions
42- * 6.5.2 Właściwość TitleCaptions
43- * 6.5.3 Właściwość Strings
44- * 6.5.4 Właściwość ItemProps
45- * 6.5.5 Właściwość KeyOptions
46- * 6.5.6 Właściwość DropDownRows
47- * 6.5.7 Funkcja DeleteRow
48- * 6.5.8 Funkcja InsertRow
49- * 6.5.9 Funkcja IsEmptyRow
50- * 6.5.10 Funkcja FindRow
51- * 6.5.11 Funkcja RestoreCurrentRow
52- * 6.5.12 Zmienione zachowanie niektórych właściwości pochodzących z TCustomStringGrid
53- * 6.5.12.1 Właściwość Options
54- * 6.5.12.2 Właściwość FixedRows
55- * 6.5.12.3 Właściwość ColCount
56- * 6.5.12.4 Właściwość Objects
57- * 6.5.13 Ogólne uwagi dotyczące korzystania z TValueListEditor
58- * 6.5.14 Zapisywanie i ładowanie zawartości TValueListEditor
59- * 6.5.14.1 Korzystanie z właściwości Strings
60- * 6.5.14.2 Korzystanie z TValueList.SaveToFile i TValueList.LoadFromFile
61- * 6.5.14.3 Korzystanie z metod SaveToCSVFile i LoadFromCSV
62- * 7 Praca z siatkami
63- * 7.1 Dostosowywanie siatek
64- * 7.2 Właściwości i Zdarzenia dostosowujące siatek
65- * 7.3 Opis procesu rysowania siatki
66- * 7.3.1 Różnice w porównaniu z Delphi
67- * 7.4 Wybór komórki w siatce
68- * 7.4.1 Różnice w porównaniu z Delphi
69- * 7.5 Gdy powyższe dostosowanie nie wystarczy, siatki pochodne
70- * 7.6 Co dzieje się w metodzie TCustomGrid.Paint?
71- * 7.6.1 Dodatkowe metody rysowania w TCustomGrid
72- * 7.6.2 Metody rysowania wprowadzone przez TCustomDrawGrid
73- * 7.7 Zapisz i Odzyskaj zawartość siatki
74- * 7.8 Edytory komórek siatki
75- * 7.8.1 Wbudowane edytory komórek
76- * 7.8.2 Korzystanie z edytorów komórek
77- * 7.8.3 Opis stylów edytora
78- * 7.9 Edycja siatek
79- * 7.9.1 Opcje i właściwości wpływające na edycję
80- * 7.10 Hint dla komórek
81- * 8 Grids w praktyce i przykłady
82- * 8.1 Skupienie komórki
83- * 8.2 Przykład: Jak ustawić niestandardowy edytor komórek
84- * 8.2.1 Przykład: Jak dodać edytor przycisków
85- * 8.3 Przykład: Praca z PickList, jak ustawić ją tylko do odczytu i jak wypełnić w czasie wykonywania
86- * 8.4 Wyrównywanie tekstu w StringGrids
87- * 8.5 Wielowierszowy tekst w siatkach
88- * 8.6 Weryfikacja wprowadzonych wartości
89- * 8.7 Sortowanie kolumn lub wierszy
90- * 8.8 Zastąp sortowanie automatyczne (ColumnClickSorts ustawione na False ). Unikaj niektórych kolumn. Pokaż strzałki sortowania w nagłówku kolumny
91- * 8.9 Podświetlenie wybranych komórek kolumny i wiersza
92- * 8.10 Unikanie pustego miejsca po prawej stronie ostatniej kolumny
93- * 8.11 Jak przewijać siatkę w czasie rzeczywistym (przesuwanie paska przewijania za pomocą myszy)
94- * 8.12 Jak zmienić rozmiar wiersza na podstawie zawartości komórek?
95- * 9 DBGrids w praktyce i przykłady
96- * 9.1 Przykład: Jak ustawić edytor memo dla dbgrids
97- * 9.2 Przykład: Unikaj wyświetlania pól tekstowych jako „(Memo)” dla DBGrids
98- * 9.3 Sortowanie kolumn lub wierszy w DBGrid ze strzałkami sortowania w nagłówku kolumny
99- * 9.4 Wybieranie rekordów w DBGrid za pomocą pól wyboru
100- * 9.5 Przykład: Jak wyeksportować DBGrid do pliku tekstowego
101-
1023## Intencje
1034
104-Ten tekst będzie próbą pokazania użytkownikowi niektórych aspektów komponentów siatek (grids) w Lazarusie. Ma również służyć jako przewodnik dla użytkowników, którzy nigdy dotąd nie używali komponentów siatek (ponieważ doświadczeni użytkownicy zazwyczaj potrzebują jedynie informacji dotyczących nowych funkcji). W niniejszym tekście postaram się zatem osiągnąć następujące cele:
5+Ten tekst będzie próbą pokazania użytkownikowi niektórych aspektów komponentów siatek (grids) w Lazarusie. Ma również służyć jako przewodnik dla użytkowników, którzy nigdy dotąd nie używali komponentów siatek (ponieważ doświadczeni użytkownicy zazwyczaj potrzebują jedynie informacji dotyczących nowych funkcji). W niniejszym tekście postaram się zatem osiągnąć następujące cele:
1056
106- 1. Przedstawić komponenty siatki osobom z niewielkim lub żadnym doświadczeniem w Delphi.
107- 2. Udokumentować różnice w odniesieniu do komponentów siatek Delphi.
108- 3. Udokumentować nową funkcjonalność w siatkach Lazarusa.
109- 4. Utworzyć referencje i przykłady dla tych komponentów.
7+1. Przedstawić komponenty siatki osobom z niewielkim lub żadnym doświadczeniem w Delphi.
8+2. Udokumentować różnice w odniesieniu do komponentów siatek Delphi.
9+3. Udokumentować nową funkcjonalność w siatkach Lazarusa.
10+4. Utworzyć referencje i przykłady dla tych komponentów.
11011
11112## Wprowadzenie
11213
113-Siatka (Grid) to komponent, który umożliwia wyświetlanie danych w formacie tabelarycznym. Najbardziej oczywistą cechą siatek jest to, że składają się one z komórek tworzących rzędy i kolumny, podobnie jak w arkuszu kalkulacyjnym.
14+Siatka (Grid) to komponent, który umożliwia wyświetlanie danych w formacie tabelarycznym. Najbardziej oczywistą cechą siatek jest to, że składają się one z komórek tworzących rzędy i kolumny, podobnie jak w arkuszu kalkulacyjnym.
11415
115-Ilość typów informacji, które można wyświetlić w siatce, jest różna i zależy głównie od tego, co użytkownik chce pokazać. Ogólnie informacje te składają się z tekstów, kolorów, obrazów lub kombinacji tych trzech.
16+Ilość typów informacji, które można wyświetlić w siatce, jest różna i zależy głównie od tego, co użytkownik chce pokazać. Ogólnie informacje te składają się z tekstów, kolorów, obrazów lub kombinacji tych trzech.
11617
117-Biorąc pod uwagę ogromną różnorodność informacji, które można przedstawić, istnieje szereg siatek, których celem jest ułatwienie użytkownikowi pokazania określonych rodzajów informacji. Na przykład istnieje siatka przeznaczona do wyświetlania tekstu: **StringGrid**. Dokumentację dla tej siatki można znaleźć [tutaj](<http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tstringgrid.html>)
18+Biorąc pod uwagę ogromną różnorodność informacji, które można przedstawić, istnieje szereg siatek, których celem jest ułatwienie użytkownikowi pokazania określonych rodzajów informacji. Na przykład istnieje siatka przeznaczona do wyświetlania tekstu: **StringGrid**. Dokumentację dla tej siatki można znaleźć [tutaj](http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tstringgrid.html)
11819
11920## Drzewo dziedziczenia
120-```
121-[TCustomControl](</index.php?title=TCustomControl&action=edit&redlink=1> "TCustomControl \(page does not exist\)")
122- |
123- |
124- TCustomGrid
125- |
126- +-------------+------------+
127- | |
128- TCustomDrawGrid TCustomDbGrid
129- | |
130- +--------+--------+ |
131- | | [[TDBGrid]]
132- [[TDrawGrid]] TCustomStringGrid
133- |
134- |
135- [[TStringGrid]]
136-```
13721
22+`                     `[[TCustomControl]]\
23+`                             |`\
24+`                             |`\
25+`                        TCustomGrid`\
26+`                             |`\
27+`               +-------------+------------+`\
28+`               |                          |`\
29+`         TCustomDrawGrid             TCustomDbGrid`\
30+`               |                          |`\
31+`      +--------+--------+                 |`\
32+`      |                 |              `[[TDBGrid]]\
33+`  `[[TDrawGrid]]`      TCustomStringGrid                `\
34+`                        |`\
35+`                        |`\
36+`                   `[[TStringGrid]]
37+
13838## Pierwszy przykład
13939
140-Ponieważ jednym z celów tej strony jest pomoc osobom z niewielką lub żadną wcześniejszą wiedzą o Lazarusie, zróbmy wprowadzający przykład użycia siatek. Dlaczego nie, stwórzmy tradycyjny przykład „Witaj Świecie!” (ang. "Hello World") za pomocą komponentu TStringGrid.
40+Ponieważ jednym z celów tej strony jest pomoc osobom z niewielką lub żadną wcześniejszą wiedzą o Lazarusie, zróbmy wprowadzający przykład użycia siatek. Dlaczego nie, stwórzmy tradycyjny przykład „Witaj Świecie!” (ang. "Hello World") za pomocą komponentu TStringGrid.
14141
142- 1. Stwórz nową aplikację.
143- * Z menu głównego wybierz: Projekt->Nowy projekt...
144- * W oknie dialogowym Utwórz nowy projekt wybierz Aplikacja i naciśnij „OK”
145- * Zostanie wyświetlony nowy pusty formularz.
146- 2. Umieść siatkę (grid) na formularzu
147- * Z palety komponentów wybierz zakładkę „Additional”
148- * Kliknij ikonę TStringGrid [![tstringgrid.png](/wiki-images/c/c4/tstringgrid.png)](</File:tstringgrid.png>)
149- * Kliknij formularz w lewym górnym rogu. Pojawi się nowa pusta siatka.
150- 3. Umieść przycisk na formularzu
151- * Z palety komponentów wybierz zakładkę „Standard”
152- * Kliknij ikonę TButton [![tbutton.png](/wiki-images/b/b2/tbutton.png)](</File:tbutton.png>)
153- * Kliknij na pusty obszar formularza. Pojawi się nowy przycisk.
42+1. Stwórz nową aplikację.
43+ - Z menu głównego wybierz: Projekt-\>Nowy projekt...
44+ - W oknie dialogowym Utwórz nowy projekt wybierz Aplikacja i naciśnij „OK”
45+ - Zostanie wyświetlony nowy pusty formularz.
46+2. Umieść siatkę (grid) na formularzu
47+ - Z palety komponentów wybierz zakładkę „Additional”
48+ - Kliknij ikonę TStringGrid ![](/wiki-images/6/67/Tstringgrid.png)
49+ - Kliknij formularz w lewym górnym rogu. Pojawi się nowa pusta siatka.
50+3. Umieść przycisk na formularzu
51+ - Z palety komponentów wybierz zakładkę „Standard”
52+ - Kliknij ikonę TButton ![](/wiki-images/b/b2/Tbutton.png)
53+ - Kliknij na pusty obszar formularza. Pojawi się nowy przycisk.
15454
155-Kliknij dwukrotnie przycisk z kroku 3 i zapisz następujący kod w module obsługi przycisku kliknięcia:
55+Kliknij dwukrotnie przycisk z kroku 3 i zapisz następujący kod w module obsługi przycisku kliknięcia:
15656
157- 1. *
158-```
57+\#*
58+
59+``` Pascal
15960StringGrid1.Cells[1,1] := 'Witaj Świecie!';
16061```
16162
162- 2. Uruchom program, klikając ikonę odtwarzania [![menu run.png](/wiki-images/0/0d/menu_run.png)](</File:menu_run.png>)
163- * po naciśnięciu przycisku Button1 w komórce w kolumnie 1 i wierszu 1 powinien pojawić się tekst „Witaj Świecie!”. (zwróć uwagę, że indeksy lewej kolumny i górnego wiersza są równe 0)
63+1. Uruchom program, klikając ikonę odtwarzania ![](/wiki-images/8/85/Menu_run.png)
64+ - po naciśnięciu przycisku Button1 w komórce w kolumnie 1 i wierszu 1 powinien pojawić się tekst „Witaj Świecie!”. (zwróć uwagę, że indeksy lewej kolumny i górnego wiersza są równe 0)
16465
16566## Różnice pomiędzy komponentami siatki Lazarusa i Delphi
16667
167-Obecne elementy siatek różnią się od siatek Delphi na kilka sposobów. Jest to spowodowane głównie tym, że kiedy po raz pierwszy opracowano siatki dla Lazarusa, były one tworzone od zera bez żadnych prób uczynienia ich w pełni kompatybilnymi z Delphi.
68+Obecne elementy siatek różnią się od siatek Delphi na kilka sposobów. Jest to spowodowane głównie tym, że kiedy po raz pierwszy opracowano siatki dla Lazarusa, były one tworzone od zera bez żadnych prób uczynienia ich w pełni kompatybilnymi z Delphi.
16869
169-Na późniejszym etapie kompatybilność z siatkami Delphi stała się pożądanym celem, a siatki Lazarus zaczęły być bardziej zgodne z interfejsem sieci Delphi. Jednak nawet to zostało zrobione bez próby dopasowania każdej właściwości lub metody siatki Lazarusa do swojego odpowiednika w Delphi. Ponadto (ponieważ wewnętrzne elementy siatki Lazarusa bardzo różnią się od wewnętrznych elementów siatki Delphi) niektóre funkcje Delphi nie są dostępne lub muszą być emulowane w inny sposób w siatce Lazarusa niż w przypadku siatki Delphi. Osiągnęliśmy większą kompatybilność z Delphi w miarę ewolucji siatek Lazarusa i jest to pożądane.
70+Na późniejszym etapie kompatybilność z siatkami Delphi stała się pożądanym celem, a siatki Lazarus zaczęły być bardziej zgodne z interfejsem sieci Delphi. Jednak nawet to zostało zrobione bez próby dopasowania każdej właściwości lub metody siatki Lazarusa do swojego odpowiednika w Delphi. Ponadto (ponieważ wewnętrzne elementy siatki Lazarusa bardzo różnią się od wewnętrznych elementów siatki Delphi) niektóre funkcje Delphi nie są dostępne lub muszą być emulowane w inny sposób w siatce Lazarusa niż w przypadku siatki Delphi. Osiągnęliśmy większą kompatybilność z Delphi w miarę ewolucji siatek Lazarusa i jest to pożądane.
17071
17172### Różnice
17273
173-Znane różnice wymieniono poniżej (kolejność nie ma znaczenia).
74+Znane różnice wymieniono poniżej (kolejność nie ma znaczenia).
17475
175- * Edytor komórek (Cell Editor)
176- * Zachowanie podczas projektowania
177- * Pewne różnice występują podczas rysowania komórek, zobacz sekcję [[Grids Reference Page/pl|Dostosowywanie siatek]].
76+- Edytor komórek (Cell Editor)
77+- Zachowanie podczas projektowania
78+- Pewne różnice występują podczas rysowania komórek, zobacz sekcję [Dostosowywanie siatek](https://wiki.freepascal.org/Grids_Reference_Page/pl#Dostosowywanie_siatek).
17879
17980### Nowe funkcje
18081
181- * Kolumny
182- * Zdarzenia
183- * Edytor siatki (Grid Editor)
82+- Kolumny
83+- Zdarzenia
84+- Edytor siatki (Grid Editor)
18485
18586### Sposoby na to, by siatka Lazarus była bardziej zgodna z Delphi
18687
187-Oto lista właściwości i korekt, które mogą być wykonane w celu dostosowania wyglądu lub zachowania komponentów grids Lazarusa do tych z Delphi. Korekty te odnoszą się do nowo utworzonej siatki. Wpisy z etykietą [Kod] należy wykonać w kodzie, a z etykietą [Projekt] można zmieniać w czasie projektowania.
88+Oto lista właściwości i korekt, które mogą być wykonane w celu dostosowania wyglądu lub zachowania komponentów grids Lazarusa do tych z Delphi. Korekty te odnoszą się do nowo utworzonej siatki. Wpisy z etykietą \[Kod\] należy wykonać w kodzie, a z etykietą \[Projekt\] można zmieniać w czasie projektowania.
18889
189-Możesz sprawić, by siatka Lazarusa wyglądała i zachowywała się tak, jak jej odpowiednik w Delphi. Poniżej wymienione są ustawienia właściwości, które pozwolą to osiągnąć. Te dostosowania są oparte na nowo utworzonej siatce. Wpisy oznaczone jako [Kod] należy ustawić w kodzie, wpisy [Projekt] można zmienić w czasie projektowania.
90+Możesz sprawić, by siatka Lazarusa wyglądała i zachowywała się tak, jak jej odpowiednik w Delphi. Poniżej wymienione są ustawienia właściwości, które pozwolą to osiągnąć. Te dostosowania są oparte na nowo utworzonej siatce. Wpisy oznaczone jako \[Kod\] należy ustawić w kodzie, wpisy \[Projekt\] można zmienić w czasie projektowania.
19091
191- * [Projekt] TitleStyle := tsStandard;
192- * [Projekt] DefaultRowHeight := 24;
193- * [Kod] EditorBorderStyle := bsNone; //to może działać tylko w Windows
194- * [Kod] UseXORFeatures := true;
195- * [Kod] AllowOutBoundEvents := False; //rewizja SVN r10992 lub nowsza
196- * [Kod] FastEditing := False; //obsługiwane w dbgrid. StringGrid wymaga wersji SVN r10992 lub nowszej
197- * [Projekt] AutoAdvance := aaNone;
92+- \[Projekt\] TitleStyle := tsStandard;
93+- \[Projekt\] DefaultRowHeight := 24;
94+- \[Kod\] EditorBorderStyle := bsNone; //to może działać tylko w Windows
95+- \[Kod\] UseXORFeatures := true;
96+- \[Kod\] AllowOutBoundEvents := False; //rewizja SVN r10992 lub nowsza
97+- \[Kod\] FastEditing := False; //obsługiwane w dbgrid. StringGrid wymaga wersji SVN r10992 lub nowszej
98+- \[Projekt\] AutoAdvance := aaNone;
19899
199100## Charakterystyka siatek
200101
201102### Informacja
202103
203-Punktem wyjścia dla referencji o TCustomGrid, TDrawGrid, TCustomDrawGrid, TCustomStringGrid i TStringGrid jest [referencje modułu Grids.pas](<http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html>)
104+Punktem wyjścia dla referencji o TCustomGrid, TDrawGrid, TCustomDrawGrid, TCustomStringGrid i TStringGrid jest [referencje modułu Grids.pas](http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html)
204105
205-Natomiast dla TCustomDBGrid i TDBgrid jest [referencje modułu DBGrids.pas](<http://lazarus-ccr.sourceforge.net/docs/lcl/dbgrids/index.html>)
106+Natomiast dla TCustomDBGrid i TDBgrid jest [referencje modułu DBGrids.pas](http://lazarus-ccr.sourceforge.net/docs/lcl/dbgrids/index.html)
206107
207-Zazwyczaj jakichkolwiek informacje o komponentach grids dla Delphi powinny pomóc nam także w Lazarusie (ale nie zapominajmy o tych kilku różnicach pomiędzy Delphi i Lazarusem, które są udokumentowane); przy czym traktuj takie dane jako tymczasowe źródło informacji, które nie zawsze będą działały tak samo jak w Delphi.
108+Zazwyczaj jakichkolwiek informacje o komponentach grids dla Delphi powinny pomóc nam także w Lazarusie (ale nie zapominajmy o tych kilku różnicach pomiędzy Delphi i Lazarusem, które są udokumentowane); przy czym traktuj takie dane jako tymczasowe źródło informacji, które nie zawsze będą działały tak samo jak w Delphi.
208109
209-TODO: Dalsza część tego rozdziału zniknie, a jego zawartość zostanie przeniesiona do [referencje modułu Grids.pas](<http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html>)
110+TODO: Dalsza część tego rozdziału zniknie, a jego zawartość zostanie przeniesiona do [referencje modułu Grids.pas](http://lazarus-ccr.sourceforge.net/docs/lcl/grids/index.html)
210111
211112### TCustomGrid
212113
213-Wszystko zobaczysz w: [Referencje TCustomGrid](<http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tcustomgrid.html> "doc:lcl/grids/tcustomgrid.html")
114+Wszystko zobaczysz w: [[doc:lcl/grids/tcustomgrid.html|Referencje TCustomGrid]]
214115
215116#### Właściwość AllowOutboundEvents
216117
217-Właściwość chroniona w klasie TCustomGrid oraz publiczna w klasie TCustomDrawGrid i klasach potomnych. Zwykle, gdy użytkownik kliknie punkt nad pustą przestrzenią za komórkami (na przykład, jeśli siatka ma trzy wiersze, ale użytkownik kliknie wyimaginowany czwarty wiersz), komórka, w której aktualnie znajduje się fokus, przesunie się do komórki najbliższej punktu, który właśnie kliknął. Nazywamy to wydarzeniem wychodzącym. Wartość domyślna to True, ponieważ tak właśnie działa siatka od samego początku. Ta właściwość została dodana, aby symulować zachowanie Delphi, gdy zdarzenia wychodzące nie są dostępne, więc aby umożliwić zgodność z Delphi, ustaw tę właściwość na False.
118+Właściwość chroniona w klasie TCustomGrid oraz publiczna w klasie TCustomDrawGrid i klasach potomnych. Zwykle, gdy użytkownik kliknie punkt nad pustą przestrzenią za komórkami (na przykład, jeśli siatka ma trzy wiersze, ale użytkownik kliknie wyimaginowany czwarty wiersz), komórka, w której aktualnie znajduje się fokus, przesunie się do komórki najbliższej punktu, który właśnie kliknął. Nazywamy to wydarzeniem wychodzącym. Wartość domyślna to True, ponieważ tak właśnie działa siatka od samego początku. Ta właściwość została dodana, aby symulować zachowanie Delphi, gdy zdarzenia wychodzące nie są dostępne, więc aby umożliwić zgodność z Delphi, ustaw tę właściwość na False.
218119
219120#### Właściwość Columns
220121
221-Lazarus zawiera właściwość **columns** w siatkach TStringGrid i TDrawGrid. Ta właściwość dodaje to, co nazywamy kolumnami niestandardowymi. Kolumny niestandardowe to zbiór obiektów, które przechowują właściwości, które mają zastosowanie do całych kolumn, na przykład tytuły kolumn (w przypadku StringGrid zastąpi wartość określoną w odpowiedniej właściwości Cells[ColumnIndex, RowTitle]), wyrównanie tekstu, kolor tła, preferowany edytor itp.
122+Lazarus zawiera właściwość **columns** w siatkach TStringGrid i TDrawGrid. Ta właściwość dodaje to, co nazywamy kolumnami niestandardowymi. Kolumny niestandardowe to zbiór obiektów, które przechowują właściwości, które mają zastosowanie do całych kolumn, na przykład tytuły kolumn (w przypadku StringGrid zastąpi wartość określoną w odpowiedniej właściwości Cells\[ColumnIndex, RowTitle\]), wyrównanie tekstu, kolor tła, preferowany edytor itp.
222123
223-Kolumny niestandardowe dodają dodatkowe właściwości lub zastępują domyślne wartości właściwości w normalnych kolumnach siatki. Ponadto, wartość **grid.ColCount** może się zwiększyć lub zmniejszyć w celu uwzględnienia liczby niestandardowych kolumn dołączanych do siatki. A to oznacza, że **grid.ColCount** = **grid.FixedCols** \+ **grid.Columns.Count**.
124+Kolumny niestandardowe dodają dodatkowe właściwości lub zastępują domyślne wartości właściwości w normalnych kolumnach siatki. Ponadto, wartość **grid.ColCount** może się zwiększyć lub zmniejszyć w celu uwzględnienia liczby niestandardowych kolumn dołączanych do siatki. A to oznacza, że **grid.ColCount** = **grid.FixedCols** + **grid.Columns.Count**.
224125
225-Na przykład, jeśli mamy siatkę bazową z ColCount := 5 i FixedCols := 2 i wykonamy:
126+Na przykład, jeśli mamy siatkę bazową z ColCount := 5 i FixedCols := 2 i wykonamy:
226127
227- * Dodaj 3 niestandardowe kolumny, to siatka bazowa będzie dokładnie taka sama, jak poprzednio, 2 stałe kolumny i 3 normalne kolumny.
228- * Dodaj 1 niestandardową kolumnę, to siatka bazowa będzie miała ColCount := 3, czyli 2 stałe kolumny i 1 normalną kolumnę.
229- * Dodaj 4 niestandardowe kolumny, to siatka bazowa będzie miała ColCount := 6, czyli 2 stałe kolumny i 4 normalne kolumny.
128+- Dodaj 3 niestandardowe kolumny, to siatka bazowa będzie dokładnie taka sama, jak poprzednio, 2 stałe kolumny i 3 normalne kolumny.
129+- Dodaj 1 niestandardową kolumnę, to siatka bazowa będzie miała ColCount := 3, czyli 2 stałe kolumny i 1 normalną kolumnę.
130+- Dodaj 4 niestandardowe kolumny, to siatka bazowa będzie miała ColCount := 6, czyli 2 stałe kolumny i 4 normalne kolumny.
230131
231-Z tego możemy wywnioskować, że:
132+Z tego możemy wywnioskować, że:
232133
233- * Stałe właściwości lub liczba kolumn nie są odpowiednio ulepszane ani modyfikowane przez kolumny niestandardowe.
234- * **grid.ColCount** zwykle różni się od **grid.Columns.Count** ('_grid.ColCount**=** grid.Columns.Count**tylko wtedy, gdy '**_**FixedCols** =0)
134+- Stałe właściwości lub liczba kolumn nie są odpowiednio ulepszane ani modyfikowane przez kolumny niestandardowe.
135+- **grid.ColCount** zwykle różni się od **grid.Columns.Count** (**grid.ColCount**=**grid.Columns.Count** tylko wtedy, gdy ' *FixedCols*'=0)
235136
236-W czasie projektowania w Inspektorze obiektów użytkownik może uzyskać dostęp do właściwości **columns** , aby wywołać edytor kolumn. Stamtąd można dodawać, usuwać lub modyfikować niestandardowe kolumny. Edytor wyświetla listę aktualnych kolumn niestandardowych; wybierając elementy z tej listy, inspektor obiektów zostaje wypełniony właściwościami dostępnymi dla każdej kolumny. Lista niestandardowych kolumn jest również dostępna w widoku drzewa komponentów Inspektora obiektów, gdzie kolumny można dodawać, usuwać lub modyfikować. Pojawiają się na niższym poziomie pod siatką kontenerów.
137+W czasie projektowania w Inspektorze obiektów użytkownik może uzyskać dostęp do właściwości **columns**, aby wywołać edytor kolumn. Stamtąd można dodawać, usuwać lub modyfikować niestandardowe kolumny. Edytor wyświetla listę aktualnych kolumn niestandardowych; wybierając elementy z tej listy, inspektor obiektów zostaje wypełniony właściwościami dostępnymi dla każdej kolumny. Lista niestandardowych kolumn jest również dostępna w widoku drzewa komponentów Inspektora obiektów, gdzie kolumny można dodawać, usuwać lub modyfikować. Pojawiają się na niższym poziomie pod siatką kontenerów.
237138
238-W czasie wykonywania programu, kolumny można modyfikować za pomocą kodu w następujący sposób:
239-```
240-var
241- c: TGridColumn;
242- begin
243- // dodaj niestandardową kolumnę siatki
244- c := Grid.Columns.Add;
245- // modyfikuj kolumnę
246- c.title.caption := 'Price'; // Ustaw tytuły kolumn
247- c.align := taRightJustify; // Wyrównaj zawartość kolumny do prawej
248- c.color := clMoneyGreen; // Zmień domyślny kolor na clMoneyGreen
249- c.Index := 0; // Niech to będzie pierwsza kolumna
250- // uzyskać dostęp do istniejącej kolumny
251- grid.columns[0].Width := 60; // Zmień szerokość kolumny 0 na 60 pikseli
252- // usuń istniejącą kolumnę
253- grid.columns.delete(0); // Usuń kolumnę 0
254- ....
255- end;
139+W czasie wykonywania programu, kolumny można modyfikować za pomocą kodu w następujący sposób:
140+
141+``` pascal
142+ var
143+ c: TGridColumn;
144+ begin
145+ // dodaj niestandardową kolumnę siatki
146+ c := Grid.Columns.Add;
147+ // modyfikuj kolumnę
148+ c.title.caption := 'Price'; // Ustaw tytuły kolumn
149+ c.align := taRightJustify; // Wyrównaj zawartość kolumny do prawej
150+ c.color := clMoneyGreen; // Zmień domyślny kolor na clMoneyGreen
151+ c.Index := 0; // Niech to będzie pierwsza kolumna
152+ // uzyskać dostęp do istniejącej kolumny
153+ grid.columns[0].Width := 60; // Zmień szerokość kolumny 0 na 60 pikseli
154+ // usuń istniejącą kolumnę
155+ grid.columns.delete(0); // Usuń kolumnę 0
156+ ....
157+ end;
256158```
257159
258-Dodatkowo, podczas korzystania z niestandardowych kolumn, siatki nie pozwalają na bezpośrednią modyfikację **grids.colcount** ; dodawanie lub usuwanie kolumn powinno odbywać się za pomocą właściwości **columns**. Wyjaśnienie jest takie, że istnieje niespójność w stopniowym usuwaniu niestandardowych kolumn za pomocą **ColCount** , gdy **ColCount** osiągnie **FixedCols** , siatka nie ma więcej niestandardowych kolumn. Jeśli teraz zwiększymy **ColCount** , nowa kolumna nie będzie kolumną niestandardową, ale normalną.
160+Dodatkowo, podczas korzystania z niestandardowych kolumn, siatki nie pozwalają na bezpośrednią modyfikację **grids.colcount**; dodawanie lub usuwanie kolumn powinno odbywać się za pomocą właściwości **columns**. Wyjaśnienie jest takie, że istnieje niespójność w stopniowym usuwaniu niestandardowych kolumn za pomocą **ColCount**, gdy **ColCount** osiągnie **FixedCols**, siatka nie ma więcej niestandardowych kolumn. Jeśli teraz zwiększymy **ColCount**, nowa kolumna nie będzie kolumną niestandardową, ale normalną.
259161
260-Obecnie nie ma planów, aby siatki wykorzystywały tylko kolumny niestandardowe.
162+Obecnie nie ma planów, aby siatki wykorzystywały tylko kolumny niestandardowe.
261163
262164#### Właściwość AutoFillColumns
263165
264-Często siatki są szersze niż pozioma przestrzeń potrzebna kolumnom - pozostawia to nieprzyjemny pusty obszar po prawej stronie ostatniej kolumny. Siatki LCL zapewniają mechanizm rozszerzania szerokości określonych kolumn w taki sposób, że puste miejsce jest wypełniane automatycznie.
166+Często siatki są szersze niż pozioma przestrzeń potrzebna kolumnom - pozostawia to nieprzyjemny pusty obszar po prawej stronie ostatniej kolumny. Siatki LCL zapewniają mechanizm rozszerzania szerokości określonych kolumn w taki sposób, że puste miejsce jest wypełniane automatycznie.
265167
266-W tym celu należy dodać **Columns** zgodnie z opisem powyżej lub przez ustawienie właściwości `ColCount` oraz właściwości siatki `AutoFillColumns`, która musi być ustawiona na `True`. Każda kolumna ma właściwość `SizePriority`. Gdy ma wartość `0`, szerokość kolumny jest pobierana z właściwości `Width` kolumny. Ale gdy ma wartość niezerową, szerokość kolumny jest dostosowywana do średniego dostępnego rozmiaru pozostałego dla wszystkich kolumn z niezerowym `SizePriority`.
168+W tym celu należy dodać **Columns** zgodnie z opisem powyżej lub przez ustawienie właściwości `ColCount` oraz właściwości siatki `AutoFillColumns`, która musi być ustawiona na `True`. Każda kolumna ma właściwość `SizePriority`. Gdy ma wartość `0`, szerokość kolumny jest pobierana z właściwości `Width` kolumny. Ale gdy ma wartość niezerową, szerokość kolumny jest dostosowywana do średniego dostępnego rozmiaru pozostałego dla wszystkich kolumn z niezerowym `SizePriority`.
267169
268170#### Procedura SaveToFile(AFileName: String)
269171
270-Zapisuje siatkę do pliku XML. Właściwość `SaveOptions` określa, co dokładnie ma zostać zapisane:
271-```
172+Zapisuje siatkę do pliku XML. Właściwość `SaveOptions` określa, co dokładnie ma zostać zapisane:
173+
174+``` Pascal
272175type
273- TGridSaveOptions = (
274- soDesign, // Zapisz strukturę siatki (liczba kolumn/wierszy i opcje - Options)
275- soAttributes, // Zapisz atrybuty siatki (czcionka - Font, pędzel - Brush, styl tekstu TextStyle)
276- soContent, // Zapisz zawartość siatki (tekst w StringGrid)
277- soPosition // Zapisz kursor siatki i pozycję zaznaczenia
278- );
279- TSaveOptions = set of TGridSaveOptions;
176+ TGridSaveOptions = (
177+ soDesign, // Zapisz strukturę siatki (liczba kolumn/wierszy i opcje - Options)
178+ soAttributes, // Zapisz atrybuty siatki (czcionka - Font, pędzel - Brush, styl tekstu TextStyle)
179+ soContent, // Zapisz zawartość siatki (tekst w StringGrid)
180+ soPosition // Zapisz kursor siatki i pozycję zaznaczenia
181+ );
182+ TSaveOptions = set of TGridSaveOptions;
280183```
281184
282185#### Procedura LoadFromFile(AFileName: String)
283186
284-Ładuje plik XML utworzony przez `SaveToFile`. Ponownie, `SaveOptions` określają, co dokładnie ma zostać załadowane z pliku.
187+Ładuje plik XML utworzony przez `SaveToFile`. Ponownie, `SaveOptions` określają, co dokładnie ma zostać załadowane z pliku.
285188
286189### TCustomDBGrid
287190
288-TCustomDBGrid jest podstawą dla TDBGrid.
191+TCustomDBGrid jest podstawą dla TDBGrid.
289192
290-Nie ujawniają właściwości Col i Row. Aby przejść do określonej kolumny, użyj np. właściwość SelectedIndex.
193+Nie ujawniają właściwości Col i Row. Aby przejść do określonej kolumny, użyj np. właściwość SelectedIndex.
291194
292-Ciekawą metodą publiczną jest AutoAdjustColumns.
195+Ciekawą metodą publiczną jest AutoAdjustColumns.
293196
294197#### Procedura AutoAdjustColumns
295198
296-Ta procedura ustawia szerokość kolumny na rozmiar najszerszego znalezionego tekstu. Można go używać po załadowaniu zestawu danych/ustawieniu go jako Aktywny - Active.
199+Ta procedura ustawia szerokość kolumny na rozmiar najszerszego znalezionego tekstu. Można go używać po załadowaniu zestawu danych/ustawieniu go jako Aktywny - Active.
297200
298-Jednak w przeciwieństwie do TCustomStringGrid.AutoAdjustColumns (patrz poniżej), spowoduje to ustawienie bardzo szerokich kolumn, chyba że masz włączoną właściwość dgAutoSizeColumns.
201+Jednak w przeciwieństwie do TCustomStringGrid.AutoAdjustColumns (patrz poniżej), spowoduje to ustawienie bardzo szerokich kolumn, chyba że masz włączoną właściwość dgAutoSizeColumns.
299202
300203#### Procedura InplaceEditor
301204
302-Zobacz przykład z błędu 23103 - _i wstaw wyjaśnienie, co robi/dlaczego jest to potrzebne. Weryfikuje wartości wejściowe? Zmienia to, co jest wyświetlane?_
303-```
205+Zobacz przykład z błędu 23103 - *i wstaw wyjaśnienie, co robi/dlaczego jest to potrzebne. Weryfikuje wartości wejściowe? Zmienia to, co jest wyświetlane?*
206+
207+``` pascal
208+
304209procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: char);
305- var
306- S: String;
210+var
211+ S: String;
212+begin
213+ if (Key in [',','.']) then
214+ begin
215+ //w przeciwieństwie do Delphi nie wszystkie edytory InPlaceEditors są edytorami typu string, więc sprawdź!
216+ if (DBGrid1.InplaceEditor is TStringCellEditor) then
307217 begin
308- if (Key in [',','.']) then
309- begin
310- //w przeciwieństwie do Delphi nie wszystkie edytory InPlaceEditors są edytorami typu string, więc sprawdź!
311- if (DBGrid1.InplaceEditor is TStringCellEditor) then
312- begin
313- S := TStringCellEditor(DBGrid1.InplaceEditor).EditText;
314- if Pos(',',S) > 0 then
315- Key := #0
316- else
317- Key := ',';
318- end;
319- end;
218+ S := TStringCellEditor(DBGrid1.InplaceEditor).EditText;
219+ if Pos(',',S) > 0 then
220+ Key := #0
221+ else
222+ Key := ',';
320223 end;
224+ end;
225+end;
321226```
322227
323228### TCustomStringGrid
324229
325-Klasa TCustomStringGrid służy jako podstawa dla klasy TStringGrid. Może być używana dla pochodnych komponentów TStringGrid, które chcą ukryć opublikowane właściwości.
230+Klasa TCustomStringGrid służy jako podstawa dla klasy TStringGrid. Może być używana dla pochodnych komponentów TStringGrid, które chcą ukryć opublikowane właściwości.
326231
327-Następujące właściwości lub metody są publiczne i są również dostępne dla TStringGrid.
232+Następujące właściwości lub metody są publiczne i są również dostępne dla TStringGrid.
328233
329-Zobacz pełną [dokumentację TCustomStringGrid](<http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tcustomstringgrid.html> "doc:lcl/grids/tcustomstringgrid.html")
234+Zobacz pełną [[doc:lcl/grids/tcustomstringgrid.html|dokumentację TCustomStringGrid]]
330235
331236#### Procedura AutoSizeColumn(aCol: Integer)
332237
333-Ta procedura dostosowuje szerokość kolumny do rozmiaru najszerszego tekstu, jaki znajduje się pośród wszystkich wierszy kolumny aCol. Wskazówka: zobacz opcję goDblClickAutoSize, która umożliwia automatyczną zmianę szerokości kolumny, gdy użyjemy podwójnego kliknięcia na obramowaniu tejże kolumny.
238+Ta procedura dostosowuje szerokość kolumny do rozmiaru najszerszego tekstu, jaki znajduje się pośród wszystkich wierszy kolumny aCol. Wskazówka: zobacz opcję goDblClickAutoSize, która umożliwia automatyczną zmianę szerokości kolumny, gdy użyjemy podwójnego kliknięcia na obramowaniu tejże kolumny.
334239
335240#### Procedura AutoAdjustColumns lub AutoSizeColumns
336241
337-Automatycznie zmienia szerokość wszystkich kolumn, dopasowując je do najdłuższego tekstu w każdej kolumnie. Jest to szybka metoda zastosowania funkcji AutoSizeColumn() dla każdej kolumny w siatce.
242+Automatycznie zmienia szerokość wszystkich kolumn, dopasowując je do najdłuższego tekstu w każdej kolumnie. Jest to szybka metoda zastosowania funkcji AutoSizeColumn() dla każdej kolumny w siatce.
338243
339244#### Procedura Clean; overload;
340245
341-Czyści wszystkie komórki siatki, także te stałe (typu fixed).
246+Czyści wszystkie komórki siatki, także te stałe (typu fixed).
342247
343248#### Procedura Clean(CleanOptions: TGridZoneSet); overload;
344249
345-Czyści wszystkie komórki w siatce wskazane w parametrze CleanOptions. Zobacz TGridZoneSet aby uzyskać więcej informacji. Poniżej kilka przykładów:
250+Czyści wszystkie komórki w siatce wskazane w parametrze CleanOptions. Zobacz TGridZoneSet aby uzyskać więcej informacji. Poniżej kilka przykładów:
346251
347- * Czyści wszystkie komórki: grid.Clean([]); (działa tak samo jak grid.clean)
348- * Czyści wszystkie normalne (nie stałe - non fixed) komórki: grid.Clean([gzNormal]);
349- * Czyści wszystkie komórki oprócz nagłówków kolumn siatki: Grid.Clean([gzNormal, gzFixedRows]);
252+- Czyści wszystkie komórki: grid.Clean(\[\]); (działa tak samo jak grid.clean)
253+- Czyści wszystkie normalne (nie stałe - non fixed) komórki: grid.Clean(\[gzNormal\]);
254+- Czyści wszystkie komórki oprócz nagłówków kolumn siatki: Grid.Clean(\[gzNormal, gzFixedRows\]);
350255
351256#### Procedura Clean(StartCol,StartRow,EndCol,EndRow: integer; CleanOptions:TGridZoneSet); overload;
352257
353-Wykonuje to samo co Clean(CleanOptions:TGridZoneSet), ale jej działanie ograniczone jest obszarem określonym parametrami StartCol, StartRow, EndCol i EndRow. Przykład:
258+Wykonuje to samo co Clean(CleanOptions:TGridZoneSet), ale jej działanie ograniczone jest obszarem określonym parametrami StartCol, StartRow, EndCol i EndRow. Przykład:
354259
355- * Czyści kolumny o ideksach od 4 do 6, ale bez nagłówków kolumn: można to zrobić na wiele sposobów, Grid.Clean(4,Grid.FixedRows,6,Grid.RowCount-1,[]); Grid.Clean(4,0,6,Grid,RowCount-1, [gzNormal]); itp.
260+- Czyści kolumny o ideksach od 4 do 6, ale bez nagłówków kolumn: można to zrobić na wiele sposobów, Grid.Clean(4,Grid.FixedRows,6,Grid.RowCount-1,\[\]); Grid.Clean(4,0,6,Grid,RowCount-1, \[gzNormal\]); itp.
356261
357262#### Procedura Clean(aRect: TRect; CleanOptions: TGridZoneSet); overload;
358263
359-Wykonuje to samo co Clean(StartCol,StartRow,EndCol,EndRow, CleanOptions), ale przy pomocy TRect zamiast wskazywania pojedynczych współrzędnych komórek. Przydatne do czyszczenia zaznaczonego obszaru: grid.Clean(Grid.Selection,[]);
264+Wykonuje to samo co Clean(StartCol,StartRow,EndCol,EndRow, CleanOptions), ale przy pomocy TRect zamiast wskazywania pojedynczych współrzędnych komórek. Przydatne do czyszczenia zaznaczonego obszaru: grid.Clean(Grid.Selection,\[\]);
360265
361-#### Procedura SaveToCSVFile(AFileName: string; ADelimiter:Char=','; WithHeader:boolean=true);
266+==== Procedura SaveToCSVFile(AFileName: string; ADelimiter:Char=','; WithHeader:boolean=true); ====
362267
363-Zapisuje zawartość siatki w pliku w formacie tekstowym, gdzie wartości są rozdzielone przecinkami (CSV) (dodanym w Lazarus r32179).
268+Zapisuje zawartość siatki w pliku w formacie tekstowym, gdzie wartości są rozdzielone przecinkami (CSV) (dodanym w Lazarus r32179).
364269
365-Argument AFilename określa nazwę pliku, w którym zostanie zapisana zawartość. Jeśli plik istnieje, zawartość zostanie nadpisana. Jeśli nie istnieje, plik zostanie utworzony.
270+Argument AFilename określa nazwę pliku, w którym zostanie zapisana zawartość. Jeśli plik istnieje, zawartość zostanie nadpisana. Jeśli nie istnieje, plik zostanie utworzony.
366271
367-ADelimiter (argument opcjonalny) jest używany do dostarczenia niestandardowego separatora, jeśli jest to wymagane. Domyślnie tworzony jest format CSV (tzn. ADelimiter:=',';) dla pliku rozdzielanego tabulatorami ADelimiter powinien mieć wartość #9.
272+ADelimiter (argument opcjonalny) jest używany do dostarczenia niestandardowego separatora, jeśli jest to wymagane. Domyślnie tworzony jest format CSV (tzn. ADelimiter:=',';) dla pliku rozdzielanego tabulatorami ADelimiter powinien mieć wartość \#9.
368273
369-Parametr WithHeader służy do określenia, czy „nagłówek wiersza” powinien zostać uwzględniony, czy nie. Nagłówek wiersza to lista nazw pól na początku pliku wyjściowego; jego zawartość pochodzi z ostatniego stałego (Fixed) wiersza w siatce. Istnieje wyjątek od tej reguły: jeśli siatka zawiera niestandardowe kolumny, zawartość nagłówka wiersza pochodzi z niestandardowych tytułów kolumn, a nie ze stałych komórek wiersza.
274+Parametr WithHeader służy do określenia, czy „nagłówek wiersza” powinien zostać uwzględniony, czy nie. Nagłówek wiersza to lista nazw pól na początku pliku wyjściowego; jego zawartość pochodzi z ostatniego stałego (Fixed) wiersza w siatce. Istnieje wyjątek od tej reguły: jeśli siatka zawiera niestandardowe kolumny, zawartość nagłówka wiersza pochodzi z niestandardowych tytułów kolumn, a nie ze stałych komórek wiersza.
370275
371-Jeśli WithHeader ma wartość True, a siatka nie zawiera stałego wiersza ani niestandardowych kolumn, zawartość nagłówka wiersza zostanie pobrana z pierwszego wiersza w siatce.
276+Jeśli WithHeader ma wartość True, a siatka nie zawiera stałego wiersza ani niestandardowych kolumn, zawartość nagłówka wiersza zostanie pobrana z pierwszego wiersza w siatce.
372277
373-Normalne wyjście danych CSV rozpocznie się od pierwszego niestałego (Non-Fixed) wiersza w siatce.
278+Normalne wyjście danych CSV rozpocznie się od pierwszego niestałego (Non-Fixed) wiersza w siatce.
374279
375-#### Procedura LoadFromCSVFile(AFileName: string; ADelimiter:Char=','; WithHeader:boolean=true);
280+==== Procedura LoadFromCSVFile(AFileName: string; ADelimiter:Char=','; WithHeader:boolean=true); ====
376281
377-Wczytuje zawartość siatki z pliku w formacie CSV (dodanym w Lazarus r32179).
282+Wczytuje zawartość siatki z pliku w formacie CSV (dodanym w Lazarus r32179).
378283
379-Kolumny będą dodawane lub usuwane do lub z siatki w zależności od potrzeb, zgodnie z liczbą pól zawartych w każdym wierszu pliku CSV. Wczytanie pliku CSV nie zmieni liczby stałych (Fixed) wierszy, które już istniały w siatce.
284+Kolumny będą dodawane lub usuwane do lub z siatki w zależności od potrzeb, zgodnie z liczbą pól zawartych w każdym wierszu pliku CSV. Wczytanie pliku CSV nie zmieni liczby stałych (Fixed) wierszy, które już istniały w siatce.
380285
381-Argument _AFileName_ określa nazwę pliku źródłowego z zawartością CSV.
286+Argument *AFileName* określa nazwę pliku źródłowego z zawartością CSV.
382287
383-Opcjonalny parametr _ADelimiter_ może być użyty do określenia innego separatora lub ogranicznika. Przykład: dla pliku rozdzielanego tabulatorami, _ADelimiter_ powinno mieć wartość #9. Innym popularnym formatem pliku jest plik rozdzielany średnikami, gdzie _ADelimiter_ powinien być ;
288+Opcjonalny parametr *ADelimiter* może być użyty do określenia innego separatora lub ogranicznika. Przykład: dla pliku rozdzielanego tabulatorami, *ADelimiter* powinno mieć wartość \#9. Innym popularnym formatem pliku jest plik rozdzielany średnikami, gdzie *ADelimiter* powinien być ;
384289
385-Parametr _WithHeader_ służy do określenia, czy pierwszy wiersz w pliku CSV powinien być traktowany jako „wiersz nagłówka”, czy nie. Jeśli siatka ma ustalone wiersze i _WithHeader_ ma wartość True, nagłówki kolumn dla ostatniego stałego (Fixed) wiersza zostaną pobrane z wiersza nagłówka. Należy jednak pamiętać, że jeśli siatka zawiera niestandardowe kolumny, wówczas wiersz nagłówka będzie używany jako źródło dla tytułów kolumn, a niestandardowe tytuły kolumn są zawsze wyświetlane w pierwszym stałym wierszu siatki lub ukryte, jeśli w siatce nie ma ustalonych wierszy.
290+Parametr *WithHeader* służy do określenia, czy pierwszy wiersz w pliku CSV powinien być traktowany jako „wiersz nagłówka”, czy nie. Jeśli siatka ma ustalone wiersze i *WithHeader* ma wartość True, nagłówki kolumn dla ostatniego stałego (Fixed) wiersza zostaną pobrane z wiersza nagłówka. Należy jednak pamiętać, że jeśli siatka zawiera niestandardowe kolumny, wówczas wiersz nagłówka będzie używany jako źródło dla tytułów kolumn, a niestandardowe tytuły kolumn są zawsze wyświetlane w pierwszym stałym wierszu siatki lub ukryte, jeśli w siatce nie ma ustalonych wierszy.
386291
387-Jeśli procedura _LoadFromCSVFile_ ma trudności z załadowaniem pliku CSV (np. cudzysłowy lub spacje są nieprawidłowo interpretowane), możesz ręcznie załadować siatkę za pomocą np. [[CsvDocument]]... i oczywiście zawsze mile widziana jest łatka dla _LoadFromCSVFile_.
292+Jeśli procedura *LoadFromCSVFile* ma trudności z załadowaniem pliku CSV (np. cudzysłowy lub spacje są nieprawidłowo interpretowane), możesz ręcznie załadować siatkę za pomocą np. [[CsvDocument]]... i oczywiście zawsze mile widziana jest łatka dla *LoadFromCSVFile*.
388293
389-#### Właściwość Cols[index: Integer]: TStrings read GetCols write SetCols;
294+#### Właściwość Cols\[index: Integer\]: TStrings read GetCols write SetCols;
390295
391-Pobierz/wstaw listę ciągów string z/do kolumny siatki o wskazanym indeksie, począwszy od wiersza o indeksie 0 do wiersza o indeksie RowCount-1.
296+Pobierz/wstaw listę ciągów string z/do kolumny siatki o wskazanym indeksie, począwszy od wiersza o indeksie 0 do wiersza o indeksie RowCount-1.
392297
393298##### Przykłady
394299
395- * Przykład wstawiania: Wstawia treść do trzeciej kolumny siatki z kontrolki ListBox:
300+- Przykład wstawiania: Wstawia treść do trzeciej kolumny siatki z kontrolki ListBox:
396301
397-```
302+``` pascal
398303Grid.Cols[2] := ListBox1.Items;
399304```
400305
401- * Przykład pobrania: Wstawia treść kontrolki ListBox z kolumny siatki o indeksie 4:
306+- Przykład pobrania: Wstawia treść kontrolki ListBox z kolumny siatki o indeksie 4:
402307
403-```
308+``` pascal
404309procedure TForm1.FillListBox1;
405- var
406- StrTempList: TStringList;
407- begin
408- StrTempList := TStringList(Grid.Cols[4]);
409- if StrTempList<>nil then begin
410- ListBox1.Items.Assign(StrTempList);
411- StrTempList.Free;
412- end;
413- end;
310+var
311+ StrTempList: TStringList;
312+begin
313+ StrTempList := TStringList(Grid.Cols[4]);
314+ if StrTempList<>nil then begin
315+ ListBox1.Items.Assign(StrTempList);
316+ StrTempList.Free;
317+ end;
318+end;
414319```
415320
416321##### Uwagi
417322
418-Ta właściwość działa inaczej w Lazarusie i w Delphi, gdy pobieramy dane z siatki. W Lazarusie tworzony jest tymczasowy obiekt typu TStringList w celu pobrania zawartości kolumny. Użytkownik jest odpowiedzialny za zwolnienie tego obiektu po użyciu.
323+Ta właściwość działa inaczej w Lazarusie i w Delphi, gdy pobieramy dane z siatki. W Lazarusie tworzony jest tymczasowy obiekt typu TStringList w celu pobrania zawartości kolumny. Użytkownik jest odpowiedzialny za zwolnienie tego obiektu po użyciu.
419324
420-Oznacza to także, że zmiany wykonywane w tej zwróconej liście ciągów string nie będą miały żadnego wpływu na zawartość siatki lub układu.
325+Oznacza to także, że zmiany wykonywane w tej zwróconej liście ciągów string nie będą miały żadnego wpływu na zawartość siatki lub układu.
421326
422-Zobacz powyższy przykład pobrania.
327+Zobacz powyższy przykład pobrania.
423328
424-#### Właściwość Rows[index: Integer]: TStrings read GetRows write SetRows;
329+#### Właściwość Rows\[index: Integer\]: TStrings read GetRows write SetRows;
425330
426-Pobierz/ustaw listę ciągów string z/do wiersza siatki o danym indeksie, począwszy od indeksu kolumny 0 do kolumny ColCount-1.
331+Pobierz/ustaw listę ciągów string z/do wiersza siatki o danym indeksie, począwszy od indeksu kolumny 0 do kolumny ColCount-1.
427332
428333##### Uwagi
429334
430-Ta właściwość działa inaczej w Lazarusie i Delphi podczas pobierania danych z siatki. W Lazarusie tworzony jest tymczasowy obiekt typu TStringList do pobierania zawartości wiersza. Obowiązkiem użytkownika jest zwolnienie tego obiektu po użyciu.
335+Ta właściwość działa inaczej w Lazarusie i Delphi podczas pobierania danych z siatki. W Lazarusie tworzony jest tymczasowy obiekt typu TStringList do pobierania zawartości wiersza. Obowiązkiem użytkownika jest zwolnienie tego obiektu po użyciu.
431336
432-Oznacza to również, że jakiekolwiek zmiany w tej zwróconej liście ciągów string nie wpłyną na zawartość ani układu, ani siatki.
337+Oznacza to również, że jakiekolwiek zmiany w tej zwróconej liście ciągów string nie wpłyną na zawartość ani układu, ani siatki.
433338
434339##### Przykłady
435340
436- * Przykład ustawiania: Ustaw zawartość trzeciego wiersza siatki jako zawartość ListBox:
341+- Przykład ustawiania: Ustaw zawartość trzeciego wiersza siatki jako zawartość ListBox:
437342
438-```
343+``` Pascal
439344Grid.Rows[2] := ListBox1.Items;
440345```
441346
442- * Przykład pobrania: Ustaw zawartość pola listy z 4 indeksu wiersza siatki:
347+- Przykład pobrania: Ustaw zawartość pola listy z 4 indeksu wiersza siatki:
443348
444-```
349+``` pascal
445350procedure TForm1.FillListBox1;
446- var
447- StrTempList: TStringList;
448- begin
449- StrTempList := TStringList(Grid.Rows[4]);
450- if StrTempList<>nil then begin
451- ListBox1.Items.Assign(StrTempList);
452- StrTempList.Free;
453- end;
454- end;
351+var
352+ StrTempList: TStringList;
353+begin
354+ StrTempList := TStringList(Grid.Rows[4]);
355+ if StrTempList<>nil then begin
356+ ListBox1.Items.Assign(StrTempList);
357+ StrTempList.Free;
358+ end;
359+end;
455360```
456361
457- * Przykład, który nie działa, oraz jego poprawka: Pobrana lista ciągów jest tylko do odczytu
362+- Przykład, który nie działa, oraz jego poprawka: Pobrana lista ciągów jest tylko do odczytu
458363
459-```
460-// te dwa przykłady nie zadziałają i spowodują wycieki pamięci,
461- // ponieważ zwrócone listy ciągów nie są zwalniane
462- Grid.Rows[1].CommaText := '1,2,3,4,5';
463- Grid.Rows[2].Text := 'a'+#13#10+'s'+#13#10+'d'+#13#10+'f'+#13#10+'g';
464-
465- // naprawienie pierwszego przypadku
466- Lst:=TStringList.Create;
467- Lst.CommaText := '1,2,3,4,5';
468- Grid.Rows[1] := Lst;
469- Lst.Free;
364+``` pascal
365+ // te dwa przykłady nie zadziałają i spowodują wycieki pamięci,
366+ // ponieważ zwrócone listy ciągów nie są zwalniane
367+ Grid.Rows[1].CommaText := '1,2,3,4,5';
368+ Grid.Rows[2].Text := 'a'+#13#10+'s'+#13#10+'d'+#13#10+'f'+#13#10+'g';
369+
370+ // naprawienie pierwszego przypadku
371+ Lst:=TStringList.Create;
372+ Lst.CommaText := '1,2,3,4,5';
373+ Grid.Rows[1] := Lst;
374+ Lst.Free;
470375```
471376
472377#### Właściwość UseXORFeatures
473378
474-Właściwość typu Boolean, wartość domyślna: False;
379+Właściwość typu Boolean, wartość domyślna: False;
475380
476-Ta właściwość kontroluje wygląd kropkowanego prostokąta fokusu w siatce (pokazuje się, gdy klikniemy myszką na jakiejś komórce). Gdy ma wartość True, prostokąt jest malowany przy użyciu operacji rastrowej XOR. Dzięki temu możemy zobaczyć prostokąt fokusu bez względu na kolor tła komórek. Gdy ma wartość False, użytkownik może kontrolować kolor kropkowanego prostokąta fokusu za pomocą [właściwości FocusColor](</index.php?title=FocusColor_property&action=edit&redlink=1> "FocusColor property \(page does not exist\)")
381+Ta właściwość kontroluje wygląd kropkowanego prostokąta fokusu w siatce (pokazuje się, gdy klikniemy myszką na jakiejś komórce). Gdy ma wartość True, prostokąt jest malowany przy użyciu operacji rastrowej XOR. Dzięki temu możemy zobaczyć prostokąt fokusu bez względu na kolor tła komórek. Gdy ma wartość False, użytkownik może kontrolować kolor kropkowanego prostokąta fokusu za pomocą [[FocusColor property|właściwości FocusColor]]
477382
478-Kontroluje również wygląd zmiany rozmiaru kolumny/wiersza. Gdy ma wartość True, linia pokazuje wizualnie rozmiar kolumny lub wiersza, jeśli użytkownik zakończy operację. Gdy ma wartość False, zmiana rozmiaru kolumny lub wiersza zaczyna obowiązywać, gdy użytkownik przeciąga myszą.
383+Kontroluje również wygląd zmiany rozmiaru kolumny/wiersza. Gdy ma wartość True, linia pokazuje wizualnie rozmiar kolumny lub wiersza, jeśli użytkownik zakończy operację. Gdy ma wartość False, zmiana rozmiaru kolumny lub wiersza zaczyna obowiązywać, gdy użytkownik przeciąga myszą.
479384
480385### TValueListEditor
481386
482-[[TValueListEditor]] to kontrolka (formant) pochodzący z TCustomStringGrid i służy do edycji par typu klucz-wartość.
387+[[TValueListEditor]] to kontrolka (formant) pochodzący z TCustomStringGrid i służy do edycji par typu klucz-wartość.
483388
484389#### Właściwość DisplayOptions
485390
486-Kontroluje różne aspekty wyglądu TValueListEditor.
391+Kontroluje różne aspekty wyglądu TValueListEditor.
487392
488393#### Właściwość TitleCaptions
489394
490-Ustawia wartości dla tytułów kolumn (jeśli właściwość DisplayOptions zawiera wartość doColumnTitles). Jeśli DisplayOptions nie ma wartości doColumnTitles, używane są domyślne tytuły.
395+Ustawia wartości dla tytułów kolumn (jeśli właściwość DisplayOptions zawiera wartość doColumnTitles). Jeśli DisplayOptions nie ma wartości doColumnTitles, używane są domyślne tytuły.
491396
492397#### Właściwość Strings
493398
494-Zapewnia dostęp do listy ciągów zawierających pary klucz-wartość.
495-Pary klucz-wartość muszą mieć format typu:
496-'NazwaKlucza=Wartość'
399+Zapewnia dostęp do listy ciągów zawierających pary klucz-wartość.\
400+Pary klucz-wartość muszą mieć format typu:\
401+'NazwaKlucza=Wartość'
497402
498403#### Właściwość ItemProps
499404
500-Możesz użyć tej właściwości, aby kontrolować sposób edytowania elementów w kolumnach „Value” (Wartość).
501-Jest to kontrolowane przez ustawienie właściwości EditStyle i ReadOnly elementu ItemProp.
405+Możesz użyć tej właściwości, aby kontrolować sposób edytowania elementów w kolumnach „Value” (Wartość).\
406+Jest to kontrolowane przez ustawienie właściwości EditStyle i ReadOnly elementu ItemProp.
502407
503408#### Właściwość KeyOptions
504409
505-KeyOptions to zbiór wartości porządkowych TKeyOptions kontrolujących, czy użytkownik może modyfikować zawartość kolumny „Key” (Klucz).
410+KeyOptions to zbiór wartości porządkowych TKeyOptions kontrolujących, czy użytkownik może modyfikować zawartość kolumny „Key” (Klucz).
506411
507- * KeyEdit: użytkownik może edytować nazwę klucza
508- * KeyAdd: użytkownik może dodawać klucze (przez wciśnięcie klawisza Insert w siatce). KeyAdd wymaga KeyEdit.
509- * KeyDelete: użytkownik może usuwać pary klucz-wartość (przez naciśnięcie kombinacji Ctrl+Delete).
510- * KeyUnique: jeśli ustawione, klucze muszą mieć unikalne nazwy. Próba wprowadzenia zduplikowanego klucza spowoduje zgłoszenie wyjątku.
412+- KeyEdit: użytkownik może edytować nazwę klucza
413+- KeyAdd: użytkownik może dodawać klucze (przez wciśnięcie klawisza Insert w siatce). KeyAdd wymaga KeyEdit.
414+- KeyDelete: użytkownik może usuwać pary klucz-wartość (przez naciśnięcie kombinacji Ctrl+Delete).
415+- KeyUnique: jeśli ustawione, klucze muszą mieć unikalne nazwy. Próba wprowadzenia zduplikowanego klucza spowoduje zgłoszenie wyjątku.
511416
512417#### Właściwość DropDownRows
513418
514-Jeśli edytor komórek jest listą wyboru (ValueEdit1.ItemProps['key1'].EditStyle=esPickList), to ta właściwość ustawia DropDownCount, czyli ilość wierszy wyświetlanej listy. Wartość domyślna to 8.
419+Jeśli edytor komórek jest listą wyboru (ValueEdit1.ItemProps\['key1'\].EditStyle=esPickList), to ta właściwość ustawia DropDownCount, czyli ilość wierszy wyświetlanej listy. Wartość domyślna to 8.
515420
516421#### Funkcja DeleteRow
517422
518-Usuwa parę Klucz-Wartość wiersza o podanym indeksie, całkowicie usuwając wiersz.
423+Usuwa parę Klucz-Wartość wiersza o podanym indeksie, całkowicie usuwając wiersz.
519424
520425#### Funkcja InsertRow
521426
522-Wstawia wiersz w siatce i ustawia parę Klucz-Wartość. Zwraca indeks nowo wstawionego wiersza.
427+Wstawia wiersz w siatce i ustawia parę Klucz-Wartość. Zwraca indeks nowo wstawionego wiersza.
523428
524429#### Funkcja IsEmptyRow
525430
526-Zwraca wartość True, jeśli komórki indeksowanego wiersza są puste (Keys[aRow]=_; Values[aRow]=_).
431+Zwraca wartość True, jeśli komórki indeksowanego wiersza są puste (Keys\[aRow\]=*; Values\[aRow\]=*).
527432
528433#### Funkcja FindRow
529434
530-Zwraca indeks wiersza, który ma określoną nazwę klucza.
435+Zwraca indeks wiersza, który ma określoną nazwę klucza.
531436
532437#### Funkcja RestoreCurrentRow
533438
534-Cofa edycję w bieżącym wierszu (jeśli edytor jest nadal aktywny). Dzieje się tak, gdy użytkownik naciśnie klawisz Escape.
439+Cofa edycję w bieżącym wierszu (jeśli edytor jest nadal aktywny). Dzieje się tak, gdy użytkownik naciśnie klawisz Escape.
535440
536441#### Zmienione zachowanie niektórych właściwości pochodzących z TCustomStringGrid
537442
538443##### Właściwość Options
539444
540-Ze względu na charakter TValueListEditor jego właściwość Options ma pewne ograniczenia
445+Ze względu na charakter TValueListEditor jego właściwość Options ma pewne ograniczenia
541446
542- * goColMoving nie jest dozwolony w opcjach (nie można go ustawić).
543- * goAutoAddRows można ustawić tylko wtedy, gdy KeyAdd jest włączony w KeyOptions. Ustawienie KeyAdd automatycznie ustawi goAutoAddRows.
544- * goAutoAddRowsSkipContentCheck jest niedozwolone (na razie powoduje awarię w TValueListeditor: wymaga naprawy).
447+- goColMoving nie jest dozwolony w opcjach (nie można go ustawić).
448+- goAutoAddRows można ustawić tylko wtedy, gdy KeyAdd jest włączony w KeyOptions. Ustawienie KeyAdd automatycznie ustawi goAutoAddRows.
449+- goAutoAddRowsSkipContentCheck jest niedozwolone (na razie powoduje awarię w TValueListeditor: wymaga naprawy).
545450
546451##### Właściwość FixedRows
547452
548-Może mieć wyłącznie wartość równą 1 (pokaż tytuły kolumn) lub 0 (nie pokazuj tytułów kolumn).
453+Może mieć wyłącznie wartość równą 1 (pokaż tytuły kolumn) lub 0 (nie pokazuj tytułów kolumn).
549454
550455##### Właściwość ColCount
551456
552-Może mieć wyłącznie wartość równą 2.
457+Może mieć wyłącznie wartość równą 2.
553458
554459##### Właściwość Objects
555460
556-Uwaga! Nie zaleca się używania tej właściwości w ogóle.
557-Kiedy jakiś (wewnętrzny) kod manipuluje właściwością Strings, zmiany dla Objects zostaną utracone.
461+Uwaga! Nie zaleca się używania tej właściwości w ogóle.\
462+Kiedy jakiś (wewnętrzny) kod manipuluje właściwością Strings, zmiany dla Objects zostaną utracone.
558463
559464#### Ogólne uwagi dotyczące korzystania z TValueListEditor
560465
561-Podczas manipulowania zawartością ValueListEditor (siatki) można bezpośrednio manipulować podstawową właściwością Strings.
562-Pamiętaj jednak, że jeśli to zrobisz, **musisz** ukryć edytor, w przeciwnym razie ciągi mogą nie być zsynchronizowane z zawartością siatki, którą widzisz na ekranie.
563-
564-Jeśli chcesz wstawić lub usunąć wiersze itp., preferowanym sposobem jest użycie metod publicznych z TValueListEditor: DeleteRow(), InsertRow(), MoveRow(), ExchangeRow() lub różnych metod Sort().
565-
566-Próba użycia metod z klasy przodka do manipulowania wierszami lub kolumnami (np. Columns.Add) może spowodować awarię.
466+Podczas manipulowania zawartością ValueListEditor (siatki) można bezpośrednio manipulować podstawową właściwością Strings.\
467+Pamiętaj jednak, że jeśli to zrobisz, musisz ukryć edytor, w przeciwnym razie ciągi mogą nie być zsynchronizowane z zawartością siatki, którą widzisz na ekranie.\
567468
469+Jeśli chcesz wstawić lub usunąć wiersze itp., preferowanym sposobem jest użycie metod publicznych z TValueListEditor: DeleteRow(), InsertRow(), MoveRow(), ExchangeRow() lub różnych metod Sort().\
470+
471+Próba użycia metod z klasy przodka do manipulowania wierszami lub kolumnami (np. Columns.Add) może spowodować awarię.
472+
568473#### Zapisywanie i ładowanie zawartości TValueListEditor
569474
570475##### Korzystanie z właściwości Strings
571476
572-Jeśli chcesz tylko zapisać i załadować zawartość TValueListEditor (np. par Klucz/Wartość, a nie układ), możesz użyć metod Strings.SaveToFile i Strings.LoadFromFile.
573-W przypadku LoadFromFile właściwość `RowCount` zostanie automatycznie dostosowana.
574-Również w przypadku LoadFromFile nie są wykonywane żadne kontrole poprawności (więc wiersze, które nie reprezentują pary Klucz/Wartość, zostaną zakończone jako klucze bez wartości).
477+Jeśli chcesz tylko zapisać i załadować zawartość TValueListEditor (np. par Klucz/Wartość, a nie układ), możesz użyć metod Strings.SaveToFile i Strings.LoadFromFile.\
478+W przypadku LoadFromFile właściwość `RowCount` zostanie automatycznie dostosowana.\
479+Również w przypadku LoadFromFile nie są wykonywane żadne kontrole poprawności (więc wiersze, które nie reprezentują pary Klucz/Wartość, zostaną zakończone jako klucze bez wartości).
575480
576481##### Korzystanie z TValueList.SaveToFile i TValueList.LoadFromFile
577482
578-When using SaveToFile and LoadFromFile you get the additional benefits of also being able to save and load the layout, like with other grids.
579-SaveToFiel will also save information about wether or not the TValueListEditor uses ColumnTitles, and if so, it saves them.
580-
581-In contrast to it's ancestors TValueList.LoadFromFile performs sanity checks on the file it tries to read. In particular RowCount must be specified and there cannot be a cell with RowIndex > RowCount or ColumnIndex other than 0 or 1.
582-If the file does not seem to be a valid TValueListEditor grid file, and exception is raised.
583-
584-TValueList.SaveToFile and TValueList.LoadFromFile do not work correctly in Lazarus versions <= 2.1 r62044.
483+When using SaveToFile and LoadFromFile you get the additional benefits of also being able to save and load the layout, like with other grids.\
484+SaveToFiel will also save information about wether or not the TValueListEditor uses ColumnTitles, and if so, it saves them.\
585485
586-Korzystając z funkcji SaveToFile i LoadFromFile z TValueList, zyskujesz dodatkowe korzyści związane z możliwością zapisywania i ładowania układu, podobnie jak w przypadku innych siatek.
587-SaveToFile zapisze również informacje o tym, czy TValueListEditor używa ColumnTitles, a jeśli tak, zapisuje je.
588-
589-W przeciwieństwie do swoich przodków, TValueList.LoadFromFile sprawdza poprawność pliku, który próbuje odczytać. W szczególności właściwość RowCount musi być określona i nie może istnieć komórka z RowIndex > RowCount lub ColumnIndex innym niż 0 lub 1.
590-Jeśli plik nie wydaje się być prawidłowym plikiem siatki TValueListEditor, zgłaszany jest wyjątek.
591-
592-TValueList.SaveToFile i TValueList.LoadFromFile nie działają poprawnie w wersjach Lazarusa <= 2.1 r62044.
486+In contrast to it's ancestors TValueList.LoadFromFile performs sanity checks on the file it tries to read. In particular RowCount must be specified and there cannot be a cell with RowIndex \> RowCount or ColumnIndex other than 0 or 1.\
487+If the file does not seem to be a valid TValueListEditor grid file, and exception is raised.\
593488
489+TValueList.SaveToFile and TValueList.LoadFromFile do not work correctly in Lazarus versions \<= 2.1 r62044.
490+
491+Korzystając z funkcji SaveToFile i LoadFromFile z TValueList, zyskujesz dodatkowe korzyści związane z możliwością zapisywania i ładowania układu, podobnie jak w przypadku innych siatek.\
492+SaveToFile zapisze również informacje o tym, czy TValueListEditor używa ColumnTitles, a jeśli tak, zapisuje je.\
493+
494+W przeciwieństwie do swoich przodków, TValueList.LoadFromFile sprawdza poprawność pliku, który próbuje odczytać. W szczególności właściwość RowCount musi być określona i nie może istnieć komórka z RowIndex \> RowCount lub ColumnIndex innym niż 0 lub 1.\
495+Jeśli plik nie wydaje się być prawidłowym plikiem siatki TValueListEditor, zgłaszany jest wyjątek.\
496+
497+TValueList.SaveToFile i TValueList.LoadFromFile nie działają poprawnie w wersjach Lazarusa \<= 2.1 r62044.
498+
594499##### Korzystanie z metod SaveToCSVFile i LoadFromCSV
595500
596-Te metody **nie** powinny być obecnie używane, ponieważ w przypadku TValueListEditor są one wadliwe.
501+Te metody nie powinny być obecnie używane, ponieważ w przypadku TValueListEditor są one wadliwe.
597502
598503## Praca z siatkami
599504
600505### Dostosowywanie siatek
601506
602-Komponenty Grid pochodzą z klasy [TCustomControl](<http://lazarus-ccr.sourceforge.net/docs/lcl/controls/tcustomcontrol.html>) i nie mają skojarzonego z nią natywnego widżetu, co oznacza, że ​​siatki nie są ograniczone przez wygląd aktualnego motywu interfejsu. Może to być zarówno zaletą, jak i wadą: zwykle programiści chcą stworzyć aplikację o jednolitym wyglądzie. Dobrą wiadomością jest to, że siatki Lazarusa są wystarczająco elastyczne, aby uzyskać coś z obu światów; programiści mogą łatwo sprawić, by siatki wyglądały podobnie do innych natywnych kontrolek, lub mogą dostosować siatkę w najdrobniejszych szczegółach, aby uzyskać prawie taki sam wygląd na dowolnej platformie lub interfejsie widżetów (tzn. z wyjątkiem pasków przewijania, ponieważ ich wygląd jest wciąż zdeterminowany aktualnym motywem).
507+Komponenty Grid pochodzą z klasy [TCustomControl](http://lazarus-ccr.sourceforge.net/docs/lcl/controls/tcustomcontrol.html) i nie mają skojarzonego z nią natywnego widżetu, co oznacza, że ​​siatki nie są ograniczone przez wygląd aktualnego motywu interfejsu. Może to być zarówno zaletą, jak i wadą: zwykle programiści chcą stworzyć aplikację o jednolitym wyglądzie. Dobrą wiadomością jest to, że siatki Lazarusa są wystarczająco elastyczne, aby uzyskać coś z obu światów; programiści mogą łatwo sprawić, by siatki wyglądały podobnie do innych natywnych kontrolek, lub mogą dostosować siatkę w najdrobniejszych szczegółach, aby uzyskać prawie taki sam wygląd na dowolnej platformie lub interfejsie widżetów (tzn. z wyjątkiem pasków przewijania, ponieważ ich wygląd jest wciąż zdeterminowany aktualnym motywem).
603508
604509### Właściwości i Zdarzenia dostosowujące siatek
605510
606-Niektóre właściwości mogą wpływać na wygląd siatki, działając, gdy komórka ma zostać pomalowana w zdarzeniu PrepareCanvas/OnPrepareCanvas, zmieniając domyślne właściwości płótna (canvas), takie jak kolor pędzla lub czcionka. Poniżej znajduje się lista takich właściwości:
607-
608- * **AlternateColor.** Dzięki tej właściwości użytkownik może zmienić kolor tła pojawiający się w naprzemiennych wierszach. Ma to na celu umożliwienie łatwiejszego odczytania danych z wierszy siatki przez użytkownika.
609- * **Color.** Ta właściwość ustawia podstawowy kolor używany do rysowania tła niestałych (Non-Fixed) komórek.
610- * **FixedColor.** Jest to kolor używany do rysowania tła dla stałych komórek (Fixed).
611- * **Flat.** Ta właściwość wyłącza trójwymiarowy wygląd stałych komórek.
612-
613- * **TitleFont.** Czcionka używana do rysowania tekstu w stałych komórkach.
614-
615- * **TitleStyle.** Ta właściwość zmienia wygląd 3D stałych komórek, istnieją 3 ustawienia:
616- * _tsLazarus._ To jest domyślny wygląd preferowany przez Lazarusa
617- * _tsNative._ Ta wartość próbuje ustawić wygląd zgodny z bieżącym motywem zestawu widżetów.
618- * _tsStandard._ Ten styl jest bardziej kontrastowy, podobnie jak siatki Delphi.
619- * **AltColorStartNormal.** Wartość logiczna. Jeśli jest True: alternatywny kolor jest zawsze w drugim rzędzie po stałych wierszach, pierwszy wiersz po stałych wierszach będzie zawsze w domyślnym kolorze. Jeśli jest False: domyślny kolor jest ustawiany na pierwszym wierszu, tak jakby nie było żadnych stałych wierszy.
620- * **BorderColor.** Ustawia kolor obramowania siatki używany, gdy Flat:=True i BorderStyle:=bsSingle.
621- * **EditorBorderStyle.** Jeśli ustawione na bsNone w systemie Windows, to edytory komórek nie będą miały obramowania, tak jak w Delphi. Ustaw domyślnie na bsSingle, ponieważ obramowanie może być specyficzne dla motywu w niektórych zestawach widżetów i umożliwiać jednolity wygląd.
511+Niektóre właściwości mogą wpływać na wygląd siatki, działając, gdy komórka ma zostać pomalowana w zdarzeniu PrepareCanvas/OnPrepareCanvas, zmieniając domyślne właściwości płótna (canvas), takie jak kolor pędzla lub czcionka. Poniżej znajduje się lista takich właściwości:
622512
623- * **FocusColor.** Kolor używany do rysowania komórki, na której aktualnie ustawione jest skupienie (fokus), jeśli UseXORFeatures nie jest ustawiony, domyślnie jest to clRed.
624- * **FocusRectVisible.** Włącza/wyłącza rysowanie skupionej komórki.
625- * **GridLineColor.** Kolor linii siatki w obszarze niestałych komórek.
626- * **GridLineStyle.** Styl pióra używany do rysowania linii w obszarze niestałych komórek, możliwe wybory to: _psSolid_ , _psDash_ , _psDot_ , _psDashDot_ , _psDashDotDot_ , _psinsideFrame_ , _psPattern_ , _psClear_. Domyślnie jest to _psSolid_.
627- * **SelectedColor.** Kolor używany do rysowania tła komórki na wybranych, zaznaczonych komórkach.
628- * **UseXORFeatures.** Jeśli ustawiony jest na True, to prostokąt skupienia (focus) jest rysowany w trybie XOR, więc powinien być widoczny w połączeniu z dowolnym kolorem tła komórki. Wpływa również na wygląd przesuwanych kolumn.
629- * **DefaultDrawing.** Wartość logiczna. Zwykle siatki przygotowują płótno (canvas) siatki przy użyciu pewnych właściwości zgodnie z rodzajem malowanej komórki. Jeśli użytkownik napisze własną procedurę obsługi zdarzeń OnDrawCell, ustawiony DefaultDrawing również maluje tło komórki. Jeśli użytkownik sam rysuje komórkę, lepiej wyłączyć tę właściwość, aby malowanie się nie duplikowało. W StringGrid ustawiony DefaultDrawing rysuje również tekst w każdej komórce.
630- * **AutoAdvance.** Determinuje to, gdzie ma zostać przeniesiony kursor komórki po naciśnięciu klawisza Enter lub po zakończeniu edycji.
631- * **TabAdvance.** Determinuje to, gdzie ma zostać przeniesiony kursor komórki po naciśnięciu klawisza Tab or Shift-Tab.
632- * **ExtendedColSizing.** Jeśli ma wartość True, użytkownik może zmienić rozmiar kolumn nie tylko w nagłówkach, ale wzdłuż ich wysokości.
513+- **AlternateColor.** Dzięki tej właściwości użytkownik może zmienić kolor tła pojawiający się w naprzemiennych wierszach. Ma to na celu umożliwienie łatwiejszego odczytania danych z wierszy siatki przez użytkownika.
514+- **Color.** Ta właściwość ustawia podstawowy kolor używany do rysowania tła niestałych (Non-Fixed) komórek.
515+- **FixedColor.** Jest to kolor używany do rysowania tła dla stałych komórek (Fixed).
516+- **Flat.** Ta właściwość wyłącza trójwymiarowy wygląd stałych komórek.\
517+- **TitleFont.** Czcionka używana do rysowania tekstu w stałych komórkach.\
518+- **TitleStyle.** Ta właściwość zmienia wygląd 3D stałych komórek, istnieją 3 ustawienia:
519+ - *tsLazarus.* To jest domyślny wygląd preferowany przez Lazarusa
520+ - *tsNative.* Ta wartość próbuje ustawić wygląd zgodny z bieżącym motywem zestawu widżetów.
521+ - *tsStandard.* Ten styl jest bardziej kontrastowy, podobnie jak siatki Delphi.
522+- **AltColorStartNormal.** Wartość logiczna. Jeśli jest True: alternatywny kolor jest zawsze w drugim rzędzie po stałych wierszach, pierwszy wiersz po stałych wierszach będzie zawsze w domyślnym kolorze. Jeśli jest False: domyślny kolor jest ustawiany na pierwszym wierszu, tak jakby nie było żadnych stałych wierszy.
523+- **BorderColor.** Ustawia kolor obramowania siatki używany, gdy Flat:=True i BorderStyle:=bsSingle.
524+- **EditorBorderStyle.** Jeśli ustawione na bsNone w systemie Windows, to edytory komórek nie będą miały obramowania, tak jak w Delphi. Ustaw domyślnie na bsSingle, ponieważ obramowanie może być specyficzne dla motywu w niektórych zestawach widżetów i umożliwiać jednolity wygląd.\
525+- **FocusColor.** Kolor używany do rysowania komórki, na której aktualnie ustawione jest skupienie (fokus), jeśli UseXORFeatures nie jest ustawiony, domyślnie jest to clRed.
526+- **FocusRectVisible.** Włącza/wyłącza rysowanie skupionej komórki.
527+- **GridLineColor.** Kolor linii siatki w obszarze niestałych komórek.
528+- **GridLineStyle.** Styl pióra używany do rysowania linii w obszarze niestałych komórek, możliwe wybory to: *psSolid*, *psDash*, *psDot*, *psDashDot*, *psDashDotDot*, *psinsideFrame* , *psPattern*, *psClear*. Domyślnie jest to *psSolid*.
529+- **SelectedColor.** Kolor używany do rysowania tła komórki na wybranych, zaznaczonych komórkach.
530+- **UseXORFeatures.** Jeśli ustawiony jest na True, to prostokąt skupienia (focus) jest rysowany w trybie XOR, więc powinien być widoczny w połączeniu z dowolnym kolorem tła komórki. Wpływa również na wygląd przesuwanych kolumn.
531+- **DefaultDrawing.** Wartość logiczna. Zwykle siatki przygotowują płótno (canvas) siatki przy użyciu pewnych właściwości zgodnie z rodzajem malowanej komórki. Jeśli użytkownik napisze własną procedurę obsługi zdarzeń OnDrawCell, ustawiony DefaultDrawing również maluje tło komórki. Jeśli użytkownik sam rysuje komórkę, lepiej wyłączyć tę właściwość, aby malowanie się nie duplikowało. W StringGrid ustawiony DefaultDrawing rysuje również tekst w każdej komórce.
532+- **AutoAdvance.** Determinuje to, gdzie ma zostać przeniesiony kursor komórki po naciśnięciu klawisza Enter lub po zakończeniu edycji.
533+- **TabAdvance.** Determinuje to, gdzie ma zostać przeniesiony kursor komórki po naciśnięciu klawisza Tab or Shift-Tab.
534+- **ExtendedColSizing.** Jeśli ma wartość True, użytkownik może zmienić rozmiar kolumn nie tylko w nagłówkach, ale wzdłuż ich wysokości.
633535
634-Inne właściwości, które również wpływają na wygląd siatek.
536+Inne właściwości, które również wpływają na wygląd siatek.
635537
636-**Options**.
538+**Options**.
637539
638- Właściwość Options to zestaw zawierający kilka elementów umożliwiających różnorodną funkcjonalność, ale niektóre są bezpośrednio związane z wyglądem siatki. Te opcje można ustawić w czasie projektowania lub w czasie wykonywania.
540+
541+Właściwość Options to zestaw zawierający kilka elementów umożliwiających różnorodną funkcjonalność, ale niektóre są bezpośrednio związane z wyglądem siatki. Te opcje można ustawić w czasie projektowania lub w czasie wykonywania.
639542
640- * **goFixedVertLine, goFixedHorzLine** Rysuje pionową lub poziomą linię, odpowiednio oddzielającą komórki lub kolumny w obszarze stałych komórek, domyślnie aktywne.
641- * **goVertLine, goHorzLine** Tak samo jak poprzednio, ale dla normalnego obszaru do przeglądania. Można stworzyć siatkę, która będzie symulować pole listy (ListBox), wyłączając oba te elementy.
642- * **goDrawFocusSelected** Jeśli ten element jest włączony, tło zaznaczenia jest malowane także w skupionej (fixed) komórce oprócz zaznaczonego kropkowanego prostokąta (pamiętaj, że to nie działa jeszcze, gdy ustawiona jest opcja goRowSelect, w takim przypadku wiersz jest zawsze malowany tak, jakby ustawiono goDrawFocusSelected).
643- * **goRowSelect** Wybierz do zaznaczania cały wiersz zamiast pojedynczych komórek.
644- * **goFixedRowNumbering** Jeśli ustawione, siatka wykona automatyczną numerację wierszy w pierwszej stałej kolumnie.
645- * **goHeaderHotTracking** Jeśli jest ustawione, siatka będzie próbowała pokazać inny wygląd komórki, gdy kursor myszy znajdzie się nad dowolną stałą komórką. Aby to zadziałało, żądana strefa komórki musi być włączona za pomocą właściwości HeaderHotZones. Spróbuj połączyć tę opcję z właściwością TitleStyle:=tsNative, aby uzyskać wygląd, który na bieżąco śledzi wygląd motywu widżetów.
646- * **goHeaderPushedLook** Jeśli jest ustawione, ten element włącza wygląd wciśnięcia po kliknięciu dowolnej stałej komórki. Strefa komórek, które mogą być „wciskane” jest włączana za pomocą właściwości HeaderPusedZones.
543+- **goFixedVertLine, goFixedHorzLine** Rysuje pionową lub poziomą linię, odpowiednio oddzielającą komórki lub kolumny w obszarze stałych komórek, domyślnie aktywne.
544+- **goVertLine, goHorzLine** Tak samo jak poprzednio, ale dla normalnego obszaru do przeglądania. Można stworzyć siatkę, która będzie symulować pole listy (ListBox), wyłączając oba te elementy.
545+- **goDrawFocusSelected** Jeśli ten element jest włączony, tło zaznaczenia jest malowane także w skupionej (fixed) komórce oprócz zaznaczonego kropkowanego prostokąta (pamiętaj, że to nie działa jeszcze, gdy ustawiona jest opcja goRowSelect, w takim przypadku wiersz jest zawsze malowany tak, jakby ustawiono goDrawFocusSelected).
546+- **goRowSelect** Wybierz do zaznaczania cały wiersz zamiast pojedynczych komórek.
547+- **goFixedRowNumbering** Jeśli ustawione, siatka wykona automatyczną numerację wierszy w pierwszej stałej kolumnie.
548+- **goHeaderHotTracking** Jeśli jest ustawione, siatka będzie próbowała pokazać inny wygląd komórki, gdy kursor myszy znajdzie się nad dowolną stałą komórką. Aby to zadziałało, żądana strefa komórki musi być włączona za pomocą właściwości HeaderHotZones. Spróbuj połączyć tę opcję z właściwością TitleStyle:=tsNative, aby uzyskać wygląd, który na bieżąco śledzi wygląd motywu widżetów.
549+- **goHeaderPushedLook** Jeśli jest ustawione, ten element włącza wygląd wciśnięcia po kliknięciu dowolnej stałej komórki. Strefa komórek, które mogą być „wciskane” jest włączana za pomocą właściwości HeaderPusedZones.
647550
648-(dopisz więcej)
551+(dopisz więcej)
649552
650553### Opis procesu rysowania siatki
651554
652-Podobnie jak inne niestandardowe kontrolki, siatka jest rysowana metodą malowania. Ogólnie rzecz biorąc, siatkę rysuje się malując wszystkie wiersze, a każdy wiersz malując poszczególne komórki.
555+Podobnie jak inne niestandardowe kontrolki, siatka jest rysowana metodą malowania. Ogólnie rzecz biorąc, siatkę rysuje się malując wszystkie wiersze, a każdy wiersz malując poszczególne komórki.
653556
654-Proces ten wygląda następująco:
557+Proces ten wygląda następująco:
655558
656- * Najpierw określany jest obszar widocznych komórek: każdy wiersz jest testowany, aby sprawdzić, czy krzyżuje się z granicą płótna (canvas); jeśli wszystko jest w porządku, widoczny obszar jest malowany przez rysowanie kolumn każdego wiersza.
657- * Wartości kolumn i wierszy służą do identyfikacji komórki, która ma zostać pomalowana, a każda kolumna jest ponownie testowana pod kątem krzyżowania się z granicą płótna; jeśli wszystko jest w porządku, niektóre dodatkowe właściwości, takie jak prostokątny zasięg komórki i stan wizualny, są przekazywane jako argumenty do metody DrawCell.
658- * W trakcie procesu rysowania stan wizualny każdej komórki jest dostosowywany zgodnie z opcjami siatki i położeniem w siatce. Stan wizualny zachowany jest w zmiennej typu TGridDrawState, która jest zbiorem składającym się z następujących elementów:
659- * _gdSelected_ Komórka będzie miała wygląd wybranej, zaznaczonej.
660- * _gdFocused_ Komórka będzie miała wygląd skupionej (focus).
661- * _gdFixed_ Komórka musi być pomalowana jak komórka stała.
662- * _gdHot_ Mysz jest nad tą komórką, więc pomaluj ją z bieżącym podświetleniem
663- * _gdPushed_ Komórka jest klikana, więc pomaluj ją jako wciśniętą
559+- Najpierw określany jest obszar widocznych komórek: każdy wiersz jest testowany, aby sprawdzić, czy krzyżuje się z granicą płótna (canvas); jeśli wszystko jest w porządku, widoczny obszar jest malowany przez rysowanie kolumn każdego wiersza.
560+- Wartości kolumn i wierszy służą do identyfikacji komórki, która ma zostać pomalowana, a każda kolumna jest ponownie testowana pod kątem krzyżowania się z granicą płótna; jeśli wszystko jest w porządku, niektóre dodatkowe właściwości, takie jak prostokątny zasięg komórki i stan wizualny, są przekazywane jako argumenty do metody DrawCell.
561+- W trakcie procesu rysowania stan wizualny każdej komórki jest dostosowywany zgodnie z opcjami siatki i położeniem w siatce. Stan wizualny zachowany jest w zmiennej typu TGridDrawState, która jest zbiorem składającym się z następujących elementów:
562+ - *gdSelected* Komórka będzie miała wygląd wybranej, zaznaczonej.
563+ - *gdFocused* Komórka będzie miała wygląd skupionej (focus).
564+ - *gdFixed* Komórka musi być pomalowana jak komórka stała.
565+ - *gdHot* Mysz jest nad tą komórką, więc pomaluj ją z bieżącym podświetleniem
566+ - *gdPushed* Komórka jest klikana, więc pomaluj ją jako wciśniętą
664567
665- * **DrawCell.** Metoda DrawCell jest wirtualna i może zostać zastąpiona w siatkach potomnych w celu wykonania niestandardowego rysowania. Informacje przekazywane do DrawCell pomagają zidentyfikować konkretną komórkę, która jest malowana, fizyczny obszar zajmowany na ekranie i widoczny status. Zobacz odwołanie do DrawCell, aby uzyskać szczegółowe informacje. Dla każdej komórki wykonywane są następujące operacje:
666- * **PrepareCanvas.** W tej metodzie, jeśli ustawiona jest właściwość DefaultDrawing, płótno siatki jest skonfigurowane z domyślnymi właściwościami pędzla i czcionki na podstawie bieżącego stanu wizualnego. W przypadku kilku właściwości wyglądu i środowiska wykonawczego wyrównanie tekstu jest ustawiane tak, aby było zgodne z wyborem programisty w niestandardowych kolumnach, jeśli takie istnieją. Jeśli DefaultDrawing ma wartość False, kolor pędzla jest ustawiony na clWindow, a kolor czcionki na clWindowText, wyrównanie tekstu jest ustawiane za pomocą wartości właściwości siatek defaultTextStyle.
667- * **OnPrepareCanvas.** Jeśli programista napisał obsługę zdarzenia dla zdarzenia OnPrepareCanvas, jest on wywoływany w tym momencie. To zdarzenie może służyć do wykonywania prostych dostosowań, takich jak zmiana koloru tła komórki, właściwości czcionki, takie jak kolor, czcionka i styl, układ tekstu, na przykład różne kombinacje wyrównania do lewej, do środka, do góry, do dołu, do prawej itp. Wszelkie zmiany wprowadzone na płótnie w tym zdarzeniu zostałoby utracone, ponieważ następujące potem rysowanie komórki ponownie zresetuje obszar roboczy do stanu domyślnego. Więc bezpieczniej jest robić zmiany tylko dla konkretnej komórki lub komórek i zapomnieć o pozostałych. Użycie tego zdarzenia czasami pomaga uniknąć użycia zdarzenia siatki OnDrawCell, w którym użytkownicy byliby zmuszeni do powielenia kodu rysowania siatki. Do zrobienia: informacje o tym, co można zrobić tutaj, a co zostawić dla zdarzenia OnDrawCell?...
668- * **OnDrawCell.** Następnie, jeśli nie określono obsługi zdarzenia OnDrawCell, siatka wywołuje metodę DefaultDrawCell, która po prostu maluje tło komórki przy użyciu bieżącego koloru i stylu pędzla płótna. Jeśli istnieje procedura obsługi OnDrawCell, siatka najpierw maluje tło komórki, ale tylko wtedy, gdy ustawiono właściwość DefaultDrawing, a następnie wywołuje zdarzenie OnDrawCell w celu wykonania niestandardowego malowania komórek. Zwykle programiści chcą wykonywać niestandardowe rysowanie tylko dla określonych komórek, ale standardowe rysowanie dla innych; w tym przypadku mogą ograniczyć niestandardową operację do określonej komórki lub komórek, zaglądając do argumentów ACol, Arow i AState, a dla innych komórek po prostu wywołując metodę DefaultDrawCell, aby pozwolić zająć się tym siatce.
669- * **Text.** W tym momencie (tylko dla TStringGrid), jeśli właściwość DefaultDrawing ma wartość True, malowana jest zawartość tekstowa komórki.
670- * **Grid lines**. Ostatnim krokiem dla każdej komórki jest malowanie linii siatki: jeśli określono opcje siatki goVertLine, goHorzLine, goFixedVertLine i goFixedHorzLine, siatka komórek jest rysowana w tym miejscu. Siatki zawierające tylko wiersze lub tylko kolumny można uzyskać, zmieniając te opcje. Jeśli programista wybrał wygląd „motywu” (tsNative), jest to również robione w tym momencie (zobacz właściwość TitleStyle).
671- * **FocusRect.** Po pomalowaniu wszystkich kolumn bieżącego wiersza nadszedł czas na narysowanie prostokąta skupienia (focus) dla aktualnie zaznaczonej komórki lub dla całego wiersza, jeśli ustawiono opcję goRowSelect.
568+- **DrawCell.** Metoda DrawCell jest wirtualna i może zostać zastąpiona w siatkach potomnych w celu wykonania niestandardowego rysowania. Informacje przekazywane do DrawCell pomagają zidentyfikować konkretną komórkę, która jest malowana, fizyczny obszar zajmowany na ekranie i widoczny status. Zobacz odwołanie do DrawCell, aby uzyskać szczegółowe informacje. Dla każdej komórki wykonywane są następujące operacje:
569+- **PrepareCanvas.** W tej metodzie, jeśli ustawiona jest właściwość DefaultDrawing, płótno siatki jest skonfigurowane z domyślnymi właściwościami pędzla i czcionki na podstawie bieżącego stanu wizualnego. W przypadku kilku właściwości wyglądu i środowiska wykonawczego wyrównanie tekstu jest ustawiane tak, aby było zgodne z wyborem programisty w niestandardowych kolumnach, jeśli takie istnieją. Jeśli DefaultDrawing ma wartość False, kolor pędzla jest ustawiony na clWindow, a kolor czcionki na clWindowText, wyrównanie tekstu jest ustawiane za pomocą wartości właściwości siatek defaultTextStyle.
570+- **OnPrepareCanvas.** Jeśli programista napisał obsługę zdarzenia dla zdarzenia OnPrepareCanvas, jest on wywoływany w tym momencie. To zdarzenie może służyć do wykonywania prostych dostosowań, takich jak zmiana koloru tła komórki, właściwości czcionki, takie jak kolor, czcionka i styl, układ tekstu, na przykład różne kombinacje wyrównania do lewej, do środka, do góry, do dołu, do prawej itp. Wszelkie zmiany wprowadzone na płótnie w tym zdarzeniu zostałoby utracone, ponieważ następujące potem rysowanie komórki ponownie zresetuje obszar roboczy do stanu domyślnego. Więc bezpieczniej jest robić zmiany tylko dla konkretnej komórki lub komórek i zapomnieć o pozostałych. Użycie tego zdarzenia czasami pomaga uniknąć użycia zdarzenia siatki OnDrawCell, w którym użytkownicy byliby zmuszeni do powielenia kodu rysowania siatki. Do zrobienia: informacje o tym, co można zrobić tutaj, a co zostawić dla zdarzenia OnDrawCell?...
571+- **OnDrawCell.** Następnie, jeśli nie określono obsługi zdarzenia OnDrawCell, siatka wywołuje metodę DefaultDrawCell, która po prostu maluje tło komórki przy użyciu bieżącego koloru i stylu pędzla płótna. Jeśli istnieje procedura obsługi OnDrawCell, siatka najpierw maluje tło komórki, ale tylko wtedy, gdy ustawiono właściwość DefaultDrawing, a następnie wywołuje zdarzenie OnDrawCell w celu wykonania niestandardowego malowania komórek. Zwykle programiści chcą wykonywać niestandardowe rysowanie tylko dla określonych komórek, ale standardowe rysowanie dla innych; w tym przypadku mogą ograniczyć niestandardową operację do określonej komórki lub komórek, zaglądając do argumentów ACol, Arow i AState, a dla innych komórek po prostu wywołując metodę DefaultDrawCell, aby pozwolić zająć się tym siatce.
572+- **Text.** W tym momencie (tylko dla TStringGrid), jeśli właściwość DefaultDrawing ma wartość True, malowana jest zawartość tekstowa komórki.
573+- **Grid lines**. Ostatnim krokiem dla każdej komórki jest malowanie linii siatki: jeśli określono opcje siatki goVertLine, goHorzLine, goFixedVertLine i goFixedHorzLine, siatka komórek jest rysowana w tym miejscu. Siatki zawierające tylko wiersze lub tylko kolumny można uzyskać, zmieniając te opcje. Jeśli programista wybrał wygląd „motywu” (tsNative), jest to również robione w tym momencie (zobacz właściwość TitleStyle).
574+- **FocusRect.** Po pomalowaniu wszystkich kolumn bieżącego wiersza nadszedł czas na narysowanie prostokąta skupienia (focus) dla aktualnie zaznaczonej komórki lub dla całego wiersza, jeśli ustawiono opcję goRowSelect.
672575
673576#### Różnice w porównaniu z Delphi
674577
675- * W Lazarusie metoda TCustomGrid.DrawCell nie jest abstrakcyjna i jej domyślna implementacja wykonuje podstawowe wypełnianie tła komórki.
676- * W Delphi tekst komórki jest rysowany przed wejściem do zdarzenia OnDrawCell (patrz [raport o błędzie #9619](<http://www.freepascal.org/mantis/view.php?id=9619>)).
578+- W Lazarusie metoda TCustomGrid.DrawCell nie jest abstrakcyjna i jej domyślna implementacja wykonuje podstawowe wypełnianie tła komórki.
579+- W Delphi tekst komórki jest rysowany przed wejściem do zdarzenia OnDrawCell (patrz [raport o błędzie \#9619](http://www.freepascal.org/mantis/view.php?id=9619)).
677580
678581### Wybór komórki w siatce
679582
680-Lokalizację bieżącej (skupionej (focused)) komórki (lub wiersza) siatki można zmienić za pomocą klawiatury, myszy lub kodu. Aby skutecznie zmienić skupienie z jednej komórki na inną, musimy przetestować pozycję docelową, aby sprawdzić, czy może ona otrzymać skupienie na komórce. W przypadku korzystania z klawiatury właściwość część procesu wykonuje AutoAdvance, znajdując następną komórkę, na której ma wykonać skupienie. Podczas korzystania z kliknięć myszą lub poruszania się po kodzie, skupienie nie zostanie przeniesione z bieżącej komórki, chyba że komórka docelowa może takie skupienie otrzymać.
583+Lokalizację bieżącej (skupionej (focused)) komórki (lub wiersza) siatki można zmienić za pomocą klawiatury, myszy lub kodu. Aby skutecznie zmienić skupienie z jednej komórki na inną, musimy przetestować pozycję docelową, aby sprawdzić, czy może ona otrzymać skupienie na komórce. W przypadku korzystania z klawiatury właściwość część procesu wykonuje AutoAdvance, znajdując następną komórkę, na której ma wykonać skupienie. Podczas korzystania z kliknięć myszą lub poruszania się po kodzie, skupienie nie zostanie przeniesione z bieżącej komórki, chyba że komórka docelowa może takie skupienie otrzymać.
681584
682-Siatka wywołuje funkcję SelectCell, aby sprawdzić, czy na komórce można wykonać skupienie: jeśli ta funkcja zwraca wartość True, to znaczy, że na komórce docelowej, zidentyfikowanej za pomocą argumentów aCol i aRow jest możliwe wykonanie skupienia (bieżąca implementacja TCustomGrid po prostu zwraca True). TCustomDrawGrid, a zatem także TDrawGrid i TStringGrid przesłaniają tę metodę, aby najpierw sprawdzić, czy komórka jest szersza niż 0; normalnie nie chcesz, aby wybrana została komórka o szerokości 0, więc komórka z tymi cechami jest automatycznie pomijana w procesie wyszukiwania odpowiedniej komórki. Inną rzeczą, jaką robi zastąpiona metoda SelectCell, jest wywołanie konfigurowanego przez użytkownika zdarzenia OnSelectCell: to zdarzenie odbiera współrzędne komórki jako argumenty i zawsze zwraca w wyniku domyślną wartość True.
585+Siatka wywołuje funkcję SelectCell, aby sprawdzić, czy na komórce można wykonać skupienie: jeśli ta funkcja zwraca wartość True, to znaczy, że na komórce docelowej, zidentyfikowanej za pomocą argumentów aCol i aRow jest możliwe wykonanie skupienia (bieżąca implementacja TCustomGrid po prostu zwraca True). TCustomDrawGrid, a zatem także TDrawGrid i TStringGrid przesłaniają tę metodę, aby najpierw sprawdzić, czy komórka jest szersza niż 0; normalnie nie chcesz, aby wybrana została komórka o szerokości 0, więc komórka z tymi cechami jest automatycznie pomijana w procesie wyszukiwania odpowiedniej komórki. Inną rzeczą, jaką robi zastąpiona metoda SelectCell, jest wywołanie konfigurowanego przez użytkownika zdarzenia OnSelectCell: to zdarzenie odbiera współrzędne komórki jako argumenty i zawsze zwraca w wyniku domyślną wartość True.
683586
684-Gdy wiadomo, że komórka może uzyskać skupienie i jesteśmy pewni, że nastąpi ruch, najpierw wywoływana jest metoda BeforeMoveSelection; to z kolei wyzwala zdarzenie OnBeforeSelection. Argumentami tej metody są współrzędne nowej komórki ze skupieniem. W tym momencie każdy widoczny edytor jest również ukryty. Słowo „before” (przed) oznacza, że ​​zaznaczenie nie zostało jeszcze zmienione, a dostęp do aktualnych współrzędnych komórki skupionej można uzyskać za pomocą właściwości grid.Col i grid.Row.
587+Gdy wiadomo, że komórka może uzyskać skupienie i jesteśmy pewni, że nastąpi ruch, najpierw wywoływana jest metoda BeforeMoveSelection; to z kolei wyzwala zdarzenie OnBeforeSelection. Argumentami tej metody są współrzędne nowej komórki ze skupieniem. W tym momencie każdy widoczny edytor jest również ukryty. Słowo „before” (przed) oznacza, że ​​zaznaczenie nie zostało jeszcze zmienione, a dostęp do aktualnych współrzędnych komórki skupionej można uzyskać za pomocą właściwości grid.Col i grid.Row.
685588
686-Następnie wewnętrzne współrzędne skupionej komórki są zmieniane, a potem wywoływana jest metoda MoveSelection; celem tej metody jest wyzwolenie zdarzenia OnSelection, jeśli jest ustawione (jest to powiadomienie, że skupiona komórka już się zmieniła, a współrzędne komórki są teraz dostępne we właściwościach grid.row i grid.col).
589+Następnie wewnętrzne współrzędne skupionej komórki są zmieniane, a potem wywoływana jest metoda MoveSelection; celem tej metody jest wyzwolenie zdarzenia OnSelection, jeśli jest ustawione (jest to powiadomienie, że skupiona komórka już się zmieniła, a współrzędne komórki są teraz dostępne we właściwościach grid.row i grid.col).
687590
688-Należy zauważyć, że nie jest dobrze używać zdarzenia OnSelectCell do wykrywania zmian skupienia komórki, ponieważ to zdarzenie zostanie wyzwolone kilka razy nawet dla tej samej komórki w procesie wyszukiwania odpowiedniej komórki. Lepiej jest użyć do tego celu zdarzeń OnBeforeSelection lub OnSelection.
591+Należy zauważyć, że nie jest dobrze używać zdarzenia OnSelectCell do wykrywania zmian skupienia komórki, ponieważ to zdarzenie zostanie wyzwolone kilka razy nawet dla tej samej komórki w procesie wyszukiwania odpowiedniej komórki. Lepiej jest użyć do tego celu zdarzeń OnBeforeSelection lub OnSelection.
689592
690593#### Różnice w porównaniu z Delphi
691594
692- * Zachowanie SelectCell i OnSelectCell jest prawdopodobnie inne — nie można tak naprawdę komentować różnic. W Lazarusie są one używane w funkcjonalności takiej jak AutoAdvance, która, o ile wiem, nie istnieje w Delphi.
595+- Zachowanie SelectCell i OnSelectCell jest prawdopodobnie inne — nie można tak naprawdę komentować różnic. W Lazarusie są one używane w funkcjonalności takiej jak AutoAdvance, która, o ile wiem, nie istnieje w Delphi.
693596
694597### Gdy powyższe dostosowanie nie wystarczy, siatki pochodne
695598
696-Siatki pochodne zazwyczaj muszą zastąpić następujące metody:
697-DrawAllRows: Rysuje wszystkie widoczne wiersze.
698-DrawRow: Rysuje wszystkie komórki w rzędzie.
699-DrawRow rysuje wszystkie komórki w rzędzie, najpierw sprawdzając, czy komórka znajduje się w obszarze przycinania, i rysuje tylko komórkę, jeśli tak jest.
700-DrawCell:
701-DrawCellGrid:
702-DrawCellText:
703-DrawFocusRect:
704-(napisz do mnie).
599+Siatki pochodne zazwyczaj muszą zastąpić następujące metody:\
600+DrawAllRows: Rysuje wszystkie widoczne wiersze.\
601+DrawRow: Rysuje wszystkie komórki w rzędzie.\
602+DrawRow rysuje wszystkie komórki w rzędzie, najpierw sprawdzając, czy komórka znajduje się w obszarze przycinania, i rysuje tylko komórkę, jeśli tak jest.\
603+DrawCell:\
604+DrawCellGrid:\
605+DrawCellText:\
606+DrawFocusRect:\
607+(napisz do mnie).\
705608
706609### Co dzieje się w metodzie `TCustomGrid.Paint`?
707610
708-Poniższa lista pokazuje wewnętrzną kolejność wywołań metod dla malowania `TCustomGrid` (lub potomka). Każda pozycja na listach reprezentuje wywołania metod podczas operacji malowania. Powinno to pomóc w znalezieniu właściwego punktu do zmiany zachowania, jeśli chodzi o tworzenie klas potomnych z `TCustomGrid`.
611+Poniższa lista pokazuje wewnętrzną kolejność wywołań metod dla malowania `TCustomGrid` (lub potomka). Każda pozycja na listach reprezentuje wywołania metod podczas operacji malowania. Powinno to pomóc w znalezieniu właściwego punktu do zmiany zachowania, jeśli chodzi o tworzenie klas potomnych z `TCustomGrid`.
709612
710- * **`DrawEdges`** : Rysuje zewnętrzną granicę siatki.
711- * **`DrawAllRows`** (virtual): Rysuje wszystkie wiersze w widocznej części siatki. Jest to jedyna metoda wywoływana w procesie malowania, która jest zadeklarowana jako _`virtual`_ (wirtualna).
712- * **`DrawRow`** (virtual): Jest wywoływana dla każdego wiersza wewnątrz obecnego widoku.
713- * **`DrawCell`** (virtual): Jest najpierw wywoływana dla każdej „normalnej” (tj. niestałej) komórki w rzędzie.
714- * **`PrepareCanvas`** (virtual): Ustawia style rysowania na płótnie zgodnie z wizualnymi właściwościami bieżącej komórki.
715- * **`DrawFillRect`** : Rysuje tło komórki ze stylami ustawionymi w `PrepareCanvas`.
716- * **`DrawCellGrid`** (virtual): Rysuje linie obramowania komórki.
717- * **`DrawFocusRect`** (virtual): W `TCustomGrid` ta metoda nic nie robi. W siatkach potomnych ta metoda jest używana do rysowania prostokąta skupienia wewnątrz aktywnej komórki.
718- * **`DrawCell`** (virtual): (patrz powyżej) Jest wywoływana dla każdej stałej (fixed) komórki w widocznym obszarze wiersza.
719- * **`DrawColRowMoving`** : Aktywna tylko podczas przenoszenia kolumny lub wiersza. Ta metoda rysuje linię wskazującą nową pozycję wiersza/kolumny.
720- * **`DrawBorder`** : W razie potrzeby (`Flat=TRUE` i `BorderStyle=bsSingle`) rysuje wewnętrzną linię obramowania.
613+- **`DrawEdges`**: Rysuje zewnętrzną granicę siatki.
614+- **`DrawAllRows`** (virtual): Rysuje wszystkie wiersze w widocznej części siatki. Jest to jedyna metoda wywoływana w procesie malowania, która jest zadeklarowana jako *`virtual`* (wirtualna).
615+ - **`DrawRow`** (virtual): Jest wywoływana dla każdego wiersza wewnątrz obecnego widoku.
616+ - **`DrawCell`** (virtual): Jest najpierw wywoływana dla każdej „normalnej” (tj. niestałej) komórki w rzędzie.
617+ - **`PrepareCanvas`** (virtual): Ustawia style rysowania na płótnie zgodnie z wizualnymi właściwościami bieżącej komórki.
618+ - **`DrawFillRect`**: Rysuje tło komórki ze stylami ustawionymi w `PrepareCanvas`.
619+ - **`DrawCellGrid`** (virtual): Rysuje linie obramowania komórki.
620+ - **`DrawFocusRect`** (virtual): W `TCustomGrid` ta metoda nic nie robi. W siatkach potomnych ta metoda jest używana do rysowania prostokąta skupienia wewnątrz aktywnej komórki.
621+ - **`DrawCell`** (virtual): (patrz powyżej) Jest wywoływana dla każdej stałej (fixed) komórki w widocznym obszarze wiersza.
622+- **`DrawColRowMoving`**: Aktywna tylko podczas przenoszenia kolumny lub wiersza. Ta metoda rysuje linię wskazującą nową pozycję wiersza/kolumny.
623+- **`DrawBorder`**: W razie potrzeby (`Flat=TRUE` i `BorderStyle=bsSingle`) rysuje wewnętrzną linię obramowania.
721624
722625#### Dodatkowe metody rysowania w `TCustomGrid`
723626
724-Te metody są zadeklarowane i (częściowo) zaimplementowane w `TCustomGrid`, ale nie są wywoływane bezpośrednio z tego miejsca. Są używane przez klasy potomne do rysowania zawartości komórki.
627+Te metody są zadeklarowane i (częściowo) zaimplementowane w `TCustomGrid`, ale nie są wywoływane bezpośrednio z tego miejsca. Są używane przez klasy potomne do rysowania zawartości komórki.
725628
726- * **`DrawCellText`** (virtual): Zapisuje/rysuje tekst, który jest przekazywany jako parametr do komórki. Tekst jest formatowany przy użyciu stylów aktywnych w `Canvas.TextStyle` (zobacz także `PrepareCanvas`).
727- * **`DrawThemedCell`** (virtual): Jest używany tylko dla stałych komórek i tylko jeśli `TitleStyle=tsNative`. Rysuje tło komórki za pomocą `ThemeServices`.
728- * **`DrawColumnText`** (virtual): Jest używany tylko dla komórek nagłówka kolumny.
729- * **`DrawColumnTitleImage`** : Jeśli siatka ma przypisany `TitleImageList` i `Columns.Title[x].Title.ImageIndex` zawiera prawidłową wartość, to ten wybrany obraz jest rysowany w komórce.
730- * **`DrawCellText`** : (patrz wyżej)
731- * **`DrawTextInCell`** (virtual): Jest używany do „normalnych” (tj. niestałych) komórek. W `TCustomGrid` ta metoda nic nie robi. W siatkach potomnych ta metoda służy do rysowania zawartości komórek. W `TSringGrid` metoda ta wywołuje `DrawCellText` (patrz wyżej).
629+- **`DrawCellText`** (virtual): Zapisuje/rysuje tekst, który jest przekazywany jako parametr do komórki. Tekst jest formatowany przy użyciu stylów aktywnych w `Canvas.TextStyle` (zobacz także `PrepareCanvas`).
630+- **`DrawThemedCell`** (virtual): Jest używany tylko dla stałych komórek i tylko jeśli `TitleStyle=tsNative`. Rysuje tło komórki za pomocą `ThemeServices`.
631+- **`DrawColumnText`** (virtual): Jest używany tylko dla komórek nagłówka kolumny.
632+ - **`DrawColumnTitleImage`**: Jeśli siatka ma przypisany `TitleImageList` i `Columns.Title[x].Title.ImageIndex` zawiera prawidłową wartość, to ten wybrany obraz jest rysowany w komórce.
633+ - **`DrawCellText`** : (patrz wyżej)
634+- **`DrawTextInCell`** (virtual): Jest używany do „normalnych” (tj. niestałych) komórek. W `TCustomGrid` ta metoda nic nie robi. W siatkach potomnych ta metoda służy do rysowania zawartości komórek. W `TSringGrid` metoda ta wywołuje `DrawCellText` (patrz wyżej).
732635
733636#### Metody rysowania wprowadzone przez `TCustomDrawGrid`
734637
735-Jak widać, klasa bazowa `TCustomGrid` nie rysuje żadnej zawartości w komórkach. Odbywa się to w **`TCustomDrawGrid`**. **`TCustomDrawGrid`** nadpisuje metodę `DrawCell` w następujący sposób:
638+Jak widać, klasa bazowa `TCustomGrid` nie rysuje żadnej zawartości w komórkach. Odbywa się to w **`TCustomDrawGrid`**. **`TCustomDrawGrid`** nadpisuje metodę `DrawCell` w następujący sposób:
736639
737- * **`DrawCell`** (override):
738- * **`PrepareCanvas`** : wywołuje odziedziczoną metodę z **`TCustomGrid`**.
739- * **`DefaultDrawCell`** (virtual): Ta metoda jest wywoływana tylko wtedy, gdy procedura obsługi zdarzeń dla `OnDrawCell` NIE jest przypisana.
740- * **`DrawFillRect / DrawThemedCell`** (od `TCustomGrid`): Rysuje tło komórki. Jeśli `TitleStyle=tsNative`, wówczas tło stałych komórek jest rysowane za pomocą `DrawThemedCell`.
741- * **`DrawCellAutonumbering`** (virtual): Kiedy `goFixedAutonumbering` jest włączona w `Options`, to numery wierszy są rysowane w pierwszej ustalonej kolumnie przy użyciu `TCustomGrid.DrawCellText`.
742- * **`DrawColumnText`** (z `TCustomGrid`): Jest wywoływana tylko dla komórek nagłówka kolumny (zobacz _Dodatkowe metody rysowania w` TCustomGrid`_).
743- * **`DrawTextInCell`** (z `TCustomGrid`): Jest wywoływana tylko dla 'normalnych' (tj. niestałych) komórek (zobacz _Dodatkowe metody rysowania w` TCustomGrid`_).
744- * **`DrawCellGrid`** (virtual): Rysuje obramowanie komórki.
640+- **`DrawCell`** (override):
641+ - **`PrepareCanvas`**: wywołuje odziedziczoną metodę z **`TCustomGrid`**.
642+ - **`DefaultDrawCell`** (virtual): Ta metoda jest wywoływana tylko wtedy, gdy procedura obsługi zdarzeń dla `OnDrawCell` NIE jest przypisana.
643+ - **`DrawFillRect / DrawThemedCell`** (od `TCustomGrid`): Rysuje tło komórki. Jeśli `TitleStyle=tsNative`, wówczas tło stałych komórek jest rysowane za pomocą `DrawThemedCell`.
644+ - **`DrawCellAutonumbering`** (virtual): Kiedy `goFixedAutonumbering` jest włączona w `Options`, to numery wierszy są rysowane w pierwszej ustalonej kolumnie przy użyciu `TCustomGrid.DrawCellText`.
645+ - **`DrawColumnText`** (z `TCustomGrid`): Jest wywoływana tylko dla komórek nagłówka kolumny (zobacz *Dodatkowe metody rysowania w `TCustomGrid`*).
646+ - **`DrawTextInCell`** (z `TCustomGrid`): Jest wywoływana tylko dla 'normalnych' (tj. niestałych) komórek (zobacz *Dodatkowe metody rysowania w `TCustomGrid`*).
647+ - **`DrawCellGrid`** (virtual): Rysuje obramowanie komórki.
745648
746649### Zapisz i Odzyskaj zawartość siatki
747650
748-Metody **SaveToFile** i **LoadFromFile** umożliwiają siatce zapisywanie i pobieranie układu i danych do/z pliku w formacie XML. TStringGrid, odziedziczony z TCustomStringGrid, ma również możliwość „eksportowania” i „importowania” swojej zawartości do/z pliku w formacie wartości oddzielonych przecinkami, lepiej znanego jako format pliku CSV. Jest to opisane w dokumentacji do metod **SaveToCSVFile** i **LoadFromCSVFile** (do zrobienia: utworzyć łącza).
651+Metody **SaveToFile** i **LoadFromFile** umożliwiają siatce zapisywanie i pobieranie układu i danych do/z pliku w formacie XML. TStringGrid, odziedziczony z TCustomStringGrid, ma również możliwość „eksportowania” i „importowania” swojej zawartości do/z pliku w formacie wartości oddzielonych przecinkami, lepiej znanego jako format pliku CSV. Jest to opisane w dokumentacji do metod **SaveToCSVFile** i **LoadFromCSVFile** (do zrobienia: utworzyć łącza).
749652
750-Rodzaj informacji, które można zapisać, a następnie pobrać podczas używania **SaveToFile** i **LoadFromFile** , jest określony przez właściwość SaveOptions (typu TSaveOptions), która jest zestawem opcji opisanych w następujący sposób:
751-```
752-soDesign: Zapisz i wczytaj ColCount,RowCount,FixedCols,FixedRows,
753- ColWidths, RowHeights i Options (TCustomGrid)
754- soPosition: Zapisz i wczytaj wartości pozycji Scroll, Row, Col i Selection (TCustomGrid)
755- soAttributes: Zapisz i wczytaj kolory, wyrównanie tekstu i układ itp. (TCustomDrawGrid)
756- soContent: Zapisz i wczytaj tekst (TCustomStringGrid)
757- soAll: Ustaw wszystkie opcje (soAll:=[soDesign,soPosition,soAttributes,soContent];)
758-```
653+Rodzaj informacji, które można zapisać, a następnie pobrać podczas używania **SaveToFile** i **LoadFromFile**, jest określony przez właściwość SaveOptions (typu TSaveOptions), która jest zestawem opcji opisanych w następujący sposób:
759654
760-Nie wszystkie opcje mają zastosowanie do wszystkich rodzajów siatek, na przykład soContent nie mają zastosowania do siatek pochodnych TCustomGrid, takich jak TDrawGrid, ponieważ ten rodzaj siatki nie zawiera pojęcia „treści”. TStringGrid jest specjalnym rodzajem siatki, która „wie”, jak obsługiwać łańcuchy i może użyć opcji soContent, jeśli jest określona.
655+`soDesign:     Zapisz i wczytaj ColCount,RowCount,FixedCols,FixedRows,`\
656+`              ColWidths, RowHeights i Options (TCustomGrid)`\
657+`soPosition:   Zapisz i wczytaj wartości pozycji Scroll, Row, Col i Selection (TCustomGrid)`\
658+`soAttributes: Zapisz i wczytaj kolory, wyrównanie tekstu i układ itp. (TCustomDrawGrid)`\
659+`soContent:    Zapisz i wczytaj tekst (TCustomStringGrid)`\
660+`soAll:        Ustaw wszystkie opcje (soAll:=[soDesign,soPosition,soAttributes,soContent];)`
761661
762-Opcja soAttributes nie jest używana w standardowych siatkach Lazarusa, jest dostępna w przypadku siatek potomnych.
662+Nie wszystkie opcje mają zastosowanie do wszystkich rodzajów siatek, na przykład soContent nie mają zastosowania do siatek pochodnych TCustomGrid, takich jak TDrawGrid, ponieważ ten rodzaj siatki nie zawiera pojęcia „treści”. TStringGrid jest specjalnym rodzajem siatki, która „wie”, jak obsługiwać łańcuchy i może użyć opcji soContent, jeśli jest określona.
763663
764-Podczas używania **LoadFromFile** siatka używa również właściwości SaveOptions, aby wiedzieć, jakie informacje należy pobrać z pliku, więc np. jest całkowicie możliwe określenie SaveOptions:=[soDesign,soContent] przy zapisywaniu i tylko SaveOptions :=[soContent] podczas ładowania.
664+Opcja soAttributes nie jest używana w standardowych siatkach Lazarusa, jest dostępna w przypadku siatek potomnych.
765665
766-Dla TStringGrid domyślną wartością SaveOptions jest [soContent], dla innego rodzaju siatek SaveOptions jest pustym zbiorem.
666+Podczas używania **LoadFromFile** siatka używa również właściwości SaveOptions, aby wiedzieć, jakie informacje należy pobrać z pliku, więc np. jest całkowicie możliwe określenie SaveOptions:=\[soDesign,soContent\] przy zapisywaniu i tylko SaveOptions :=\[soContent\] podczas ładowania.
767667
768-**Uwaga:** Jeden typowy problem podczas zapisywania i pobierania danych siatki występuje, gdy użytkownik określi właściwość SaveOptions przed **SaveToFile** , ale nie przed **LoadFromFile**. W przypadku użycia **LoadFromFile** jakiś czas po użyciu **SaveToFile** właściwość SaveOptions jest ustawiona prawidłowo, ale jeśli **LoadFromFile** zostanie wykonane przy następnym uruchomieniu programu, właściwość SaveOptions może nie zostać poprawnie skonfigurowane, z tego powodu zaleca się, aby zawsze określać właściwość SaveOptions tuż przed **LoadFromFile** lub robić to globalnie podczas uruchamiania programu, jak w poniższym przykładzie:
668+Dla TStringGrid domyślną wartością SaveOptions jest \[soContent\], dla innego rodzaju siatek SaveOptions jest pustym zbiorem.
769669
770-* * *
670+**Uwaga:** Jeden typowy problem podczas zapisywania i pobierania danych siatki występuje, gdy użytkownik określi właściwość SaveOptions przed **SaveToFile**, ale nie przed **LoadFromFile**. W przypadku użycia **LoadFromFile** jakiś czas po użyciu **SaveToFile** właściwość SaveOptions jest ustawiona prawidłowo, ale jeśli **LoadFromFile** zostanie wykonane przy następnym uruchomieniu programu, właściwość SaveOptions może nie zostać poprawnie skonfigurowane, z tego powodu zaleca się, aby zawsze określać właściwość SaveOptions tuż przed **LoadFromFile** lub robić to globalnie podczas uruchamiania programu, jak w poniższym przykładzie:
771671
672+------------------------------------------------------------------------
673+
772674**Przykład:**
773675
774- 1. Najpierw przejdź do menu "Plik -> Nowy -> Aplikacja";
775- 2. Umieść pusty TStringGrid w formularzu;
776- 3. Umieść na formularzu TButton i TOpenDialog;
777- 4. Dodaj zdarzenie OnCreate do formularza;
778- 5. Dodaj zdarzenie OnClick dla przycisku.
676+1. Najpierw przejdź do menu "Plik -\> Nowy -\> Aplikacja";
677+2. Umieść pusty TStringGrid w formularzu;
678+3. Umieść na formularzu TButton i TOpenDialog;
679+4. Dodaj zdarzenie OnCreate do formularza;
680+5. Dodaj zdarzenie OnClick dla przycisku.
779681
780-```
682+``` pascal
781683unit Unit1;
782-
783- {$mode objfpc}{$H+}
784-
785- interface
786-
787- uses
788- Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Grids,
789- Buttons, StdCtrls, XMLCfg;
790-
791- type
792-
793- { TForm1 }
794- TForm1 = class(TForm)
795- StringGrid1: TStringGrid;
796- Button1: TButton;
797- OpenDialog1: TOpenDialog;
798- procedure Button1Click(Sender: TObject);
799- procedure Form1Create(Sender: TObject);
800- private
801- { private declarations }
802- public
803- { public declarations }
804- end;
805-
806- var
807- Form1: TForm1;
808-
809- implementation
810-
811- { TForm1 }
812-
813- procedure TForm1.Form1Create(Sender: TObject);
814- begin
815- //ustawia SaveOptions w momencie tworzenia formularza
816- stringgrid1.SaveOptions := [soDesign,soPosition,soAttributes,soContent];
817- end;
818-
819-
820- procedure TForm1.Button1Click(Sender: TObject);
821- begin
822- //Pytaj, czy uruchomiono metodę Execute w OpenDialog,
823- //a gdy to nastąpi, użytkownik wybiera plik XML do załadowania,
824- //którego nazwa była przechowywana we właściwości FileName.
825-
826- if opendialog1.Execute then
827- begin
828- //Wyczyść siatkę
829- StringGrid1.Clear;
830- //Załaduj plik XML
831- StringGrid1.LoadFromFile(OpenDialog1.FileName);
832- //Odśwież siatkę
833- StringGrid1.Refresh;
834- end;
835- end;
836-
837- initialization
838- {$I unit1.lrs}
839-
840- end.
841-```
842684
843-* * *
685+{$mode objfpc}{$H+}
844686
845-**Przykładowy plik xml:** (Skopiuj poniższy tekst do pliku txt. Nie zapomnij umieścić nagłówka xml :-))
687+interface
688+
689+uses
690+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Grids,
691+ Buttons, StdCtrls, XMLCfg;
692+
693+type
694+
695+ { TForm1 }
696+ TForm1 = class(TForm)
697+ StringGrid1: TStringGrid;
698+ Button1: TButton;
699+ OpenDialog1: TOpenDialog;
700+ procedure Button1Click(Sender: TObject);
701+ procedure Form1Create(Sender: TObject);
702+ private
703+ { private declarations }
704+ public
705+ { public declarations }
706+ end;
707+
708+var
709+ Form1: TForm1;
710+
711+implementation
712+
713+{ TForm1 }
714+
715+procedure TForm1.Form1Create(Sender: TObject);
716+begin
717+ //ustawia SaveOptions w momencie tworzenia formularza
718+ stringgrid1.SaveOptions := [soDesign,soPosition,soAttributes,soContent];
719+end;
720+
721+procedure TForm1.Button1Click(Sender: TObject);
722+begin
723+ //Pytaj, czy uruchomiono metodę Execute w OpenDialog,
724+ //a gdy to nastąpi, użytkownik wybiera plik XML do załadowania,
725+ //którego nazwa była przechowywana we właściwości FileName.
726+
727+ if opendialog1.Execute then
728+ begin
729+ //Wyczyść siatkę
730+ StringGrid1.Clear;
731+ //Załaduj plik XML
732+ StringGrid1.LoadFromFile(OpenDialog1.FileName);
733+ //Odśwież siatkę
734+ StringGrid1.Refresh;
735+ end;
736+end;
737+
738+initialization
739+ {$I unit1.lrs}
740+
741+end.
846742```
743+
744+------------------------------------------------------------------------
745+
746+**Przykładowy plik xml:** (Skopiuj poniższy tekst do pliku txt. Nie zapomnij umieścić nagłówka xml :-))
747+
748+``` xml
847749<?xml version="1.0"?>
848- <CONFIG>
849- <grid version="3">
850- <saveoptions create="True" position="True" content="True"/>
851- <design columncount="2" rowcount="5" fixedcols="1" fixedrows="1" defaultcolwidth="64" defaultRowHeight="20">
852- <options>
853- <goFixedVertLine value="True"/>
854- <goFixedHorzLine value="True"/>
855- <goVertLine value="True"/>
856- <goHorzLine value="True"/>
857- <goRangeSelect value="True"/>
858- <goDrawFocusSelected value="False"/>
859- <goRowSizing value="False"/>
860- <goColSizing value="False"/>
861- <goRowMoving value="False"/>
862- <goColMoving value="False"/>
863- <goEditing value="False"/>
864- <goTabs value="False"/>
865- <goRowSelect value="False"/>
866- <goAlwaysShowEditor value="False"/>
867- <goThumbTracking value="False"/>
868- <goColSpanning value="False"/>
869- <goRelaxedRowSelect value="False"/>
870- <goDblClickAutoSize value="False"/>
871- <goSmoothScroll value="True"/>
872- </options>
873- </design>
874- <position topleftcol="1" topleftrow="1" col="1" row="1">
875- <selection left="1" top="1" right="1" bottom="1"/>
876- </position>
877- <content>
878- <cells cellcount="10">
879- <cell1 column="0" row="0" text="Title Col1"/>
880- <cell2 column="0" row="1" text="value(1.1)"/>
881- <cell3 column="0" row="2" text="value(2.1)"/>
882- <cell4 column="0" row="3" text="value(3.1)"/>
883- <cell5 column="0" row="4" text="value(4.1)"/>
884- <cell6 column="1" row="0" text="Title Col2"/>
885- <cell7 column="1" row="1" text="value(1.2)"/>
886- <cell8 column="1" row="2" text="value(2.2)"/>
887- <cell9 column="1" row="3" text="value(3.2)"/>
888- <cell10 column="1" row="4" text="value(4.2)"/>
889- </cells>
890- </content>
891- </grid>
892- </CONFIG>
750+<CONFIG>
751+ <grid version="3">
752+ <saveoptions create="True" position="True" content="True"/>
753+ <design columncount="2" rowcount="5" fixedcols="1" fixedrows="1" defaultcolwidth="64" defaultRowHeight="20">
754+ <options>
755+ <goFixedVertLine value="True"/>
756+ <goFixedHorzLine value="True"/>
757+ <goVertLine value="True"/>
758+ <goHorzLine value="True"/>
759+ <goRangeSelect value="True"/>
760+ <goDrawFocusSelected value="False"/>
761+ <goRowSizing value="False"/>
762+ <goColSizing value="False"/>
763+ <goRowMoving value="False"/>
764+ <goColMoving value="False"/>
765+ <goEditing value="False"/>
766+ <goTabs value="False"/>
767+ <goRowSelect value="False"/>
768+ <goAlwaysShowEditor value="False"/>
769+ <goThumbTracking value="False"/>
770+ <goColSpanning value="False"/>
771+ <goRelaxedRowSelect value="False"/>
772+ <goDblClickAutoSize value="False"/>
773+ <goSmoothScroll value="True"/>
774+ </options>
775+ </design>
776+ <position topleftcol="1" topleftrow="1" col="1" row="1">
777+ <selection left="1" top="1" right="1" bottom="1"/>
778+ </position>
779+ <content>
780+ <cells cellcount="10">
781+ <cell1 column="0" row="0" text="Title Col1"/>
782+ <cell2 column="0" row="1" text="value(1.1)"/>
783+ <cell3 column="0" row="2" text="value(2.1)"/>
784+ <cell4 column="0" row="3" text="value(3.1)"/>
785+ <cell5 column="0" row="4" text="value(4.1)"/>
786+ <cell6 column="1" row="0" text="Title Col2"/>
787+ <cell7 column="1" row="1" text="value(1.2)"/>
788+ <cell8 column="1" row="2" text="value(2.2)"/>
789+ <cell9 column="1" row="3" text="value(3.2)"/>
790+ <cell10 column="1" row="4" text="value(4.2)"/>
791+ </cells>
792+ </content>
793+ </grid>
794+</CONFIG>
893795```
894796
895797### Edytory komórek siatki
896798
897-Siatka używa edytorów komórek do zmiany zawartości komórek.
799+Siatka używa edytorów komórek do zmiany zawartości komórek.
898800
899-W przypadku wyspecjalizowanej siatki, takiej jak TStringGrid, edytor jest zwykłą jednowierszową kontrolką edytora tekstu, ale czasami pożądane jest posiadanie innych sposobów wprowadzania informacji. Na przykład:
801+W przypadku wyspecjalizowanej siatki, takiej jak TStringGrid, edytor jest zwykłą jednowierszową kontrolką edytora tekstu, ale czasami pożądane jest posiadanie innych sposobów wprowadzania informacji. Na przykład:
900802
901- 1. pokaż okno dialogowe otwierania pliku, po to by znaleźć lokalizację pliku, żeby użytkownik nie musiał ręcznie wpisywać pełnej ścieżki
902- 2. jeśli tekst w komórce reprezentuje datę, wyświetl kalendarz, abyśmy mogli łatwo wybrać konkretną datę.
803+1. pokaż okno dialogowe otwierania pliku, po to by znaleźć lokalizację pliku, żeby użytkownik nie musiał ręcznie wpisywać pełnej ścieżki
804+2. jeśli tekst w komórce reprezentuje datę, wyświetl kalendarz, abyśmy mogli łatwo wybrać konkretną datę.
903805
904-Czasami informacje, które użytkownik powinien wprowadzić w komórce, są ograniczone do ograniczonej listy słów; w takim przypadku bezpośrednie wpisywanie informacji może wprowadzać błędy i może zaistnieć potrzeba zaimplementowania procedur sprawdzania poprawności. Możemy tego uniknąć, używając edytora komórek, który przedstawia użytkownikowi listę zawierającą tylko prawidłowe wartości.
806+Czasami informacje, które użytkownik powinien wprowadzić w komórce, są ograniczone do ograniczonej listy słów; w takim przypadku bezpośrednie wpisywanie informacji może wprowadzać błędy i może zaistnieć potrzeba zaimplementowania procedur sprawdzania poprawności. Możemy tego uniknąć, używając edytora komórek, który przedstawia użytkownikowi listę zawierającą tylko prawidłowe wartości.
905807
906-Dotyczy to również ogólnych siatek, takich jak TDrawGrid, w których użytkownik potrzebuje jakiejś struktury do przechowywania danych, które będą wyświetlane w siatce. W takiej sytuacji informacje wprowadzone w edytorze komórek aktualizują wewnętrzną strukturę, aby odzwierciedlić zmiany w siatce.
808+Dotyczy to również ogólnych siatek, takich jak TDrawGrid, w których użytkownik potrzebuje jakiejś struktury do przechowywania danych, które będą wyświetlane w siatce. W takiej sytuacji informacje wprowadzone w edytorze komórek aktualizują wewnętrzną strukturę, aby odzwierciedlić zmiany w siatce.
907809
908810#### Wbudowane edytory komórek
909811
910-Moduł grids.pas zawiera już niektóre z najczęściej używanych edytorów komórek gotowych do użycia w siatkach. Możliwe jest również tworzenie nowych edytorów komórek (niestandardowe edytory komórek), jeśli wbudowane edytory nie są odpowiednie do określonego zadania.
812+Moduł grids.pas zawiera już niektóre z najczęściej używanych edytorów komórek gotowych do użycia w siatkach. Możliwe jest również tworzenie nowych edytorów komórek (niestandardowe edytory komórek), jeśli wbudowane edytory nie są odpowiednie do określonego zadania.
911813
912-Wbudowane edytory komórek to Button, Edit i Picklist.
814+Wbudowane edytory komórek to Button, Edit i Picklist.
913815
914816#### Korzystanie z edytorów komórek
915817
916-Użytkownicy mogą określić, jaki edytor będzie używany dla danej komórki, korzystając z jednej z dwóch metod.
818+Użytkownicy mogą określić, jaki edytor będzie używany dla danej komórki, korzystając z jednej z dwóch metod.
917819
918- 1. **Korzystanie z niestandardowej kolumny i wybranie właściwości ButtonStyle kolumny**. W pierwszej metodzie użytkownik może wybrać styl edytora, który będzie wyświetlany. Dostępne wartości to: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn, cbsButtonColumn.
919- 2. **Używanie zdarzenia siatki OnSelectEditor**. W drugiej metodzie, w parametrze Editor użytkownik określa, którego edytora użyć dla komórki zidentyfikowanej dla kolumny aCol i wiersza ARow w siatce pochodnej TCustomDrawGrid lub TColumn w TCustomDBGrid. Do tego celu służy publiczna funkcja siatek EditorByStyle(), która jako parametr przyjmuje jedną z następujących wartości: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn, cbsButtonColumn. Ta metoda ma pierwszeństwo przed metodą pierwszą, gdy używane są kolumny niestandardowe. W tym miejscu można określić niestandardowy edytor komórek (patrz rozdział 5 [tego dokumentu](<http://www.freepascal.org/~michael/articles/grids/grids.pdf>) autorstwa Michaëla Van Canneyta, który wyjaśnia jak poprawnie zaimplementować niestandardowy edytor). To zdarzenie jest również miejscem do zamontowania edytora z wartościami specyficznymi dla komórki, wiersza lub kolumny (np. niestandardowe menu kontekstowe dla edytora komórek).
820+1. **Korzystanie z niestandardowej kolumny i wybranie właściwości ButtonStyle kolumny**. W pierwszej metodzie użytkownik może wybrać styl edytora, który będzie wyświetlany. Dostępne wartości to: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn, cbsButtonColumn.
821+2. **Używanie zdarzenia siatki OnSelectEditor**. W drugiej metodzie, w parametrze Editor użytkownik określa, którego edytora użyć dla komórki zidentyfikowanej dla kolumny aCol i wiersza ARow w siatce pochodnej TCustomDrawGrid lub TColumn w TCustomDBGrid. Do tego celu służy publiczna funkcja siatek EditorByStyle(), która jako parametr przyjmuje jedną z następujących wartości: cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn, cbsButtonColumn. Ta metoda ma pierwszeństwo przed metodą pierwszą, gdy używane są kolumny niestandardowe. W tym miejscu można określić niestandardowy edytor komórek (patrz rozdział 5 [tego dokumentu](http://www.freepascal.org/~michael/articles/grids/grids.pdf) autorstwa Michaëla Van Canneyta, który wyjaśnia jak poprawnie zaimplementować niestandardowy edytor). To zdarzenie jest również miejscem do zamontowania edytora z wartościami specyficznymi dla komórki, wiersza lub kolumny (np. niestandardowe menu kontekstowe dla edytora komórek).
920822
921-Ustawienie właściwości _ButtonStyle_ działa tylko wtedy, gdy kolumna jest tworzona za pomocą polecenia _StringGrid1.Columns.Add;_. Użycie wyrażenia takiego jak _StringGrid1.ColCount:=X;_ spowoduje wyjątek. Ustawienie właściwości ButtonStyle można wykonać za pomocą podobnego kodu:
922-```
823+Ustawienie właściwości *ButtonStyle* działa tylko wtedy, gdy kolumna jest tworzona za pomocą polecenia *StringGrid1.Columns.Add;*. Użycie wyrażenia takiego jak *StringGrid1.ColCount:=X;* spowoduje wyjątek. Ustawienie właściwości ButtonStyle można wykonać za pomocą podobnego kodu:
824+
825+``` pascal
923826if ColCB< StringGrid1.Columns.Count
924- then StringGrid1.Columns.Items[ColCB].ButtonStyle:=cbsCheckboxColumn;
827+ then StringGrid1.Columns.Items[ColCB].ButtonStyle:=cbsCheckboxColumn;
925828```
926829
927830#### Opis stylów edytora
928831
929-Poniżej znajduje się opis stylów edytora. Są to wartości wyliczeniowe typu TColumnButtonStyle, dlatego są poprzedzone przedrostkiem „cbs”. Ten typ został użyty, aby zachować kompatybilność z DBGrid firmy Delphi.
832+Poniżej znajduje się opis stylów edytora. Są to wartości wyliczeniowe typu TColumnButtonStyle, dlatego są poprzedzone przedrostkiem „cbs”. Ten typ został użyty, aby zachować kompatybilność z DBGrid firmy Delphi.
930833
931- * **cbsAuto**
834+- **cbsAuto**
932835
933- To jest domyślny styl edytora dla siatek potomnych TCustomGrid. Rzeczywista klasa edytora, która będzie używana do edycji zawartości komórki, zależy od kilku czynników. W przypadku TCustomGrids używana jest klasa TStringCellEditor pochodząca z TCustomMaskEdit. Ten edytor wyspecjalizowany jest do edycji jednowierszowych ciągów string. Jest on następnie domyślnie używany w TStringGrid i TDrawGrid. W przypadku korzystania z kolumn niestandardowych, jeśli programista wypełnił właściwość PickList kolumny, działa to tak, jakby ustawiono styl edytora cbsPickList. W przypadku TCustomDBGrid, który ma pole typu boolean, zachowuje się on tak, jakby określono styl edytora cbsCheckBoxColumn. Jest to zalecana wartość dla niestandardowych edytorów komórek. Do zrobienia: odniesienie do OnEditingDone.
836+
837+To jest domyślny styl edytora dla siatek potomnych TCustomGrid. Rzeczywista klasa edytora, która będzie używana do edycji zawartości komórki, zależy od kilku czynników. W przypadku TCustomGrids używana jest klasa TStringCellEditor pochodząca z TCustomMaskEdit. Ten edytor wyspecjalizowany jest do edycji jednowierszowych ciągów string. Jest on następnie domyślnie używany w TStringGrid i TDrawGrid. W przypadku korzystania z kolumn niestandardowych, jeśli programista wypełnił właściwość PickList kolumny, działa to tak, jakby ustawiono styl edytora cbsPickList. W przypadku TCustomDBGrid, który ma pole typu boolean, zachowuje się on tak, jakby określono styl edytora cbsCheckBoxColumn. Jest to zalecana wartość dla niestandardowych edytorów komórek. Do zrobienia: odniesienie do OnEditingDone.
934838
935- * **cbsEllipsis**
839+- **cbsEllipsis**
936840
937- Ten styl edytora jest najbardziej ogólny. Gdy jest używany, w komórce edycji pojawia się przycisk, a programiści mogą użyć zdarzenia siatki OnEditButtonClick, aby wykryć, kiedy użytkownik nacisnął przycisk i podjąć dowolną akcję zaprogramowaną dla takiej komórki. Na przykład programista może użyć tego stylu edytora, aby wyświetlić okno dialogowe kalendarza, aby umożliwić użytkownikowi łatwe wybranie określonej daty. Innymi możliwościami może być wyświetlenie okna dialogowego otwierania pliku w celu znalezienia plików, kalkulatora, aby użytkownik mógł wprowadzić liczbowy wynik obliczeń itp.
841+
842+Ten styl edytora jest najbardziej ogólny. Gdy jest używany, w komórce edycji pojawia się przycisk, a programiści mogą użyć zdarzenia siatki OnEditButtonClick, aby wykryć, kiedy użytkownik nacisnął przycisk i podjąć dowolną akcję zaprogramowaną dla takiej komórki. Na przykład programista może użyć tego stylu edytora, aby wyświetlić okno dialogowe kalendarza, aby umożliwić użytkownikowi łatwe wybranie określonej daty. Innymi możliwościami może być wyświetlenie okna dialogowego otwierania pliku w celu znalezienia plików, kalkulatora, aby użytkownik mógł wprowadzić liczbowy wynik obliczeń itp.
938843
939- OnEditButtonClick to tylko powiadomienie, aby dowiedzieć się, w której komórce został kliknięty przycisk, sprawdź właściwości grid.Row i grid.Col.
844+
845+OnEditButtonClick to tylko powiadomienie, aby dowiedzieć się, w której komórce został kliknięty przycisk, sprawdź właściwości grid.Row i grid.Col.
940846
941- A DBGrid ma specyficzne właściwości do pobierania aktywnej kolumny lub pola, a ponieważ to zdarzenie występuje w aktywnym rekordzie, może aktualizować informacje w aktywnym polu.
847+
848+A DBGrid ma specyficzne właściwości do pobierania aktywnej kolumny lub pola, a ponieważ to zdarzenie występuje w aktywnym rekordzie, może aktualizować informacje w aktywnym polu.
942849
943- Ten styl edytora jest zaimplementowany przy użyciu TButtonCellEditor, bezpośredniego potomka TButton.
850+
851+Ten styl edytora jest zaimplementowany przy użyciu TButtonCellEditor, bezpośredniego potomka TButton.
944852
945- * **cbsNone**
853+- **cbsNone**
946854
947- Ten styl edytora instruuje siatkę, aby nie używała żadnego edytora dla określonej komórki lub kolumny; zachowuje się wtedy tak, jakby siatka była tylko do odczytu dla takiej komórki lub kolumny.
855+
856+Ten styl edytora instruuje siatkę, aby nie używała żadnego edytora dla określonej komórki lub kolumny; zachowuje się wtedy tak, jakby siatka była tylko do odczytu dla takiej komórki lub kolumny.
948857
949- * **cbsPickList**
858+- **cbsPickList**
950859
951- Służy do przedstawienia użytkownikowi listy wartości, które można wprowadzić. Ten styl edytora jest zaimplementowany przy użyciu TPickListCellEditor, komponentu wywodzącego się z TCustomComboBox. Lista wyświetlanych wartości jest wypełniana na jeden z dwóch sposobów, w zależności od metody użytej do wyboru stylu edytora.
860+
861+Służy do przedstawienia użytkownikowi listy wartości, które można wprowadzić. Ten styl edytora jest zaimplementowany przy użyciu TPickListCellEditor, komponentu wywodzącego się z TCustomComboBox. Lista wyświetlanych wartości jest wypełniana na jeden z dwóch sposobów, w zależności od metody użytej do wyboru stylu edytora.
952862
953- 1. W przypadku używania kolumn niestandardowych programiści mogą wprowadzić listę wartości za pomocą właściwości PickList kolumny. [DLA POCZĄTKUJĄCYCH: TODO: dokładna procedura edycji listy]
954- 2. W OnSelectEditor programiści pobierają instancję TPickListCellEditor za pomocą funkcji EditorByStyle(cbsPickList). Zobacz tutaj przykład
863+1. W przypadku używania kolumn niestandardowych programiści mogą wprowadzić listę wartości za pomocą właściwości PickList kolumny. \[DLA POCZĄTKUJĄCYCH: TODO: dokładna procedura edycji listy\]
864+2. W OnSelectEditor programiści pobierają instancję TPickListCellEditor za pomocą funkcji EditorByStyle(cbsPickList). Zobacz tutaj przykład
955865
956- Wartość w siatce TStringGrid automatycznie odzwierciedla wybraną wartość. W razie potrzeby programista może wykryć moment wybrania wartości, zapisując procedurę obsługi zdarzenia dla zdarzenia OnPickListSelect siatki, dzięki czemu można podjąć dodatkowe kroki (na przykład w celu przetworzenia nowej wartości). TODO: powiązanie z OnEditingDone.
866+Wartość w siatce TStringGrid automatycznie odzwierciedla wybraną wartość. W razie potrzeby programista może wykryć moment wybrania wartości, zapisując procedurę obsługi zdarzenia dla zdarzenia OnPickListSelect siatki, dzięki czemu można podjąć dodatkowe kroki (na przykład w celu przetworzenia nowej wartości). TODO: powiązanie z OnEditingDone.
957867
958- * **cbsCheckboxColumn**
868+- **cbsCheckboxColumn**
959869
960- Może to być przydatne, gdy zawartość danych powiązana z kolumną jest ograniczona do pary wartości, na przykład tak-nie, prawda-fałsz, włącz-wyłącz, 1-0 itp. Zamiast zmuszać użytkownika do wpisania wartości dla tego rodzaju danych w StringCellEditor lub aby wybrać jedną wartość z listy, cbsCheckboxColumn służy do modyfikowania danych kolumny za pomocą reprezentacji pola wyboru, którą użytkownik może przełączać za pomocą kliknięcia myszą lub wciskając klawisz spacji (jeśli kolumna zawierająca pole wyboru jest zaznaczona i jeśli StringGrid jest edytowalny).
961- Pobieranie lub ustawianie wartości pola wyboru w komórce odbywa się w następujący sposób:
962-```
870+
871+Może to być przydatne, gdy zawartość danych powiązana z kolumną jest ograniczona do pary wartości, na przykład tak-nie, prawda-fałsz, włącz-wyłącz, 1-0 itp. Zamiast zmuszać użytkownika do wpisania wartości dla tego rodzaju danych w StringCellEditor lub aby wybrać jedną wartość z listy, cbsCheckboxColumn służy do modyfikowania danych kolumny za pomocą reprezentacji pola wyboru, którą użytkownik może przełączać za pomocą kliknięcia myszą lub wciskając klawisz spacji (jeśli kolumna zawierająca pole wyboru jest zaznaczona i jeśli StringGrid jest edytowalny).
872+
873+Pobieranie lub ustawianie wartości pola wyboru w komórce odbywa się w następujący sposób:
874+
875+``` pascal
963876StringGrid1.Cell[x,y]:='Z';
964877```
965878
966- gdzie Z należy zastąpić przez _0_ dla niezaznaczonego, _1_ dla zaznaczonego i pusty ciąg dla wyszarzonego. Zauważ, że każda wartość (string) inna niż _0_ i _1_ będzie wyświetlana jako szare pole wyboru.
879+
880+gdzie Z należy zastąpić przez *0* dla niezaznaczonego, *1* dla zaznaczonego i pusty ciąg dla wyszarzonego. Zauważ, że każda wartość (string) inna niż *0* i *1* będzie wyświetlana jako szare pole wyboru.
967881
968- Jeśli właściwość ButtonStyle kolumny jest ustawiona na cbsAuto, a DBGrid wykryje, że pole powiązane z kolumną jest polem logicznym, wówczas siatka automatycznie użyje tego stylu edytora. Ten automatyczny wybór można wyłączyć lub włączyć za pomocą właściwości OptionsExtra DBGrid; ustawienie elementu dgeCheckboxColumn na wartość False wyłącza tą funkcję.
882+
883+Jeśli właściwość ButtonStyle kolumny jest ustawiona na cbsAuto, a DBGrid wykryje, że pole powiązane z kolumną jest polem logicznym, wówczas siatka automatycznie użyje tego stylu edytora. Ten automatyczny wybór można wyłączyć lub włączyć za pomocą właściwości OptionsExtra DBGrid; ustawienie elementu dgeCheckboxColumn na wartość False wyłącza tą funkcję.
969884
970- Wartości używane do rozpoznawania stanów zaznaczonych lub niezaznaczonych są ustawiane we właściwościach kolumny ValueChecked i ValueUnchecked.
885+
886+Wartości używane do rozpoznawania stanów zaznaczonych lub niezaznaczonych są ustawiane we właściwościach kolumny ValueChecked i ValueUnchecked.
971887
972- W dowolnym momencie wartość pola może mieć od jednego do trzech stanów: Unchecked (niezaznaczone), Checked (zaznaczone) lub Grayed (wyszarzone). Wewnętrznie te stany są identyfikowane przez następujące wartości typu TDBGridCheckBoxState: gcbpUnChecked, gcbpChecked i gcbpGrayed.
888+
889+W dowolnym momencie wartość pola może mieć od jednego do trzech stanów: Unchecked (niezaznaczone), Checked (zaznaczone) lub Grayed (wyszarzone). Wewnętrznie te stany są identyfikowane przez następujące wartości typu TDBGridCheckBoxState: gcbpUnChecked, gcbpChecked i gcbpGrayed.
973890
974- Ten styl edytora nie używa prawdziwych komponentów TCheckbox do obsługi interakcji użytkownika: wizualną reprezentację zapewniają trzy wbudowane obrazy bitmapowe, które odpowiadają możliwym stanom pola wyboru. Użyte mapy bitowe można dostosować, pisząc procedurę obsługi zdarzenia DBGrid OnUserCheckboxBitmap; program obsługi tego zdarzenia otrzymuje stan pola wyboru w parametrze CheckedState typu TDBGridCheckboxState oraz parametr mapy bitowej, którego programista może użyć do określenia niestandardowych map bitowych.
891+
892+Ten styl edytora nie używa prawdziwych komponentów TCheckbox do obsługi interakcji użytkownika: wizualną reprezentację zapewniają trzy wbudowane obrazy bitmapowe, które odpowiadają możliwym stanom pola wyboru. Użyte mapy bitowe można dostosować, pisząc procedurę obsługi zdarzenia DBGrid OnUserCheckboxBitmap; program obsługi tego zdarzenia otrzymuje stan pola wyboru w parametrze CheckedState typu TDBGridCheckboxState oraz parametr mapy bitowej, którego programista może użyć do określenia niestandardowych map bitowych.
975893
976- * **cbsButtonColumn**
894+- **cbsButtonColumn**
977895
978- Ten styl edytora służy do wyświetlania przycisku w każdej komórce w kolumnie. Podobnie jak w przypadku cbsCheckboxColumn ten edytor nie używa prawdziwych przycisków, wygląd jest określony przez aktualny motyw zestawu widżetów.
896+
897+Ten styl edytora służy do wyświetlania przycisku w każdej komórce w kolumnie. Podobnie jak w przypadku cbsCheckboxColumn ten edytor nie używa prawdziwych przycisków, wygląd jest określony przez aktualny motyw zestawu widżetów.
979898
980- Użytkownik wie, jaki konkretny przycisk został naciśnięty, obsługując OnEditButtonClick w siatce i sprawdzając kolumnę i wiersz siatki. Zauważ, że w tym konkretnym przypadku zmienne col i row siatki nie identyfikują aktualnie zaznaczonej komórki, ale komórkę klikniętego przycisku. Po obsłużeniu zdarzenia OnEditButtonClick i jeśli użytkownik nie zmodyfikował col lub row siatki w tej procedurze obsługi, siatka automatycznie resetuje col i row, aby odzwierciedlić aktualnie wybraną komórkę. Podczas obsługi OnEditButtonClick bieżący wybór siatki jest dostępny w grid.Selection, który jest właściwością typu TRect, Left i Right reprezentują indeksy kolumn, Top i Bottom są indeksami wierszy.
899+
900+Użytkownik wie, jaki konkretny przycisk został naciśnięty, obsługując OnEditButtonClick w siatce i sprawdzając kolumnę i wiersz siatki. Zauważ, że w tym konkretnym przypadku zmienne col i row siatki nie identyfikują aktualnie zaznaczonej komórki, ale komórkę klikniętego przycisku. Po obsłużeniu zdarzenia OnEditButtonClick i jeśli użytkownik nie zmodyfikował col lub row siatki w tej procedurze obsługi, siatka automatycznie resetuje col i row, aby odzwierciedlić aktualnie wybraną komórkę. Podczas obsługi OnEditButtonClick bieżący wybór siatki jest dostępny w grid.Selection, który jest właściwością typu TRect, Left i Right reprezentują indeksy kolumn, Top i Bottom są indeksami wierszy.
981901
982- Podpis przycisku to odpowiedni ciąg string komórki.
902+
903+Podpis przycisku to odpowiedni ciąg string komórki.
983904
984905### Edycja siatek
985906
986-Efekt edycji jest różny w zależności od rodzaju użytej siatki, na przykład TStringGrid przechowuje edytowany tekst wewnętrznie, a TDBGrid wpływa na rekordy w zestawie danych (dataset). TDrawGrid nie wie, co zrobić z edytowanym tekstem, jeśli programista nie przejmie nad nim kontroli, jest on po prostu odrzucany.
987-Dla TDrawGrid (chociaż powinno to działać dla wszystkich klas siatki) w celu uzyskania dostępu do edytowanego tekstu, programista może użyć zdarzenia **OnSetEditText** , które jest wyzwalane za każdym razem, gdy użytkownik zmodyfikuje coś w edytorze, parametry _aCol_ i _aRow_ tego zdarzenia identyfikują edytowaną komórkę, parametr _Value_ przechowuje tekst, jest to zalecana metoda. Innym sposobem dostępu do edytowanego tekstu jest pobranie go bezpośrednio z edytora po zakończeniu procesu edycji za pomocą zdarzenia **OnEditingDone**. Można to osiągnąć, uzyskując dostęp do wewnętrznego edytora używanego do edycji, w tym przypadku domyślnego „String Cell Editor” (Komórkowy Edytor String). W tym celu istnieją dwie metody: Pierwsza polega na użyciu zdarzenia **OnSelectEditor** , gdzie parametr _Editor_ jest instancją, która będzie używana do edycji komórki, musisz zapisać tę instancję do zmiennej, na przykład TheEditor (typu _TSringCellEditor_), do późniejszego wykorzystania w **OnEditingDone**. Drugą alternatywą jest użycie metody siatki **EditorByStyle** , ta metoda akceptuje „styl edytora” jako parametr i zwraca instancję edytora odpowiadającego temu stylowi. W naszym przypadku wiedząc, że styl cbsAuto zwraca domyślny edytor komórek, w module obsługi zdarzenia **OnEditingDone** możemy bezpośrednio użyć TheEditor := Grid.EditorByStyle(cbsAuto). Następnie możesz pobrać tekst za pomocą _TheEditor.Text_. Jeśli zastosujesz tę metodę, zauważ, że „z wielką mocą wiąże się wielka odpowiedzialność”.
907+Efekt edycji jest różny w zależności od rodzaju użytej siatki, na przykład TStringGrid przechowuje edytowany tekst wewnętrznie, a TDBGrid wpływa na rekordy w zestawie danych (dataset). TDrawGrid nie wie, co zrobić z edytowanym tekstem, jeśli programista nie przejmie nad nim kontroli, jest on po prostu odrzucany.\
908+Dla TDrawGrid (chociaż powinno to działać dla wszystkich klas siatki) w celu uzyskania dostępu do edytowanego tekstu, programista może użyć zdarzenia **OnSetEditText**, które jest wyzwalane za każdym razem, gdy użytkownik zmodyfikuje coś w edytorze, parametry *aCol* i *aRow* tego zdarzenia identyfikują edytowaną komórkę, parametr *Value* przechowuje tekst, jest to zalecana metoda. Innym sposobem dostępu do edytowanego tekstu jest pobranie go bezpośrednio z edytora po zakończeniu procesu edycji za pomocą zdarzenia **OnEditingDone**. Można to osiągnąć, uzyskując dostęp do wewnętrznego edytora używanego do edycji, w tym przypadku domyślnego „String Cell Editor” (Komórkowy Edytor String). W tym celu istnieją dwie metody: Pierwsza polega na użyciu zdarzenia **OnSelectEditor**, gdzie parametr *Editor* jest instancją, która będzie używana do edycji komórki, musisz zapisać tę instancję do zmiennej, na przykład TheEditor (typu *TSringCellEditor*), do późniejszego wykorzystania w **OnEditingDone**. Drugą alternatywą jest użycie metody siatki **EditorByStyle**, ta metoda akceptuje „styl edytora” jako parametr i zwraca instancję edytora odpowiadającego temu stylowi. W naszym przypadku wiedząc, że styl cbsAuto zwraca domyślny edytor komórek, w module obsługi zdarzenia **OnEditingDone** możemy bezpośrednio użyć TheEditor := Grid.EditorByStyle(cbsAuto). Następnie możesz pobrać tekst za pomocą *TheEditor.Text*. Jeśli zastosujesz tę metodę, zauważ, że „z wielką mocą wiąże się wielka odpowiedzialność”.
988909
989910#### Opcje i właściwości wpływające na edycję
990911
991-Zachowanie edycyjne jest kontrolowane przez szereg właściwości i opcji, praktycznie każde dostosowanie lub opcje, które wpływają na edycję, wymagają edytowalnej siatki, w przeciwnym razie takie dostosowanie może zostać zignorowane.
992-Na początku edytowalny stan siatek jest inny, dla TDrawGrid i TStringGrid edycja jest wyłączona, dla TDbGrid jest domyślnie włączona.
993-Właściwość **Options** zawiera kilka pozycji, które zajmują się edycją, są one opisane poniżej:
912+Zachowanie edycyjne jest kontrolowane przez szereg właściwości i opcji, praktycznie każde dostosowanie lub opcje, które wpływają na edycję, wymagają edytowalnej siatki, w przeciwnym razie takie dostosowanie może zostać zignorowane.\
913+Na początku edytowalny stan siatek jest inny, dla TDrawGrid i TStringGrid edycja jest wyłączona, dla TDbGrid jest domyślnie włączona.\
914+Właściwość **Options** zawiera kilka pozycji, które zajmują się edycją, są one opisane poniżej:\
915+***goEditing, dgEditing (w DbGrid)**. Ta opcja zmienia edytowalny stan siatki, można ją zmienić w czasie wykonywania, ponieważ jest zaznaczona, gdy edycja ma się rozpocząć.
994916
995- * **goEditing, dgEditing (w DbGrid)**. Ta opcja zmienia edytowalny stan siatki, można ją zmienić w czasie wykonywania, ponieważ jest zaznaczona, gdy edycja ma się rozpocząć.
996- * **goAlwaysShowEditor**. Zwykle edytor jest ukryty i staje się widoczny tylko wtedy, gdy jest potrzebny. Dzięki tej opcji edytor będzie widoczny przez cały czas, jeśli siatka nie jest edytowalna, opcja ta jest ignorowana, a edytor jest zawsze ukryty.
917+- **goAlwaysShowEditor**. Zwykle edytor jest ukryty i staje się widoczny tylko wtedy, gdy jest potrzebny. Dzięki tej opcji edytor będzie widoczny przez cały czas, jeśli siatka nie jest edytowalna, opcja ta jest ignorowana, a edytor jest zawsze ukryty.
997918
998919### Hint dla komórek
999920
1000-„Hint” to właściwość wyświetlająca wskazówkę, krótką notatkę lub podpowiedź dla kontrolki, nad którą umieścimy kursor myszy. Inna nazwa tego elementu to „Tooltip”. Nazwy spotykane w języku polskim to także „dymek” lub „chmurka”.
921+„Hint” to właściwość wyświetlająca wskazówkę, krótką notatkę lub podpowiedź dla kontrolki, nad którą umieścimy kursor myszy. Inna nazwa tego elementu to „Tooltip”. Nazwy spotykane w języku polskim to także „dymek” lub „chmurka”.
1001922
1002-Oprócz standardowej właściwości Hint dostępnej dla większości kontrolek, potomkowie TCustomGrid mogą wyświetlać specjalny dymek dla komórki, nad którą znajduje się kursor myszy. Ta funkcja jest kontrolowana przez opcje siatki **goCellHints** i **goTruncCellHints** (lub **dgCellHints** i **gdTruncCellHints** odpowiednio dla DBGrid):
923+Oprócz standardowej właściwości Hint dostępnej dla większości kontrolek, potomkowie TCustomGrid mogą wyświetlać specjalny dymek dla komórki, nad którą znajduje się kursor myszy. Ta funkcja jest kontrolowana przez opcje siatki **goCellHints** i **goTruncCellHints** (lub **dgCellHints** i **gdTruncCellHints** odpowiednio dla DBGrid):
1003924
1004- * **goCellHints** aktywuje zdarzenie **OnGetCellHint** w celu pobrania wyświetlanego tekstu dymku dla komórki określonej przez przekazane parametry. W przypadku TDrawGrid i TStringGrid podane są indeksy kolumn i wierszy, natomiast w przypadku TDBGrid tekst komórki może zostać wydobyty z pola przypisanego do określonego obiektu kolumny.
1005- * **goTruncCellHints** wyświetla dymek tylko wtedy, gdy tekst nie mieści się w komórce i jest obcięty; tekst podpowiedzi to nieobcięty tekst komórki. W Lazarusie 1.9+ ten tekst jest przekazywany do zdarzenia **OnGetCellHint** w celu dalszego doprecyzowania (np. wyświetlenie całego tekstu notatki w dymku). W przypadku skróconych tekstów komórek zaleca się również włączenie opcji **goCellEllipsis** (lub **dgCellEllipsis** dla DBGrid), która dodaje '...' do skróconego tekstu komórki.
925+- **goCellHints** aktywuje zdarzenie **OnGetCellHint** w celu pobrania wyświetlanego tekstu dymku dla komórki określonej przez przekazane parametry. W przypadku TDrawGrid i TStringGrid podane są indeksy kolumn i wierszy, natomiast w przypadku TDBGrid tekst komórki może zostać wydobyty z pola przypisanego do określonego obiektu kolumny.
926+- **goTruncCellHints** wyświetla dymek tylko wtedy, gdy tekst nie mieści się w komórce i jest obcięty; tekst podpowiedzi to nieobcięty tekst komórki. W Lazarusie 1.9+ ten tekst jest przekazywany do zdarzenia **OnGetCellHint** w celu dalszego doprecyzowania (np. wyświetlenie całego tekstu notatki w dymku). W przypadku skróconych tekstów komórek zaleca się również włączenie opcji **goCellEllipsis** (lub **dgCellEllipsis** dla DBGrid), która dodaje '...' do skróconego tekstu komórki.
1006927
1007-Jeśli siatka ma wartość w swojej standardowej właściwości **Hint** , wówczas właściwość **HintPriority** może być użyta do kontrolowania, w jaki sposób wszystkie te dymki mogą zostać połączone w jedno wyskakujące okienko:
928+Jeśli siatka ma wartość w swojej standardowej właściwości **Hint**, wówczas właściwość **HintPriority** może być użyta do kontrolowania, w jaki sposób wszystkie te dymki mogą zostać połączone w jedno wyskakujące okienko:
1008929
1009- * **chpAll** umieszcza tekst z właściwości Hint w pierwszym wierszu, dymek określony przez zdarzenie OnGetCellHint w drugim wierszu, a wskazówkę dotyczącą obciętych komórek w trzecim wierszu
1010- * **chpAllNoDefault** wyświetla tylko dymki dotyczące komórek podane przez zdarzenie OnGetCellHint i obcięte komórki.
1011- * **chpTruncOnly** wyświetla tylko dymki dotyczące obciętych komórek; to są ustawienia domyślne.
930+- **chpAll** umieszcza tekst z właściwości Hint w pierwszym wierszu, dymek określony przez zdarzenie OnGetCellHint w drugim wierszu, a wskazówkę dotyczącą obciętych komórek w trzecim wierszu
931+- **chpAllNoDefault** wyświetla tylko dymki dotyczące komórek podane przez zdarzenie OnGetCellHint i obcięte komórki.
932+- **chpTruncOnly** wyświetla tylko dymki dotyczące obciętych komórek; to są ustawienia domyślne.
1012933
1013-Ponadto standardowa właściwość siatki **ShowHint** musi być ustawiona na wartość True, aby wyświetlać dymki dotyczące komórek.
934+Ponadto standardowa właściwość siatki **ShowHint** musi być ustawiona na wartość True, aby wyświetlać dymki dotyczące komórek.
1014935
1015936## Grids w praktyce i przykłady
1016937
1017938### Skupienie komórki
1018939
1019-Wykonanie skupienia (focus) dla komórki w TStringGrid jest łatwe. Zwróć uwagę, że liczenie (zwykle w programowaniu) zaczyna się od zera, a nie od 1. Aby zrobić skupienie dla komórki w 10. rzędzie i 9. kolumnie, wykonaj:
1020-```
940+Wykonanie skupienia (focus) dla komórki w TStringGrid jest łatwe. Zwróć uwagę, że liczenie (zwykle w programowaniu) zaczyna się od zera, a nie od 1. Aby zrobić skupienie dla komórki w 10. rzędzie i 9. kolumnie, wykonaj:
941+
942+``` Pascal
1021943StringGrid1.Row := 9;
1022- StringGrid1.Col := 8;
944+StringGrid1.Col := 8;
1023945```
1024946
1025947### Przykład: Jak ustawić niestandardowy edytor komórek
1026948
1027-Zobacz lazarus/examples/gridexamples/gridcelleditor/gridcelleditor.lpi (począwszy od Lazarusa 1.2)
949+Zobacz lazarus/examples/gridexamples/gridcelleditor/gridcelleditor.lpi (począwszy od Lazarusa 1.2)
1028950
1029951#### Przykład: Jak dodać edytor przycisków
1030-```
952+
953+``` pascal
1031954// Warunkowo pokaż edytor przycisków w kolumnie o indeksie 1 lub 2, jeśli
1032- // komórka w kolumnie o indeksie 1 jest pusta
1033-
1034- procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer;
1035- var Editor: TWinControl);
1036- begin
1037- if (aCol = 1) or (aCol = 2) then
1038- if StringGrid1.Cells[1,aRow] = '' then
1039- begin
1040- Editor := StringGrid1.EditorByStyle(cbsEllipsis);
1041- end;
1042- end;
1043-
1044- // Uruchamianie akcji...
1045- procedure TForm1.StringGrid1EditButtonClick(Sender: TObject);
955+// komórka w kolumnie o indeksie 1 jest pusta
956+
957+procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer;
958+ var Editor: TWinControl);
959+begin
960+ if (aCol = 1) or (aCol = 2) then
961+ if StringGrid1.Cells[1,aRow] = '' then
1046962 begin
1047- if StringGrid1.Col = 1 then ShowMessage('kliknięto edytor kolumny 1');
1048- if StringGrid1.Col = 2 then ShowMessage('kliknięto edytor kolumny 2');
963+ Editor := StringGrid1.EditorByStyle(cbsEllipsis);
1049964 end;
965+ end;
966+
967+// Uruchamianie akcji...
968+procedure TForm1.StringGrid1EditButtonClick(Sender: TObject);
969+begin
970+ if StringGrid1.Col = 1 then ShowMessage('kliknięto edytor kolumny 1');
971+ if StringGrid1.Col = 2 then ShowMessage('kliknięto edytor kolumny 2');
972+end;
1050973```
1051974
1052975### Przykład: Praca z PickList, jak ustawić ją tylko do odczytu i jak wypełnić w czasie wykonywania
1053976
1054-Za pomocą zdarzenia OnSelectEditor w siatce można dostosować zachowanie edytora PickList (patrz styl przycisku cbsPickList). W kolejnym przykładzie edytor listy wyboru w kolumnie 1 został zmodyfikowany tak, że w nieparzystych wierszach użytkownik może wprowadzać wartości przez ręczne wpisanie, w parzystych wierszach wartości są ograniczone do tych zawartych na liście wyboru. Ten przykład pokazuje również, jak wypełnić listę różnymi wartościami w zależności od przetwarzanego wiersza.
1055-```
977+Za pomocą zdarzenia OnSelectEditor w siatce można dostosować zachowanie edytora PickList (patrz styl przycisku cbsPickList). W kolejnym przykładzie edytor listy wyboru w kolumnie 1 został zmodyfikowany tak, że w nieparzystych wierszach użytkownik może wprowadzać wartości przez ręczne wpisanie, w parzystych wierszach wartości są ograniczone do tych zawartych na liście wyboru. Ten przykład pokazuje również, jak wypełnić listę różnymi wartościami w zależności od przetwarzanego wiersza.
978+
979+``` pascal
1056980procedure TForm1.gridSelectEditor(Sender: TObject; aCol, aRow: Integer;
1057- var Editor: TWinControl);
1058- begin
1059- if aCol=1 then begin
1060- if (Editor is TCustomComboBox) then
1061- with Editor as TCustomComboBox do begin
1062- if (aRow mod 2=0) then
1063- Style := csDropDown
1064- else
1065- Style := csDropDownList;
1066- case aRow of
1067- 1:
1068- Items.CommaText := 'ONE,TWO,THREE,FOUR';
1069- 2:
1070- Items.CommaText := 'A,B,C,D,E';
1071- 3:
1072- Items.CommaText := 'MX,ES,NL,UK';
1073- 4:
1074- Items.CommaText := 'RED,GREEN,BLUE,YELLOW';
1075- end;
1076- end;
981+ var Editor: TWinControl);
982+begin
983+ if aCol=1 then begin
984+ if (Editor is TCustomComboBox) then
985+ with Editor as TCustomComboBox do begin
986+ if (aRow mod 2=0) then
987+ Style := csDropDown
988+ else
989+ Style := csDropDownList;
990+ case aRow of
991+ 1:
992+ Items.CommaText := 'ONE,TWO,THREE,FOUR';
993+ 2:
994+ Items.CommaText := 'A,B,C,D,E';
995+ 3:
996+ Items.CommaText := 'MX,ES,NL,UK';
997+ 4:
998+ Items.CommaText := 'RED,GREEN,BLUE,YELLOW';
999+ end;
10771000 end;
1078- end;
1001+ end;
1002+end;
10791003```
10801004
10811005### Wyrównywanie tekstu w StringGrids
10821006
1083-Ten kod pokazuje, jak używać różnych sposobów wyrównania tekstu w kolumnach 2 i 3.
1084-```
1007+Ten kod pokazuje, jak używać różnych sposobów wyrównania tekstu w kolumnach 2 i 3.
1008+
1009+``` pascal
10851010procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
1086- aState: TGridDrawState);
1087- var
1088- MyTextStyle: TTextStyle;
1089- begin
1090- if (aCol=2) or (aCol=3) then
1091- begin
1092- MyTextStyle := StringGrid1.Canvas.TextStyle;
1093- if aCol=2 then
1094- MyTextStyle.Alignment := taRightJustify
1095- else
1096- if aCol=3 then
1097- MyTextStyle.Alignment := taCenter;
1098- StringGrid1.Canvas.TextStyle := MyTextStyle;
1099- end;
1100- end;
1011+ aState: TGridDrawState);
1012+var
1013+ MyTextStyle: TTextStyle;
1014+begin
1015+ if (aCol=2) or (aCol=3) then
1016+ begin
1017+ MyTextStyle := StringGrid1.Canvas.TextStyle;
1018+ if aCol=2 then
1019+ MyTextStyle.Alignment := taRightJustify
1020+ else
1021+ if aCol=3 then
1022+ MyTextStyle.Alignment := taCenter;
1023+ StringGrid1.Canvas.TextStyle := MyTextStyle;
1024+ end;
1025+end;
11011026```
11021027
11031028### Wielowierszowy tekst w siatkach
11041029
1105-Ten przykład pokazuje, jak utworzyć tekst wielowierszowy w komórce [3,2]. Działa to tak samo dla DBGrid, gdzie OnPrepareCanvas ma parametry do radzenia sobie z TColumns, a stamtąd z TFields.
1106-```
1030+Ten przykład pokazuje, jak utworzyć tekst wielowierszowy w komórce \[3,2\]. Działa to tak samo dla DBGrid, gdzie OnPrepareCanvas ma parametry do radzenia sobie z TColumns, a stamtąd z TFields.
1031+
1032+``` pascal
11071033procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
1108- aState: TGridDrawState);
1109- var
1110- MyTextStyle: TTextStyle;
1111- begin
1112- if (aRow=2) or (aCol=3) then
1113- begin
1114- MyTextStyle := StringGrid1.Canvas.TextStyle;
1115- MyTextStyle.SingleLine := false;
1116- StringGrid1.Canvas.TextStyle := MyTextStyle;
1117- end;
1118- end;
1034+ aState: TGridDrawState);
1035+var
1036+ MyTextStyle: TTextStyle;
1037+begin
1038+ if (aRow=2) or (aCol=3) then
1039+ begin
1040+ MyTextStyle := StringGrid1.Canvas.TextStyle;
1041+ MyTextStyle.SingleLine := false;
1042+ StringGrid1.Canvas.TextStyle := MyTextStyle;
1043+ end;
1044+end;
11191045```
11201046
11211047### Weryfikacja wprowadzonych wartości
11221048
1123-Lazarus w wersji 0.9.29 wprowadza w StringGrid zdarzenie OnValidateEntry typu TValidateEntryEvent, które ma następującą deklarację:
1124-```
1049+Lazarus w wersji 0.9.29 wprowadza w StringGrid zdarzenie OnValidateEntry typu TValidateEntryEvent, które ma następującą deklarację:
1050+
1051+``` pascal
11251052type
1126- TValidateEntryEvent = procedure(sender: TObject; aCol, aRow: Integer; const OldValue: string; var NewValue: string) of object;
1127-```
1128-```
1129-aCol, aRow to współrzędne sprawdzanej komórki.
1130- OldValue to wartość, która znajdowała się w komórce cells[aCol, aRow] przed rozpoczęciem edycji.
1131- NewValue to wartość, która zostanie ostatecznie wstawiona do komórki cells[aCol, aRow].
1053+ TValidateEntryEvent = procedure(sender: TObject; aCol, aRow: Integer; const OldValue: string; var NewValue: string) of object;
11321054```
11331055
1134-Ze względu na sposób, w jaki działa StringGrid, ustawiając wartość komórki podczas edycji przez użytkownika (patrz zdarzenie OnSetEditText w siatce i metoda SetEditText), gdy wyzwalane jest zdarzenie OnValidateEntry, komórka zawiera już wprowadzoną wartość (prawidłową lub nie); za pomocą argumentów zdarzenia OldValue i NewValue wartość komórki może zostać zweryfikowana i zmieniona w razie potrzeby.
1056+`aCol, aRow to współrzędne sprawdzanej komórki.`\
1057+`OldValue to wartość, która znajdowała się w komórce cells[aCol, aRow] przed rozpoczęciem edycji.`\
1058+`NewValue to wartość, która zostanie ostatecznie wstawiona do komórki cells[aCol, aRow].`
11351059
1136-Zwykle sprawdzanie poprawności następuje, gdy użytkownik przeniósł się do innej komórki. Jeśli walidacja się nie powiedzie, pożądane jest, aby edytor komórek był widoczny/aktywny, aby wpisana wartość mogła zostać poprawiona przez użytkownika. Aby siatka wiedziała, że ​​walidacja nie powiodła się, należy zgłosić wyjątek. Siatka obsłuży wyjątek poprzez Application.HandleException i każdy ruch zostanie anulowany.
1060+Ze względu na sposób, w jaki działa StringGrid, ustawiając wartość komórki podczas edycji przez użytkownika (patrz zdarzenie OnSetEditText w siatce i metoda SetEditText), gdy wyzwalane jest zdarzenie OnValidateEntry, komórka zawiera już wprowadzoną wartość (prawidłową lub nie); za pomocą argumentów zdarzenia OldValue i NewValue wartość komórki może zostać zweryfikowana i zmieniona w razie potrzeby.
11371061
1138-Na przykład, załóżmy że komórka cell[1,1] powinna zawierać tylko wartości 'A' lub 'B', walidację można przeprowadzić za pomocą:
1139-```
1062+Zwykle sprawdzanie poprawności następuje, gdy użytkownik przeniósł się do innej komórki. Jeśli walidacja się nie powiedzie, pożądane jest, aby edytor komórek był widoczny/aktywny, aby wpisana wartość mogła zostać poprawiona przez użytkownika. Aby siatka wiedziała, że ​​walidacja nie powiodła się, należy zgłosić wyjątek. Siatka obsłuży wyjątek poprzez Application.HandleException i każdy ruch zostanie anulowany.
1063+
1064+Na przykład, załóżmy że komórka cell\[1,1\] powinna zawierać tylko wartości 'A' lub 'B', walidację można przeprowadzić za pomocą:
1065+
1066+``` pascal
11401067procedure TForm1.GridValidateEntry(sender: TObject; aCol,
1141- aRow: Integer; const OldValue: string; var NewValue: String);
1142- begin
1143- if (aCol=1) and (aRow=1) then begin
1144- if grid.Cells[aCol,aRow]<>'A') and grid.Cells[aCol,aRow]<>'B') then begin
1145- // ustaw nową prawidłową wartość, aby użytkownik mógł na przykład nacisnąć RETURN, aby kontynuować.
1146- NewValue := 'A';
1147- // inną opcją jest powrót do poprzedniej wartości komórki (która z założenia jest prawidłowa)
1148- // NewValue := OldValue;
1149- // Użyj EAbort zamiast innego przerwania typu Exception, aby uniknąć okna dialogowego
1150- // z fałszywym komunikatem błędu i odwrotnego debugowania
1151- raise EAbort.Create('Tylko A lub B są tutaj dozwolone');
1152- end else begin
1153- // jeśli nie zostanie zgłoszony żaden wyjątek, przyjmuje się, że wartość jest prawidłowa, ale
1154- // w razie potrzeby ostateczną wartość można jeszcze zmienić, wypełniając NewValue inną wartością
1155-
1156- // komputer wie lepiej :)
1157- if grid.Cells[1,1]='A' then
1158- NewValue := 'B'
1159- else
1160- NewValue := 'A';
1161- end;
1162- end;
1068+ aRow: Integer; const OldValue: string; var NewValue: String);
1069+begin
1070+ if (aCol=1) and (aRow=1) then begin
1071+ if grid.Cells[aCol,aRow]<>'A') and grid.Cells[aCol,aRow]<>'B') then begin
1072+ // ustaw nową prawidłową wartość, aby użytkownik mógł na przykład nacisnąć RETURN, aby kontynuować.
1073+ NewValue := 'A';
1074+ // inną opcją jest powrót do poprzedniej wartości komórki (która z założenia jest prawidłowa)
1075+ // NewValue := OldValue;
1076+ // Użyj EAbort zamiast innego przerwania typu Exception, aby uniknąć okna dialogowego
1077+ // z fałszywym komunikatem błędu i odwrotnego debugowania
1078+ raise EAbort.Create('Tylko A lub B są tutaj dozwolone');
1079+ end else begin
1080+ // jeśli nie zostanie zgłoszony żaden wyjątek, przyjmuje się, że wartość jest prawidłowa, ale
1081+ // w razie potrzeby ostateczną wartość można jeszcze zmienić, wypełniając NewValue inną wartością
1082+
1083+ // komputer wie lepiej :)
1084+ if grid.Cells[1,1]='A' then
1085+ NewValue := 'B'
1086+ else
1087+ NewValue := 'A';
11631088 end;
1089+ end;
1090+end;
11641091```
11651092
11661093### Sortowanie kolumn lub wierszy
11671094
1168-Właściwość ColumnClickSorts umożliwia automatyczne sortowanie siatki wtedy, gdy użytkownik kliknie nagłówek kolumny. Wielokrotne kliknięcie tej samej kolumny zmienia kolejność sortowania. Wyświetlane są obrazy domyślnego sortowania kolumn, które wskazują, która kolumna została kliknięta.
1095+Właściwość ColumnClickSorts umożliwia automatyczne sortowanie siatki wtedy, gdy użytkownik kliknie nagłówek kolumny. Wielokrotne kliknięcie tej samej kolumny zmienia kolejność sortowania. Wyświetlane są obrazy domyślnego sortowania kolumn, które wskazują, która kolumna została kliknięta.
11691096
1170-W kodzie możesz użyć metody SortColRow().
1097+W kodzie możesz użyć metody SortColRow().
11711098
1172-Pierwszy parametr, IsColumn, to wartość logiczna. Ustaw ją na:
1099+Pierwszy parametr, IsColumn, to wartość logiczna. Ustaw ją na:
11731100
1174- * True jeśli posortowana ma być kolumna
1175- * False jeśli posortowany ma zostać wiersz.
1101+- True jeśli posortowana ma być kolumna
1102+- False jeśli posortowany ma zostać wiersz.
11761103
1177-Drugi parametr, index, jest liczbą całkowitą:
1104+Drugi parametr, index, jest liczbą całkowitą:
11781105
1179- * Indeks wskazuje kolumnę lub wiersz do posortowania.
1106+- Indeks wskazuje kolumnę lub wiersz do posortowania.
11801107
1181-Ostatnie dwa parametry są opcjonalne, określają podzakres wierszy lub kolumn do sortowania.
1108+Ostatnie dwa parametry są opcjonalne, określają podzakres wierszy lub kolumn do sortowania.
11821109
1183- * FromIndex (od kolumny lub wiersza)
1184- * ToIndex (do kolumny lub wiersza)
1110+- FromIndex (od kolumny lub wiersza)
1111+- ToIndex (do kolumny lub wiersza)
11851112
1186-Jeśli ostatnie dwa parametry nie zostaną określone, sortowana jest cała kolumna lub wiersz.
1113+Jeśli ostatnie dwa parametry nie zostaną określone, sortowana jest cała kolumna lub wiersz.
11871114
1188-Sortowanie wykorzystuje algorytm QuickSort, można go zmienić, jeśli siatka potomna przesłoni metodę sort() i wywoła funkcję doCompareCells w celu porównania komórek.
1115+Sortowanie wykorzystuje algorytm QuickSort, można go zmienić, jeśli siatka potomna przesłoni metodę sort() i wywoła funkcję doCompareCells w celu porównania komórek.
11891116
1190-Domyślnie zawartość komórek sortowana jest jako ciągi string w kolejności rosnącej lub malejącej. Kolejność można wybrać za pomocą właściwości SortOrder. Domyślnie używana jest kolejność rosnąca.
1191-```
1117+Domyślnie zawartość komórek sortowana jest jako ciągi string w kolejności rosnącej lub malejącej. Kolejność można wybrać za pomocą właściwości SortOrder. Domyślnie używana jest kolejność rosnąca.
1118+
1119+``` pascal
11921120// Sortuj kolumnę 3 w kolejności rosnącej
1193- grid.SortColRow(true, 3);
1194-
1195- // Sortuj kolumnę 3 w kolejności malejącej, pomiń wiersze stałe (fixed) u góry
1196- grid.SortOrder := soDescending; // lub soAscending
1197- grid.SortColRow(true, 3, grid.FixedRows, grid.RowCount-1);
1198-```
1121+grid.SortColRow(true, 3);
11991122
1200-Do niestandardowego sortowania liczb, dat, stanów itp. StringGrid ma zdarzenie OnCompareCells, które użytkownicy mogą wykorzystać na przykład w ten sposób:
1123+// Sortuj kolumnę 3 w kolejności malejącej, pomiń wiersze stałe (fixed) u góry
1124+grid.SortOrder := soDescending; // lub soAscending
1125+grid.SortColRow(true, 3, grid.FixedRows, grid.RowCount-1);
12011126```
1127+
1128+Do niestandardowego sortowania liczb, dat, stanów itp. StringGrid ma zdarzenie OnCompareCells, które użytkownicy mogą wykorzystać na przykład w ten sposób:
1129+
1130+``` pascal
12021131procedure TForm1.GridCompareCells(Sender: TObject; ACol, ARow, BCol, BRow: Integer; var Result: integer);
1203- begin
1204- // Wynik będzie <0, =0 lub >0 dla normalnego sortowania.
1205- result := StrToIntDef(Grid.Cells[ACol,ARow],0)-StrToIntDef(Grid.Cells[BCol,BRow],0);
1206- //W przypadku odwrotnej kolejności, wystarczy zanegować wynik (np. bazując na SortOrder siatki).
1207- if StringGrid1.SortOrder = soDescending then
1208- result := -result;
1209- end;
1132+begin
1133+ // Wynik będzie <0, =0 lub >0 dla normalnego sortowania.
1134+ result := StrToIntDef(Grid.Cells[ACol,ARow],0)-StrToIntDef(Grid.Cells[BCol,BRow],0);
1135+ //W przypadku odwrotnej kolejności, wystarczy zanegować wynik (np. bazując na SortOrder siatki).
1136+ if StringGrid1.SortOrder = soDescending then
1137+ result := -result;
1138+end;
12101139```
12111140
1212-Możesz użyć OnCompareCells również wtedy, gdy automatyczne sortowanie kolumn jest włączone za pomocą właściwości ColumnClickSorts.
1141+Możesz użyć OnCompareCells również wtedy, gdy automatyczne sortowanie kolumn jest włączone za pomocą właściwości ColumnClickSorts.
12131142
12141143### Zastąp sortowanie automatyczne (ColumnClickSorts ustawione na False ). Unikaj niektórych kolumn. Pokaż strzałki sortowania w nagłówku kolumny
12151144
1216-(gdy ColumnClickSorts jest ustawione na False, to w nagłówku kolumny NIE są wyświetlane strzałki sortowania, a więc musimy ustawić strzałki.)
1217-```
1145+(gdy ColumnClickSorts jest ustawione na False, to w nagłówku kolumny NIE są wyświetlane strzałki sortowania, a więc musimy ustawić strzałki.)
1146+
1147+``` pascal
12181148procedure TForm1.StringGrid1HeaderClick(Sender: TObject; IsColumn: Boolean;
1219- Index: Integer);
1220- begin
1221- if isColumn then with StringGrid1 do
1222- begin
1223- col:=Index; // Wybierz kolumnę do sortowania
1224- if Tag = 0 then Tag :=-1 // Załóżmy, że dane w kolumnie są posortowane rosnąco
1225- else Tag := Tag * -1; // Używanie StringGrid1.Tag do przechowywania porządku sortowania
1226- // Pierwsze kliknięcie nagłówka posortuje kolumnę malejąco
1227-
1228- // Aktywuj CompareCells (aktywuj sortowanie)
1229- case Index of
1230- 0: col:=-1; // Nie sortuj kolumny 0 i nie pokazuj strzałki sortowania
1231- 1: SortColRow(True, Index); // Sortowanie odbędzie się w CompareCells zaraz po wykonaniu instrukcji
1232- 2: SortColRow(True, Index);
1233- 3: SortColRow(True, Index);
1234- 4: SortColRow(True, Index);
1235- 5: col:=-1; // Nie sortuj kolumny 5 i nie pokazuj strzałki sortowania
1236- end;
1237- end;
1149+ Index: Integer);
1150+begin
1151+ if isColumn then with StringGrid1 do
1152+ begin
1153+ col:=Index; // Wybierz kolumnę do sortowania
1154+ if Tag = 0 then Tag :=-1 // Załóżmy, że dane w kolumnie są posortowane rosnąco
1155+ else Tag := Tag * -1; // Używanie StringGrid1.Tag do przechowywania porządku sortowania
1156+ // Pierwsze kliknięcie nagłówka posortuje kolumnę malejąco
1157+
1158+ // Aktywuj CompareCells (aktywuj sortowanie)
1159+ case Index of
1160+ 0: col:=-1; // Nie sortuj kolumny 0 i nie pokazuj strzałki sortowania
1161+ 1: SortColRow(True, Index); // Sortowanie odbędzie się w CompareCells zaraz po wykonaniu instrukcji
1162+ 2: SortColRow(True, Index);
1163+ 3: SortColRow(True, Index);
1164+ 4: SortColRow(True, Index);
1165+ 5: col:=-1; // Nie sortuj kolumny 5 i nie pokazuj strzałki sortowania
12381166 end;
1239-
1240- // Compare zwraca jedną z następujących wartości:
1241- // jeśli A<B zwraca: -1 ( Rosnąco )
1242- // jeśli A=B zwraca: 0
1243- // jeśli A>B zwraca: 1 ( Malejąco)
1244-
1245- // Jak sortować: Text, Integer, Float, DateTime:
1246-
1247- procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
1248- BRow: Integer; var Result: integer);
1249-
1250- function CompareTextAsText: Integer; // Text
1251- begin
1252- CompareText(Cells[ACol,ARow], Cells[BCol,BRow]);
1253- end;
1254-
1255- function CompareTextAsInteger: Integer;
1256- var i1,i2:Integer;
1257- begin
1258- if TryStrToInt(StringGrid1.Cells[ACol,ARow],i1) and // Integer
1259- TryStrToInt(StringGrid1.Cells[BCol,BRow],i2) then
1260- Result := CompareValue(i1, i2)
1261- else Exit(0);
1262- end;
1263-
1264- function CompareTextAsFloat: Integer; // Float
1265- var f1,f2:Extended;
1266- begin
1267- if TryStrToFloat(StringGrid1.Cells[ACol,ARow],f1) and
1268- TryStrToFloat(StringGrid1.Cells[BCol,BRow],f2) then
1269- Result := CompareValue(f1, f2)
1270- else Exit(0);
1271- end;
1272-
1273- function CompareTextAsDateTime: Integer; // DateTime
1274- var
1275- D1, D2 : TDateTime;
1276- begin
1277- if Trim(StringGrid1.Cells[ACol,ARow]) <> Trim(StringGrid1.Cells[BCol,BRow]) then
1278- begin
1279- if trim(StringGrid1.Cells[ACol,ARow]) = '' then Exit(1);
1280- if Trim(StringGrid1.Cells[BCol,BRow]) = '' then Exit(-1);
1281- end
1282- else Exit(0);
1283-
1284- if TryStrToDate(StringGrid1.Cells[ACol,ARow], D1, 'yy/mm/dd') and
1285- TryStrToDate(StringGrid1.Cells[BCol,BRow], D2, 'yy/mm/dd') then
1286- Result := CompareDateTime(D1, D2)
1287- else Exit(0);
1288- end;
1289-
1290- begin // Nie rób tutaj nic więcej, sortowanie może być zrobione niepoprawnie
1291- With StringGrid1 do
1292- begin
1293- case ACol of
1294- 0 : ; // Nie sortuj kolumny 0
1295- 1 : Result := CompareTextAsText; // Text
1296- 2 : Result := CompareTextAsInteger; // Integer
1297- 3 : Result := CompareTextAsFloat; // Float
1298- 4 : Result := CompareTextAsDateTime; // DateTime
1299- end; {Case}
1300- end;
1301- if StringGrid1.Tag = -1 then Result := -Result; // Zmień kolejność sortowania
1302- end;
1303-
1304- // DrawCell załatwia sprawę, poprzednie obrazy strzałek są usuwane:
1305- procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
1306- aRect: TRect; aState: TGridDrawState);
1307-
1308- procedure DrawArrow(ImgIndex:Integer); // Potrzebujesz obrazów strzałek w górę/w dół w ImageList
1309- begin
1310- with StringGrid1 do
1311- TitleImageList.Draw(Canvas, // TitleImageList z StringGrid
1312- ARect.Right - TitleImageList.Width,
1313- (ARect.Bottom - ARect.Top - TitleImageList.Height) div 2 + 2, // Położenie strzałki można regulować.
1314- ImgIndex );
1315- end;
1167+ end;
1168+end;
1169+
1170+// Compare zwraca jedną z następujących wartości:
1171+// jeśli A<B zwraca: -1 ( Rosnąco )
1172+// jeśli A=B zwraca: 0
1173+// jeśli A>B zwraca: 1 ( Malejąco)
1174+
1175+// Jak sortować: Text, Integer, Float, DateTime:
1176+
1177+procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
1178+ BRow: Integer; var Result: integer);
1179+
1180+ function CompareTextAsText: Integer; // Text
1181+ begin
1182+ CompareText(Cells[ACol,ARow], Cells[BCol,BRow]);
1183+ end;
1184+
1185+ function CompareTextAsInteger: Integer;
1186+ var i1,i2:Integer;
1187+ begin
1188+ if TryStrToInt(StringGrid1.Cells[ACol,ARow],i1) and // Integer
1189+ TryStrToInt(StringGrid1.Cells[BCol,BRow],i2) then
1190+ Result := CompareValue(i1, i2)
1191+ else Exit(0);
1192+ end;
1193+
1194+ function CompareTextAsFloat: Integer; // Float
1195+ var f1,f2:Extended;
1196+ begin
1197+ if TryStrToFloat(StringGrid1.Cells[ACol,ARow],f1) and
1198+ TryStrToFloat(StringGrid1.Cells[BCol,BRow],f2) then
1199+ Result := CompareValue(f1, f2)
1200+ else Exit(0);
1201+ end;
1202+
1203+ function CompareTextAsDateTime: Integer; // DateTime
1204+ var
1205+ D1, D2 : TDateTime;
1206+ begin
1207+ if Trim(StringGrid1.Cells[ACol,ARow]) <> Trim(StringGrid1.Cells[BCol,BRow]) then
13161208 begin
1317- if Col > 0 then // W tym demo nie ma strzałek w kolumnie 0
1318- if (ARow = 0) and // Załóżmy, że wiersz 0 jest wierszem tytułu
1319- Assigned(TitleImageList) then // Potrzebujesz strzałek w górę/w dół w ImageList
1320- case Columns.Items[aCol].Tag of // Użyj właściwości Tag kolumny jako indeksu strzałki rosnąco/malejąco
1321- -1: DrawArrow(1); // Zastąp swoim indeksem strzałki w dół
1322- 0: DrawArrow(-1); // Usuń poprzedni obraz
1323- 1: DrawArrow(2); // Zastąp swoim indeksem strzałki w górę
1324- end;
1325- end;
1209+ if trim(StringGrid1.Cells[ACol,ARow]) = '' then Exit(1);
1210+ if Trim(StringGrid1.Cells[BCol,BRow]) = '' then Exit(-1);
1211+ end
1212+ else Exit(0);
1213+
1214+ if TryStrToDate(StringGrid1.Cells[ACol,ARow], D1, 'yy/mm/dd') and
1215+ TryStrToDate(StringGrid1.Cells[BCol,BRow], D2, 'yy/mm/dd') then
1216+ Result := CompareDateTime(D1, D2)
1217+ else Exit(0);
1218+ end;
1219+
1220+begin // Nie rób tutaj nic więcej, sortowanie może być zrobione niepoprawnie
1221+ With StringGrid1 do
1222+ begin
1223+ case ACol of
1224+ 0 : ; // Nie sortuj kolumny 0
1225+ 1 : Result := CompareTextAsText; // Text
1226+ 2 : Result := CompareTextAsInteger; // Integer
1227+ 3 : Result := CompareTextAsFloat; // Float
1228+ 4 : Result := CompareTextAsDateTime; // DateTime
1229+ end; {Case}
1230+ end;
1231+ if StringGrid1.Tag = -1 then Result := -Result; // Zmień kolejność sortowania
1232+end;
1233+
1234+// DrawCell załatwia sprawę, poprzednie obrazy strzałek są usuwane:
1235+procedure TForm1.StringGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
1236+ aRect: TRect; aState: TGridDrawState);
1237+
1238+ procedure DrawArrow(ImgIndex:Integer); // Potrzebujesz obrazów strzałek w górę/w dół w ImageList
1239+ begin
1240+ with StringGrid1 do
1241+ TitleImageList.Draw(Canvas, // TitleImageList z StringGrid
1242+ ARect.Right - TitleImageList.Width,
1243+ (ARect.Bottom - ARect.Top - TitleImageList.Height) div 2 + 2, // Położenie strzałki można regulować.
1244+ ImgIndex );
1245+ end;
1246+begin
1247+ if Col > 0 then // W tym demo nie ma strzałek w kolumnie 0
1248+ if (ARow = 0) and // Załóżmy, że wiersz 0 jest wierszem tytułu
1249+ Assigned(TitleImageList) then // Potrzebujesz strzałek w górę/w dół w ImageList
1250+ case Columns.Items[aCol].Tag of // Użyj właściwości Tag kolumny jako indeksu strzałki rosnąco/malejąco
1251+ -1: DrawArrow(1); // Zastąp swoim indeksem strzałki w dół
1252+ 0: DrawArrow(-1); // Usuń poprzedni obraz
1253+ 1: DrawArrow(2); // Zastąp swoim indeksem strzałki w górę
1254+ end;
1255+end;
13261256```
13271257
13281258### Podświetlenie wybranych komórek kolumny i wiersza
13291259
1330-W rewizji 40276 Lazarusa dodano opcję (**gdRowHighlight**), która działa podobnie do **goRowSelect** , ale używa jaśniejszego koloru do zaznaczania, a prostokąt skupienia wskazuje zaznaczoną komórką, a nie cały rząd. Działa to dobrze w przypadku wierszy, ale co z kolumnami?.
1260+W rewizji 40276 Lazarusa dodano opcję (**gdRowHighlight**), która działa podobnie do **goRowSelect**, ale używa jaśniejszego koloru do zaznaczania, a prostokąt skupienia wskazuje zaznaczoną komórką, a nie cały rząd. Działa to dobrze w przypadku wierszy, ale co z kolumnami?.
13311261
1332-Ta sekcja przedstawia sposób podświetlania kolumn, wierszy lub obu (przykład podświetlający tylko nagłówki kolumn i wierszy można znaleźć w lazarus/examples/gridexamples/spreadsheet, ten praktyczny poradnik jest tak naprawdę rozszerzeniem tego przykładu). Wykorzystywane są dwa zdarzenia siatki: **OnBeforeSelection** i **OnPrepareCanvas** , a rysowanie nie jest konieczne.
1262+Ta sekcja przedstawia sposób podświetlania kolumn, wierszy lub obu (przykład podświetlający tylko nagłówki kolumn i wierszy można znaleźć w lazarus/examples/gridexamples/spreadsheet, ten praktyczny poradnik jest tak naprawdę rozszerzeniem tego przykładu). Wykorzystywane są dwa zdarzenia siatki: **OnBeforeSelection** i **OnPrepareCanvas**, a rysowanie nie jest konieczne.
13331263
1334-Zdarzenie **OnBeforeSelection** jest wyzwalane, gdy zaznaczenie ma ulec zmianie. W tym zdarzeniu możemy się dowiedzieć, która komórka jest aktualnie zaznaczona i jaka komórka zostanie wybrana jako następna. Używamy tych informacji, aby unieważnić cały wiersz lub kolumnę zarówno dla starych, jak i nowych komórek. Gdy rozpocznie się następny cykl malowania, siatka zostanie poinstruowana, aby pomalować komórki należące do obszarów unieważnionych. Jednym z pierwszych kroków podczas malowania jest wywołanie zdarzenia **OnPrepareCanvas** (jeśli istnieje) w celu ustawienia domyślnych właściwości płótna. Używamy tego zdarzenia do ustawienia podświetlonego wiersza lub kolumny:
1335-```
1264+Zdarzenie **OnBeforeSelection** jest wyzwalane, gdy zaznaczenie ma ulec zmianie. W tym zdarzeniu możemy się dowiedzieć, która komórka jest aktualnie zaznaczona i jaka komórka zostanie wybrana jako następna. Używamy tych informacji, aby unieważnić cały wiersz lub kolumnę zarówno dla starych, jak i nowych komórek. Gdy rozpocznie się następny cykl malowania, siatka zostanie poinstruowana, aby pomalować komórki należące do obszarów unieważnionych. Jednym z pierwszych kroków podczas malowania jest wywołanie zdarzenia **OnPrepareCanvas** (jeśli istnieje) w celu ustawienia domyślnych właściwości płótna. Używamy tego zdarzenia do ustawienia podświetlonego wiersza lub kolumny:
1265+
1266+``` pascal
13361267procedure TForm1.gridBeforeSelection(Sender: TObject; aCol, aRow: Integer);
1337- begin
1338- // tutaj możemy zdecydować, czy chcemy podświetlać kolumny, wiersze, czy jedno i drugie
1339- // w tym przykładzie podświetlamy oba
1340-
1341- if Grid.Col<>aCol then
1342- begin
1343- // wykryto zmianę w bieżącej kolumnie
1344- grid.InvalidateCol(aCol); // unieważnia nową wybraną kolumnę komórek
1345- grid.InvalidateCol(grid.Col); // unieważnia bieżącą (będzie to „stara”) wybrana kolumna
1346- end;
1347- if Grid.Row<>aRow then
1348- begin
1349- grid.InvalidateRow(aRow); // unieważnia nowy wybrany wiersz komórki
1350- grid.InvalidateRow(grid.Row); // unieważnia bieżący (będzie to „stary”) wybrany wiersz
1351- end;
1352- end;
1353-
1354- procedure TForm1.gridPrepareCanvas(sender: TObject; aCol, aRow: Integer;
1355- aState: TGridDrawState);
1356- begin
1357- if gdFixed in aState then
1358- begin
1359- if (aCol=grid.Col) or (aRow=grid.Row) then
1360- grid.Canvas.Brush.Color := clInactiveCaption; // podświetliłoby to również nagłówki kolumn lub wierszy
1361- end else
1362- if gdFocused in aState then begin
1363- // zostawiamy w spokoju aktualnie wybraną/skupioną komórkę
1364- end else
1365- if (aCol=Grid.Col) or (aRow=grid.Row) then
1366- grid.Canvas.Brush.Color := clSkyBlue; // podświetl wiersze i kolumny kolorem clSkyBlue
1367- end;
1268+begin
1269+ // tutaj możemy zdecydować, czy chcemy podświetlać kolumny, wiersze, czy jedno i drugie
1270+ // w tym przykładzie podświetlamy oba
1271+
1272+ if Grid.Col<>aCol then
1273+ begin
1274+ // wykryto zmianę w bieżącej kolumnie
1275+ grid.InvalidateCol(aCol); // unieważnia nową wybraną kolumnę komórek
1276+ grid.InvalidateCol(grid.Col); // unieważnia bieżącą (będzie to „stara”) wybrana kolumna
1277+ end;
1278+ if Grid.Row<>aRow then
1279+ begin
1280+ grid.InvalidateRow(aRow); // unieważnia nowy wybrany wiersz komórki
1281+ grid.InvalidateRow(grid.Row); // unieważnia bieżący (będzie to „stary”) wybrany wiersz
1282+ end;
1283+end;
1284+
1285+procedure TForm1.gridPrepareCanvas(sender: TObject; aCol, aRow: Integer;
1286+ aState: TGridDrawState);
1287+begin
1288+ if gdFixed in aState then
1289+ begin
1290+ if (aCol=grid.Col) or (aRow=grid.Row) then
1291+ grid.Canvas.Brush.Color := clInactiveCaption; // podświetliłoby to również nagłówki kolumn lub wierszy
1292+ end else
1293+ if gdFocused in aState then begin
1294+ // zostawiamy w spokoju aktualnie wybraną/skupioną komórkę
1295+ end else
1296+ if (aCol=Grid.Col) or (aRow=grid.Row) then
1297+ grid.Canvas.Brush.Color := clSkyBlue; // podświetl wiersze i kolumny kolorem clSkyBlue
1298+end;
13681299```
13691300
13701301### Unikanie pustego miejsca po prawej stronie ostatniej kolumny
13711302
1372-Aby to osiągnąć, siatka musi być w trybie kolumnowym. Gdy właściwość siatki `AutoFillColumns` ma wartość `True`, puste miejsce jest dzielone przez wszystkie kolumny, które mają niezerowy `SizePriority`. Dlatego powinieneś wykonać następujące kroki, aby wypełnić całą poziomą przestrzeń siatki:
1303+Aby to osiągnąć, siatka musi być w trybie kolumnowym. Gdy właściwość siatki `AutoFillColumns` ma wartość `True`, puste miejsce jest dzielone przez wszystkie kolumny, które mają niezerowy `SizePriority`. Dlatego powinieneś wykonać następujące kroki, aby wypełnić całą poziomą przestrzeń siatki:
13731304
1374- * Ustaw `AutoFillColumns` na `True`.
1375- * Korzystając z edytora kolumn, dodaj tyle kolumn, ile potrzebujesz.
1376- * Zaznacz każdą kolumnę w drzewie obiektów nad inspektorem obiektów i ustaw jej `SizePriority` na `0`.
1377- * Teraz zdecyduj, która kolumna zostanie poszerzona tak, że cała pusta przestrzeń zostanie wykorzystana. Ustaw `SizePriority` tej kolumny na `1`.
1305+- Ustaw `AutoFillColumns` na `True`.
1306+- Korzystając z edytora kolumn, dodaj tyle kolumn, ile potrzebujesz.
1307+- Zaznacz każdą kolumnę w drzewie obiektów nad inspektorem obiektów i ustaw jej `SizePriority` na `0`.
1308+- Teraz zdecyduj, która kolumna zostanie poszerzona tak, że cała pusta przestrzeń zostanie wykorzystana. Ustaw `SizePriority` tej kolumny na `1`.
13781309
13791310### Jak przewijać siatkę w czasie rzeczywistym (przesuwanie paska przewijania za pomocą myszy)
13801311
1381-If you scroll a Grid by moving the scrollbar with the mouse then the Grid per default is not moved "in realtime". Only after you release the mouse, the Grid "jumps" to its new position. You can enable a scrolling in "realtime" by adding Option `goThumbTracking`.
1312+If you scroll a Grid by moving the scrollbar with the mouse then the Grid per default is not moved "in realtime". Only after you release the mouse, the Grid "jumps" to its new position. You can enable a scrolling in "realtime" by adding Option `goThumbTracking`.
13821313
1383-Example:
1384-```
1385-StringGrid1.Options:=StringGrid1.Options + [goThumbTracking];
1314+Example:
1315+
1316+``` pascal
1317+ StringGrid1.Options:=StringGrid1.Options + [goThumbTracking];
13861318```
13871319
13881320Unfortunately this Option is neither documented in `<lazarus-installdir>\lcl\grids.pas` (ver 2.0.6) nor in <https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tgridoptions.html>
13891321
1390-
1391-Jeśli przewijasz siatkę, przesuwając pasek przewijania za pomocą myszy, domyślnie siatka nie jest przesuwana „w czasie rzeczywistym”. Dopiero po zwolnieniu myszy siatka „przeskakuje” do nowej pozycji. Możesz włączyć przewijanie w czasie rzeczywistym, dodając opcję `goThumbTracking`.
1322+Jeśli przewijasz siatkę, przesuwając pasek przewijania za pomocą myszy, domyślnie siatka nie jest przesuwana „w czasie rzeczywistym”. Dopiero po zwolnieniu myszy siatka „przeskakuje” do nowej pozycji. Możesz włączyć przewijanie w czasie rzeczywistym, dodając opcję `goThumbTracking`.
13921323
1393-Przykład:
1394-```
1395-StringGrid1.Options:=StringGrid1.Options + [goThumbTracking];
1324+Przykład:
1325+
1326+``` pascal
1327+ StringGrid1.Options:=StringGrid1.Options + [goThumbTracking];
13961328```
13971329
13981330Niestety ta opcja nie jest udokumentowana w `<lazarus-installdir>\lcl\grids.pas` (wersja 2.0.6) ani w <https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tgridoptions.html>
13991331
14001332### Jak zmienić rozmiar wiersza na podstawie zawartości komórek?
14011333
1402-Lacak w raporcie o błędzie [#38473](<https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/38473>) przedstawił następujący kod:
1403-```
1334+Lacak w raporcie o błędzie [\#38473](https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/38473) przedstawił następujący kod:
1335+
1336+``` pascal
1337+
14041338{ TStringGridHelper }
1405- TStringGridHelper = class helper for TStringGrid
1406- protected
1407- procedure AutoSizeRow(aRow: integer);
1408- end;
1409-
1410- { TStringGridHelper }
1411- procedure TStringGridHelper.AutoSizeRow(aRow: integer);
1412- var
1413- aCanvas: TCanvas;
1414- aCol, maxRowHeight:integer;
1415- aText: String;
1416- textRect: TRect;
1417- begin
1418- aCanvas := GetWorkingCanvas(Canvas);
1419- maxRowHeight := DefaultRowHeight;
1420- for aCol:=0 to ColCount-1 do begin
1421- aText := Cells[aCol,aRow];
1422- textRect := Rect(0, 0, ColWidths[aCol], MaxInt);
1423- DrawText(aCanvas.Handle, PChar(aText), Length(aText), textRect, DT_CALCRECT or DT_WORDBREAK);
1424- if maxRowHeight < textRect.Height then
1425- maxRowHeight := textRect.Height
1426- end;
1427- if aCanvas<>Canvas then FreeWorkingCanvas(aCanvas);
1428- RowHeights[aRow] := maxRowHeight+2;
1429- end;
1430-```
1339+ TStringGridHelper = class helper for TStringGrid
1340+ protected
1341+ procedure AutoSizeRow(aRow: integer);
1342+ end;
14311343
1432-Dodaj to gdzieś w swoim kodzie źródłowym, a następnie możesz zmieniać rozmiar wiersza tak, jakby procedura AutoSizeRow była częścią siatki, na przykład:
1344+{ TStringGridHelper }
1345+procedure TStringGridHelper.AutoSizeRow(aRow: integer);
1346+var
1347+ aCanvas: TCanvas;
1348+ aCol, maxRowHeight:integer;
1349+ aText: String;
1350+ textRect: TRect;
1351+begin
1352+ aCanvas := GetWorkingCanvas(Canvas);
1353+ maxRowHeight := DefaultRowHeight;
1354+ for aCol:=0 to ColCount-1 do begin
1355+ aText := Cells[aCol,aRow];
1356+ textRect := Rect(0, 0, ColWidths[aCol], MaxInt);
1357+ DrawText(aCanvas.Handle, PChar(aText), Length(aText), textRect, DT_CALCRECT or DT_WORDBREAK);
1358+ if maxRowHeight < textRect.Height then
1359+ maxRowHeight := textRect.Height
1360+ end;
1361+ if aCanvas<>Canvas then FreeWorkingCanvas(aCanvas);
1362+ RowHeights[aRow] := maxRowHeight+2;
1363+end;
14331364```
1434-// Zmień rozmiar wiersza o indeksie 2
1365+
1366+Dodaj to gdzieś w swoim kodzie źródłowym, a następnie możesz zmieniać rozmiar wiersza tak, jakby procedura AutoSizeRow była częścią siatki, na przykład:
1367+
1368+ // Zmień rozmiar wiersza o indeksie 2
14351369 grid.AutoSizeRow(2);
1436-```
14371370
14381371## DBGrids w praktyce i przykłady
14391372
14401373### Przykład: Jak ustawić edytor memo dla dbgrids
14411374
1442-Możesz oczywiście użyć innej kontrolki zamiast TMemo. Dostosuj według gustu. Zaadaptowane z [[1]](<http://forum.lazarus.freepascal.org/index.php?topic=3640.0>) (uproszczone użycie właściwości SelectedFieldRect, zobacz [[2]](<http://forum.lazarus.freepascal.org/index.php/topic,8713.msg43288.html#msg43288>))
1375+Możesz oczywiście użyć innej kontrolki zamiast TMemo. Dostosuj według gustu. Zaadaptowane z [1](http://forum.lazarus.freepascal.org/index.php?topic=3640.0) (uproszczone użycie właściwości SelectedFieldRect, zobacz [2](http://forum.lazarus.freepascal.org/index.php/topic,8713.msg43288.html#msg43288))
14431376
1444- * Umieść kontrolkę memo (lub jakąkolwiek kontrolkę, którą chcesz) na formularzu, ustaw dowolne właściwości i ustaw jej widoczność na False. Będzie ona używana podczas edycji komórki siatki. W tym przykładzie użyjemy GridCellMemo.
1445- * W zdarzeniu OnSelectEditor umieść następujący kod - dostosuj go, jeśli nie chcesz edytować kolumny logicznej 3, kolumny fizycznej 4:
1377+- Umieść kontrolkę memo (lub jakąkolwiek kontrolkę, którą chcesz) na formularzu, ustaw dowolne właściwości i ustaw jej widoczność na False. Będzie ona używana podczas edycji komórki siatki. W tym przykładzie użyjemy GridCellMemo.
1378+- W zdarzeniu OnSelectEditor umieść następujący kod - dostosuj go, jeśli nie chcesz edytować kolumny logicznej 3, kolumny fizycznej 4:
14461379
1447-```
1448-if (Column.DesignIndex = 3) then
1449- begin
1450- GridCellMemo.BoundsRect := DbGrid.SelectedFieldRect;
1451- GridCellMemo.Text:=Column.Field.AsString;
1452- Editor := GridCellMemo;
1453- end;
1380+``` pascal
1381+ if (Column.DesignIndex = 3) then
1382+ begin
1383+ GridCellMemo.BoundsRect := DbGrid.SelectedFieldRect;
1384+ GridCellMemo.Text:=Column.Field.AsString;
1385+ Editor := GridCellMemo;
1386+ end;
14541387```
14551388
1456- * Załóżmy, że Twoje źródło danych nazywa się Datasource1, a DBGrid nazywa się ResultsGrid. Następnie w zdarzeniu OnEditingDone dla GridCellMemo umieść następujące elementy:
1389+- Załóżmy, że Twoje źródło danych nazywa się Datasource1, a DBGrid nazywa się ResultsGrid. Następnie w zdarzeniu OnEditingDone dla GridCellMemo umieść następujące elementy:
14571390
1458-(Pierwotny post na forum wykorzystywał zdarzenie OnChange, które uruchamia się za każdym razem, gdy zawartość jest zmieniana. Użycie OnEditingDone jest uruchamiane dopiero po zakończeniu edycji przez użytkownika.)
1459-```
1460-if not(Datasource1.State in [dsEdit, dsInsert]) then
1461- Datasource1.Edit;
1462-
1463- Datasource1.DataSet.FieldByName(ResultsGrid.SelectedField.FieldName).AsString:=GridCellMemo.Text;
1391+(Pierwotny post na forum wykorzystywał zdarzenie OnChange, które uruchamia się za każdym razem, gdy zawartość jest zmieniana. Użycie OnEditingDone jest uruchamiane dopiero po zakończeniu edycji przez użytkownika.)
1392+
1393+``` pascal
1394+ if not(Datasource1.State in [dsEdit, dsInsert]) then
1395+ Datasource1.Edit;
1396+
1397+ Datasource1.DataSet.FieldByName(ResultsGrid.SelectedField.FieldName).AsString:=GridCellMemo.Text;
14641398```
14651399
1466-_Uwaga'_ Używanie normalnej kontrolki jako niestandardowego edytora ma wiele wad: nie zmieni rozmiaru ani nie zmieni położenia podczas zmiany rozmiaru kolumn lub przewijania siatki, musisz zadbać o modyfikację danych w siatce (jak wyjaśniono powyżej), nie działa poprawnie z DbGrids i zakłóca normalną nawigację po siatce za pomocą klawiatury. Siatka współdziała z edytorem za pomocą specjalnych komunikatów siatki, więc lepiej jest utworzyć podklasę kontrolki w celu zarządzania tymi komunikatami, jak wyjaśniono w rozdziale piątym [tego dokumentu](<http://www.freepascal.org/~michael/articles/grids/grids.pdf>).
1400+*Uwaga*' Używanie normalnej kontrolki jako niestandardowego edytora ma wiele wad: nie zmieni rozmiaru ani nie zmieni położenia podczas zmiany rozmiaru kolumn lub przewijania siatki, musisz zadbać o modyfikację danych w siatce (jak wyjaśniono powyżej), nie działa poprawnie z DbGrids i zakłóca normalną nawigację po siatce za pomocą klawiatury. Siatka współdziała z edytorem za pomocą specjalnych komunikatów siatki, więc lepiej jest utworzyć podklasę kontrolki w celu zarządzania tymi komunikatami, jak wyjaśniono w rozdziale piątym [tego dokumentu](http://www.freepascal.org/~michael/articles/grids/grids.pdf).
14671401
1468-**Uwaga** Jeśli masz więcej niż jedną siatkę na tej samej formie, użyj innego niestandardowego edytora dla każdej z nich: jeśli użyjesz tego samego elementu sterującego, wydarzą się złe rzeczy, ponieważ obie siatki będą próbowały użyć go jednocześnie.
1402+**Uwaga** Jeśli masz więcej niż jedną siatkę na tej samej formie, użyj innego niestandardowego edytora dla każdej z nich: jeśli użyjesz tego samego elementu sterującego, wydarzą się złe rzeczy, ponieważ obie siatki będą próbowały użyć go jednocześnie.
14691403
14701404### Przykład: Unikaj wyświetlania pól tekstowych jako „(Memo)” dla DBGrids
14711405
1472-When you use SQL statements like "Select * from A" you might see "(Memo)" instead of your content in a grid cell. There are many ways to fix this, but maybe the easiest is to change your statement "Select * from A" to "Select Cast(Column as TEXT) as Column from A". This is a common problem when you use a DBGrid component.
1406+When you use SQL statements like "Select * from A" you might see "(Memo)" instead of your content in a grid cell. There are many ways to fix this, but maybe the easiest is to change your statement "Select * from A" to "Select Cast(Column as TEXT) as Column from A". This is a common problem when you use a DBGrid component.
14731407
1474-Gdy używasz instrukcji SQL, takich jak „Select * From A”, możesz w komórkach siatki zobaczyć tekst „(Memo)” zamiast rzeczywistej zawartości. Jest wiele sposobów, aby to naprawić, ale być może najłatwiej jest zmienić instrukcję „Select * From A” na „Select Cast(Column as TEXT) as Column From A”. Jest to powszechny problem, gdy używasz komponentu DBGrid.
1475-```
1476-var
1477- sql : UTF8String;
1478- Queryu : TSQLQuery;
1479- .....
1480- sql := 'SELECT cast(Name as TEXT) as Name FROM Client';
1481- Queryu.SQL.Text:=sql;
1408+Gdy używasz instrukcji SQL, takich jak „Select * From A”, możesz w komórkach siatki zobaczyć tekst „(Memo)” zamiast rzeczywistej zawartości. Jest wiele sposobów, aby to naprawić, ale być może najłatwiej jest zmienić instrukcję „Select * From A” na „Select Cast(Column as TEXT) as Column From A”. Jest to powszechny problem, gdy używasz komponentu DBGrid.
1409+
1410+``` pascal
1411+ var
1412+ sql : UTF8String;
1413+ Queryu : TSQLQuery;
1414+.....
1415+ sql := 'SELECT cast(Name as TEXT) as Name FROM Client';
1416+ Queryu.SQL.Text:=sql;
14821417```
14831418
14841419### Sortowanie kolumn lub wierszy w DBGrid ze strzałkami sortowania w nagłówku kolumny
14851420
1486-To jest przykład, który sortuje **DBgrid** przy użyciu zdarzenia **OnTitleClick** oraz **TSQLQuery** i indeksów. Powinno to również działać w przypadku dowolnego zgodnego zestawu danych, takiego jak **TbufDataset**. Funkcja używa właściwości **Column.Tag** do przechowywania stanu sortowania dla każdej klikniętej kolumny, więc gdy wrócisz do już posortowanej kolumny, wybierze odpowiednią strzałkę sortowania do wyświetlenia.
1421+To jest przykład, który sortuje **DBgrid** przy użyciu zdarzenia **OnTitleClick** oraz **TSQLQuery** i indeksów. Powinno to również działać w przypadku dowolnego zgodnego zestawu danych, takiego jak **TbufDataset**. Funkcja używa właściwości **Column.Tag** do przechowywania stanu sortowania dla każdej klikniętej kolumny, więc gdy wrócisz do już posortowanej kolumny, wybierze odpowiednią strzałkę sortowania do wyświetlenia.
14871422
14881423**Warunki wstępne:**
14891424
1490- * Będzie potrzebny ImageList do przechowywania strzałek sortowania w górę/w dół. Przypisz swoją kontrolkę ImageList do właściwości **TitleImageList** dbgrid.
1491- * Upewnij się, że **[TSQLQuery.MaxIndexesCount](<http://lazarus-ccr.sourceforge.net/docs/fcl/sqldb/tsqlquery.maxindexescount.html> "doc:fcl/sqldb/tsqlquery.maxindexescount.html")** jest wystarczająco duży, aby pomieścić nowe indeksy, które będziesz tworzyć. W tym przykładzie ustawiłem je na 100.
1492- * Będzie także potrzebna prywatna zmienna do przechowywania ostatniej kolumny użytej do sortowania. W tym przykładzie nazwałem ją **FLastColumn**.
1425+- Będzie potrzebny ImageList do przechowywania strzałek sortowania w górę/w dół. Przypisz swoją kontrolkę ImageList do właściwości **TitleImageList** dbgrid.
1426+- Upewnij się, że **[[doc:fcl/sqldb/tsqlquery.maxindexescount.html|TSQLQuery.MaxIndexesCount]]** jest wystarczająco duży, aby pomieścić nowe indeksy, które będziesz tworzyć. W tym przykładzie ustawiłem je na 100.
1427+- Będzie także potrzebna prywatna zmienna do przechowywania ostatniej kolumny użytej do sortowania. W tym przykładzie nazwałem ją **FLastColumn**.
14931428
1494-W tym przykładzie użyty **TSQLQuery** nazywa się OpenQuery.
1429+W tym przykładzie użyty **TSQLQuery** nazywa się OpenQuery.
14951430
1496-[Template:Uwaga](</index.php?title=Template:Uwaga&action=edit&redlink=1> "Template:Uwaga \(page does not exist\)")
1431+Aby ponownie użyć komponentu **TSQLQuery** z inną instrukcją SQL, indeksy muszą zostać wyczyszczone po sortowaniu, w przeciwnym razie zostanie zgłoszony wyjątek podczas otwierania **TSQLQuery** z inną instrukcją SQL.
14971432
1498-Aby ponownie użyć komponentu **TSQLQuery** z inną instrukcją SQL, indeksy muszą zostać wyczyszczone po sortowaniu, w przeciwnym razie zostanie zgłoszony wyjątek podczas otwierania **TSQLQuery** z inną instrukcją SQL.
1499-```
1433+``` pascal
15001434FLastColumn: TColumn; //przechowuj ostatnią kolumnę siatki, według której sortowaliśmy
1501-
1502- procedure TSQLForm.ResultsGridTitleClick(Column: TColumn);
1503- const
1504- ImageArrowUp=0; //powinien pasować do obrazu na ImageList
1505- ImageArrowDown=1; //powinien pasować do obrazu na ImageList
1506- var
1507- ASC_IndexName, DESC_IndexName:string;
1508- procedure UpdateIndexes;
1509- begin
1510- // Upewnij się, że definicje indeksów są aktualne
1511- OpenQuery.IndexDefs.Updated:=false; {<<<--Ta linia jest krytyczna. IndexDefs.Update nie zostanie
1512- zaktualizowany, jeśli jest już ustawiony na True, co nastąpi w pierwszej posortowanej kolumnie.}
1513- Openquery.IndexDefs.Update;
1514- end;
1515- begin
1516- ASC_IndexName:='ASC_'+Column.FieldName;
1517- DESC_IndexName:='DESC_'+Column.FieldName;
1518- // indeksy nie mogą sortować typów binarnych, takich jak ftMemo, ftBLOB
1519- if (Column.Field.DataType in [ftBLOB,ftMemo,ftWideMemo]) then
1520- exit;
1521- // sprawdź, czy indeks sortowania rosnąco już istnieje dla tej kolumny.
1522- // jeśli nie, utwórz go
1523- if OpenQuery.IndexDefs.IndexOf(ASC_IndexName) = -1 then
1524- begin
1525- OpenQuery.AddIndex(ASC_IndexName,column.FieldName,[]);
1526- UpdateIndexes; //ensure index defs are up to date
1527- end;
1528- // sprawdź, czy indeks sortowania malejąco już istnieje dla tej kolumny.
1529- // jeśli nie, utwórz go
1530- if OpenQuery.IndexDefs.IndexOf(DESC_IndexName) = -1 then
1531- begin
1532- OpenQuery.AddIndex(DESC_IndexName,column.FieldName,[ixDescending]);
1533- UpdateIndexes; //ensure index defs are up to date
1534- end;
1535-
1536- // Użyj właściwości Tag kolumny, aby przełączyć ASC/DESC
1537- column.tag := not column.tag;
1538- if boolean(column.tag) then
1539- begin
1540- Column.Title.ImageIndex:=ImageArrowUp;
1541- Openquery.IndexName:=ASC_IndexName;
1542- end
1543- else
1544- begin
1545- Column.Title.ImageIndex:=ImageArrowDown;
1546- OpenQuery.IndexName:=DESC_IndexName;
1547- end;
1548- // Usuń strzałkę sortowania z poprzedniej kolumny, którą posortowaliśmy
1549- if (FLastColumn <> nil) and (FlastColumn <> Column) then
1550- FLastColumn.Title.ImageIndex:=-1;
1551- FLastColumn:=column;
1552- end;
1435+
1436+procedure TSQLForm.ResultsGridTitleClick(Column: TColumn);
1437+const
1438+ ImageArrowUp=0; //powinien pasować do obrazu na ImageList
1439+ ImageArrowDown=1; //powinien pasować do obrazu na ImageList
1440+var
1441+ ASC_IndexName, DESC_IndexName:string;
1442+ procedure UpdateIndexes;
1443+ begin
1444+ // Upewnij się, że definicje indeksów są aktualne
1445+ OpenQuery.IndexDefs.Updated:=false; {<<<--Ta linia jest krytyczna. IndexDefs.Update nie zostanie
1446+ zaktualizowany, jeśli jest już ustawiony na True, co nastąpi w pierwszej posortowanej kolumnie.}
1447+ Openquery.IndexDefs.Update;
1448+ end;
1449+begin
1450+ ASC_IndexName:='ASC_'+Column.FieldName;
1451+ DESC_IndexName:='DESC_'+Column.FieldName;
1452+ // indeksy nie mogą sortować typów binarnych, takich jak ftMemo, ftBLOB
1453+ if (Column.Field.DataType in [ftBLOB,ftMemo,ftWideMemo]) then
1454+ exit;
1455+ // sprawdź, czy indeks sortowania rosnąco już istnieje dla tej kolumny.
1456+ // jeśli nie, utwórz go
1457+ if OpenQuery.IndexDefs.IndexOf(ASC_IndexName) = -1 then
1458+ begin
1459+ OpenQuery.AddIndex(ASC_IndexName,column.FieldName,[]);
1460+ UpdateIndexes; //ensure index defs are up to date
1461+ end;
1462+ // sprawdź, czy indeks sortowania malejąco już istnieje dla tej kolumny.
1463+ // jeśli nie, utwórz go
1464+ if OpenQuery.IndexDefs.IndexOf(DESC_IndexName) = -1 then
1465+ begin
1466+ OpenQuery.AddIndex(DESC_IndexName,column.FieldName,[ixDescending]);
1467+ UpdateIndexes; //ensure index defs are up to date
1468+ end;
1469+
1470+ // Użyj właściwości Tag kolumny, aby przełączyć ASC/DESC
1471+ column.tag := not column.tag;
1472+ if boolean(column.tag) then
1473+ begin
1474+ Column.Title.ImageIndex:=ImageArrowUp;
1475+ Openquery.IndexName:=ASC_IndexName;
1476+ end
1477+ else
1478+ begin
1479+ Column.Title.ImageIndex:=ImageArrowDown;
1480+ OpenQuery.IndexName:=DESC_IndexName;
1481+ end;
1482+ // Usuń strzałkę sortowania z poprzedniej kolumny, którą posortowaliśmy
1483+ if (FLastColumn <> nil) and (FlastColumn <> Column) then
1484+ FLastColumn.Title.ImageIndex:=-1;
1485+ FLastColumn:=column;
1486+end;
15531487```
15541488
15551489### Wybieranie rekordów w DBGrid za pomocą pól wyboru
15561490
1557-Celem jest umożliwienie wyboru dowolnych rekordów w dbgrid za pomocą pól wyboru (CheckBox), siatka ma możliwość automatycznego wyświetlania pól wyboru po wykryciu pól logicznych, dla innych typów pól użytkownik może ręcznie wybrać styl przycisku cbsCheckboxColumn dla kolumny. W przypadku tego rodzaju kolumn wystarczy kliknąć pole wyboru, a zawartość pola zostanie odpowiednio zmodyfikowana.
1491+Celem jest umożliwienie wyboru dowolnych rekordów w dbgrid za pomocą pól wyboru (CheckBox), siatka ma możliwość automatycznego wyświetlania pól wyboru po wykryciu pól logicznych, dla innych typów pól użytkownik może ręcznie wybrać styl przycisku cbsCheckboxColumn dla kolumny. W przypadku tego rodzaju kolumn wystarczy kliknąć pole wyboru, a zawartość pola zostanie odpowiednio zmodyfikowana.
15581492
1559-Ale co się stanie, jeśli w naszym zbiorze danych nie będzie takiego dostępnego pola? Czy nie chcemy, aby siatka wchodziła w stan edycji po zaznaczeniu pola wyboru? Dodanie kolumny bez pola z ButtonStyle=cbsCheckboxColumn spowoduje wyświetlenie wszystkich pól wyboru wyszarzone i wyłączone, ponieważ nie ma pola połączonego z tą kolumną, a więc nie ma nic do modyfikacji. Ponieważ chcemy sami obsłużyć stan pola wyboru, musimy przechowywać stan gdzieś dla każdego rekordu. W tym celu możemy użyć klasy TBookmarkList (zdefiniowanej w module dbgrids.pas), gdzie właściwość CurrentRowSelected może poinformować, czy bieżący rekord jest zaznaczony, czy nie. Za pomocą zdarzeń dbgrid OnCellClick i OnUserCheckboxState możemy śledzić stan pola wyboru.
1493+Ale co się stanie, jeśli w naszym zbiorze danych nie będzie takiego dostępnego pola? Czy nie chcemy, aby siatka wchodziła w stan edycji po zaznaczeniu pola wyboru? Dodanie kolumny bez pola z ButtonStyle=cbsCheckboxColumn spowoduje wyświetlenie wszystkich pól wyboru wyszarzone i wyłączone, ponieważ nie ma pola połączonego z tą kolumną, a więc nie ma nic do modyfikacji. Ponieważ chcemy sami obsłużyć stan pola wyboru, musimy przechowywać stan gdzieś dla każdego rekordu. W tym celu możemy użyć klasy TBookmarkList (zdefiniowanej w module dbgrids.pas), gdzie właściwość CurrentRowSelected może poinformować, czy bieżący rekord jest zaznaczony, czy nie. Za pomocą zdarzeń dbgrid OnCellClick i OnUserCheckboxState możemy śledzić stan pola wyboru.
15601494
1561-Zauważ, że ta technika wymaga Lazarusa w rewizji r31148 lub nowszego, który implementuje zdarzenie OnUserCheckboxState.
1562-```
1495+Zauważ, że ta technika wymaga Lazarusa w rewizji r31148 lub nowszego, który implementuje zdarzenie OnUserCheckboxState.
1496+
1497+``` pascal
15631498...
1564- uses ..., dbgrids, stdctrls, ...
1565-
1566- type
1567-
1568- { TForm1 }
1569-
1570- TForm1 = class(TForm)
1571- ...
1572- procedure DBGrid1CellClick(Column: TColumn);
1573- procedure DBGrid1UserCheckboxState(sender: TObject; column: TColumn; var AState: TCheckboxState);
1574- procedure FormCreate(Sender: TObject);
1575- procedure FormDestroy(Sender: TObject);
1576- ...
1577- private
1578- RecList: TBookmarklist;
1579- ...
1580- end;
1581-
1582- procedure TForm1.DBGrid1CellClick(Column: TColumn);
1583- begin
1584- if Column.Index=1 then
1585- RecList.CurrentRowSelected := not RecList.CurrentRowSelected;
1586- end;
1587-
1588- procedure TForm1.FormCreate(Sender: TObject);
1589- begin
1590- RecList := TBookmarkList.Create(DbGrid1);
1591- end;
1592-
1593- procedure TForm1.FormDestroy(Sender: TObject);
1594- begin
1595- RecList.Free;
1596- end;
1597-
1598- procedure TForm1.DBGrid1UserCheckboxState(sender: TObject; column: TColumn; var AState: TCheckboxState);
1599- begin
1600- if RecList.CurrentRowSelected then
1601- AState := cbChecked
1602- else
1603- AState := cbUnchecked;
1604- end;
1499+uses ..., dbgrids, stdctrls, ...
1500+
1501+type
1502+
1503+ { TForm1 }
1504+
1505+ TForm1 = class(TForm)
1506+ ...
1507+ procedure DBGrid1CellClick(Column: TColumn);
1508+ procedure DBGrid1UserCheckboxState(sender: TObject; column: TColumn; var AState: TCheckboxState);
1509+ procedure FormCreate(Sender: TObject);
1510+ procedure FormDestroy(Sender: TObject);
1511+ ...
1512+ private
1513+ RecList: TBookmarklist;
1514+ ...
1515+ end;
1516+
1517+procedure TForm1.DBGrid1CellClick(Column: TColumn);
1518+begin
1519+ if Column.Index=1 then
1520+ RecList.CurrentRowSelected := not RecList.CurrentRowSelected;
1521+end;
1522+
1523+procedure TForm1.FormCreate(Sender: TObject);
1524+begin
1525+ RecList := TBookmarkList.Create(DbGrid1);
1526+end;
1527+
1528+procedure TForm1.FormDestroy(Sender: TObject);
1529+begin
1530+ RecList.Free;
1531+end;
1532+
1533+procedure TForm1.DBGrid1UserCheckboxState(sender: TObject; column: TColumn; var AState: TCheckboxState);
1534+begin
1535+ if RecList.CurrentRowSelected then
1536+ AState := cbChecked
1537+ else
1538+ AState := cbUnchecked;
1539+end;
16051540```
16061541
16071542### Przykład: Jak wyeksportować DBGrid do pliku tekstowego
16081543
1609-Istnieje kilka sposobów na utworzenie pliku tekstowego z zawartości DBGrid. Zwykle ludzie powiedzą ci, że zamiast myśleć o DBGrid jako kontenerze danych, należy spojrzeć na niego jak na połączony zestaw danych. Ale co się stanie, gdy reprezentacja tekstowa, którą chcesz uzyskać, musi pasować do wyglądu siatek, widoczności kolumn, szerokości lub kolejności? Jednym z rozwiązań jest użycie pakietu LazReport, który ma składnik przeznaczony specjalnie do tworzenia raportu z DbGrid, raport ten można następnie wyeksportować do kilku innych formatów, w tym do formatu tekstowego. Tutaj przedstawiono inne proste rozwiązanie, które może być również wykorzystane jako podstawa dla innych eksporterów formatów tekstowych, na przykład prostego eksportera html.
1610-```
1544+Istnieje kilka sposobów na utworzenie pliku tekstowego z zawartości DBGrid. Zwykle ludzie powiedzą ci, że zamiast myśleć o DBGrid jako kontenerze danych, należy spojrzeć na niego jak na połączony zestaw danych. Ale co się stanie, gdy reprezentacja tekstowa, którą chcesz uzyskać, musi pasować do wyglądu siatek, widoczności kolumn, szerokości lub kolejności? Jednym z rozwiązań jest użycie pakietu LazReport, który ma składnik przeznaczony specjalnie do tworzenia raportu z DbGrid, raport ten można następnie wyeksportować do kilku innych formatów, w tym do formatu tekstowego. Tutaj przedstawiono inne proste rozwiązanie, które może być również wykorzystane jako podstawa dla innych eksporterów formatów tekstowych, na przykład prostego eksportera html.
1545+
1546+``` pascal
16111547// aGrid: Siatka do wyeksportowania
1612- // lpp: Ilość linii na stronę. Bez nagłówka tekstu
1613- // pageBreak: Czy wstaw podział strony. Niektóre drukarki mogą użyć tego do rozpoczęcia nowej strony
1614- // wymagania: moduł LazUTF8
1615- function GridTextExporter(aGrid: TDbGrid; lpp: Integer; pageBreak:boolean): TStringList;
1616- const
1617- PX_PER_CHAR = 7;
1618-
1619- var
1620- Ds: TDataset;
1621- book: TBookMark;
1622- recCount: Integer;
1623- line: string;
1624- column: TColumn;
1625-
1626- function WidthToChar(aWidth: Integer): integer;
1627- begin
1628- result := trunc(aWidth/PX_PER_CHAR);
1629- end;
1630-
1631- procedure AddNext(theText: string; alignment: TAlignment);
1632- var
1633- width: Integer;
1634- begin
1635- if (line<>'') and (line<>#12) then
1636- line := line + ' ';
1637-
1638- width := WidthToChar(Column.Width);
1639-
1640- case Alignment of
1641- taRightJustify: line := line + UTF8PadLeft(theText, width);
1642- taCenter: line := line + UTF8PadCenter(theText, width);
1643- else line := line + UTF8PadRight(theText, width);
1644- end;
1645- end;
1646-
1647- procedure CollectHeader;
1648- begin
1649- AddNext(Column.Title.Caption, Column.Title.Alignment);
1650- end;
1651-
1652- procedure CollectField;
1653- var
1654- field: TField;
1655- begin
1656- field := Column.Field;
1657-
1658- if (field.DataType=ftMemo) and (dgDisplayMemoText in aGrid.Options) then
1659- AddNext(field.AsString, Column.Alignment)
1660- else if Field.DataType<>ftBlob then
1661- AddNext(field.DisplayText, Column.Alignment)
1662- else
1663- AddNext('(blob)', Column.Alignment);
1664- end;
1665-
1666- procedure LoopColumns(printingRecord: boolean);
1667- var
1668- c: TCollectionItem;
1669- begin
1670- if (not printingRecord) and pageBreak and (result.count>0) then
1671- line := #12
1672- else
1673- line := '';
1674- for c in aGrid.Columns do begin
1675- Column := TColumn(c);
1676- if Column.Visible and (Column.Width>=PX_PER_CHAR) then begin
1677- if printingRecord then CollectField
1678- else CollectHeader;
1679- end;
1680- end;
1681- result.add(line);
1682- end;
1683-
1684- begin
1685- result := TStringList.create;
1686- Ds := aGrid.DataSource.DataSet;
1687- Ds.DisableControls;
1688- book := Ds.GetBookmark;
1689- try
1690- Ds.First;
1691- recCount := 0;
1692- while not DS.EOF do begin
1693- if RecCount mod lpp = 0 then
1694- LoopColumns(false);
1695- LoopColumns(true);
1696- inc(recCount);
1697- Ds.Next;
1698- end;
1699- finally
1700- Ds.GotoBookmark(book);
1701- Ds.FreeBookmark(book);
1702- Ds.EnableControls;
1548+// lpp: Ilość linii na stronę. Bez nagłówka tekstu
1549+// pageBreak: Czy wstaw podział strony. Niektóre drukarki mogą użyć tego do rozpoczęcia nowej strony
1550+// wymagania: moduł LazUTF8
1551+function GridTextExporter(aGrid: TDbGrid; lpp: Integer; pageBreak:boolean): TStringList;
1552+const
1553+ PX_PER_CHAR = 7;
1554+
1555+var
1556+ Ds: TDataset;
1557+ book: TBookMark;
1558+ recCount: Integer;
1559+ line: string;
1560+ column: TColumn;
1561+
1562+ function WidthToChar(aWidth: Integer): integer;
1563+ begin
1564+ result := trunc(aWidth/PX_PER_CHAR);
1565+ end;
1566+
1567+ procedure AddNext(theText: string; alignment: TAlignment);
1568+ var
1569+ width: Integer;
1570+ begin
1571+ if (line<>'') and (line<>#12) then
1572+ line := line + ' ';
1573+
1574+ width := WidthToChar(Column.Width);
1575+
1576+ case Alignment of
1577+ taRightJustify: line := line + UTF8PadLeft(theText, width);
1578+ taCenter: line := line + UTF8PadCenter(theText, width);
1579+ else line := line + UTF8PadRight(theText, width);
1580+ end;
1581+ end;
1582+
1583+ procedure CollectHeader;
1584+ begin
1585+ AddNext(Column.Title.Caption, Column.Title.Alignment);
1586+ end;
1587+
1588+ procedure CollectField;
1589+ var
1590+ field: TField;
1591+ begin
1592+ field := Column.Field;
1593+
1594+ if (field.DataType=ftMemo) and (dgDisplayMemoText in aGrid.Options) then
1595+ AddNext(field.AsString, Column.Alignment)
1596+ else if Field.DataType<>ftBlob then
1597+ AddNext(field.DisplayText, Column.Alignment)
1598+ else
1599+ AddNext('(blob)', Column.Alignment);
1600+ end;
1601+
1602+ procedure LoopColumns(printingRecord: boolean);
1603+ var
1604+ c: TCollectionItem;
1605+ begin
1606+ if (not printingRecord) and pageBreak and (result.count>0) then
1607+ line := #12
1608+ else
1609+ line := '';
1610+ for c in aGrid.Columns do begin
1611+ Column := TColumn(c);
1612+ if Column.Visible and (Column.Width>=PX_PER_CHAR) then begin
1613+ if printingRecord then CollectField
1614+ else CollectHeader;
17031615 end;
17041616 end;
1705-```
1617+ result.add(line);
1618+ end;
17061619
1707-Aby skorzystać z tej funkcji, wystarczy wykonać to:
1620+begin
1621+ result := TStringList.create;
1622+ Ds := aGrid.DataSource.DataSet;
1623+ Ds.DisableControls;
1624+ book := Ds.GetBookmark;
1625+ try
1626+ Ds.First;
1627+ recCount := 0;
1628+ while not DS.EOF do begin
1629+ if RecCount mod lpp = 0 then
1630+ LoopColumns(false);
1631+ LoopColumns(true);
1632+ inc(recCount);
1633+ Ds.Next;
1634+ end;
1635+ finally
1636+ Ds.GotoBookmark(book);
1637+ Ds.FreeBookmark(book);
1638+ Ds.EnableControls;
1639+ end;
1640+end;
17081641```
1642+
1643+Aby skorzystać z tej funkcji, wystarczy wykonać to:
1644+
1645+``` pascal
17091646var
1710- L: TStringList;
1711- begin
1712- L := GridTextExporter(grid, 80, true);
1713- L.SaveToFile('grid.txt');
1714- L.Free;
1715- end;
1647+ L: TStringList;
1648+begin
1649+ L := GridTextExporter(grid, 80, true);
1650+ L.SaveToFile('grid.txt');
1651+ L.Free;
1652+end;
17161653```
17171654
1718-* * *
1655+------------------------------------------------------------------------
17191656
17201657**Tłumaczenie**
17211658
1722-Na język polski przełożył: --[Sławomir Załęcki](</User:Slawek> "User:Slawek") ([[User talk:Slawek|talk]]) 17:13, 2 February 2022 (CET)
1659+Na język polski przełożył: --Sławomir Załęcki ([[User talk:Slawek|talk]]) 17:13, 2 February 2022 (CET)
17231660
17241661---
1725-*From the Free Pascal wiki, page "Grids Reference Page/pl", as the Internet Archive kept it on 2024-09-20. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
1662+*From the Free Pascal wiki, page "Grids Reference Page/pl", as it stood on 2022-02-02 after a change by Slawek, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history