Grid - část první ( popis problémů při dynamickém generování gridu)

Grid patří mezi nejproklínanější a nejvelebovanější třídu ve VFP. Právě jednoduchost s jakou se dají vytvářet zdánlivě složité gridy vizuálním návrhem, způsobí rozčarování při programovém vytváření gridu.

Návrh gridu by se dal dělit dle tří kategorií podle obtížnosti způsobu návrhu:

1) Návrh začátečníků
Grid je visuálně navržen přímo na formuláři. Formulář si zdroj dat otevírá sám pomocí integrovaného DataEnvironmentu.

Problémy s návrhem nejsou.

2) Návrh pokročilých
Grid je visuálně navržen přímo na formuláři či třídě formuláře popřípadě je vytvořena vlastní třída gridu již s předvytvořenými sloupcemi. Formulář si zdroj dat otevírá sám, nebo je zdroj dat otevřen v události Load() na formuláři.

Zde již mohou nastat drobné problémy, neboť je opravdu nutné zajistit, aby byl přístupný daný alias, který je uveden ve vlastnosti RecordSource na gridu, dříve než proběhne inicilizace gridu tj. dříve než proběhne událost Init() gridu.
Pokud tomu tak není, dojde k tomu, že obsah polí neodpovídá popisu polí, či dokonce přibyla další pole.

Vysvětlení: VFP při inicializaci gridu postupuje takto:
a) Otestuje zda zdroj dat (alias) existuje.
b) Pokud ne,pak přebere zdroje sloupců z aktuálního aliasu dle fyzické struktury. Popisy sloupců zůstávají beze změn.
ba) Pokud má aktuální alias více sloupců než je udán počet sloupců v gridu, pak je do gridu přidá. Popisy vizuálně vytvořených sloupců zůstávají beze změn, u přidaných sloupců je popis totožný s popisem položky v DBC konteineru (vlastnost Caption), pokud je vyplněn, jinak je totožný s názvem položky.
c) Pokud ano, pak se grid zobrazí korektně.

3) Návrh expertů
Sem patří dynamické vytváření gridu za běhu programu (ať jednou či vícekrát) na základě zdroje dat, či vlastních informací, přičemž zdroj dat může být pokaždé jiný. Sloupce jsou vytvářeny dle základní třídy Column či odvozených tříd.

Základní pravidla při vytváření sloupců v gridu:
a) Nastavit vlastnost RecordSource na požadovaný alias.
b) Postupně (odzadu) pomocí metody DeleteColumn() odstranit sloupce, které VFP automaticky vygenerovala.
c) Vytvořit sloupce pomocí metody AddObject().

Zdrojový kód:

loGrid.RecordSource=Můj_Zdroj_Dat && Zdroj dat
FOR lii=loGrid.ColumnCount TO 1 STEP -1
    loGrid.DeleteColumn(lii) && Odstraň sloupec
NEXT
FOR lii=1 TO Počet_Sloupců
    loGrid.AddObject("Column"+LTRIM(STR(lii,11)),Název_mé_třídy_sloupce) && Přidej sloupec
    WITH loGrid.Columns(lii)
    ...
    ...
    ENDWITH
NEXT

Samotný návrh třídy sloupce by měl být ve VFP 3.0 - VFP 7.0 umístěn v PRG souboru, VFP 8.0 to možná bude umět definovat i vizuálně ve VCX knihovně.
Zdrojový kód:

DEFINE CLASS _MyColumn AS Column
   ADD OBJECT Header1 AS Header
   ADD OBJECT Text1   AS Textbox

   FontName="MS Sans Serif"
   FontSize=8

   Text1.Margin=0    
   Text1.BorderStyle=0   && Bez okraje
   Text1.FontName="MS Sans Serif"
   Text1.FontSize=8

   Header1.FontName="MS Sans Serif"
   Header1.FontSize=8

   BackColor=RGB(255,255,255)  && Barva pozadí sloupce
   ForeColor=RGB(000,000,000)  && Barva písma sloupce
   ReadOnly=.T.

   PROCEDURE Show
      STORE .T. TO This.Visible,This.Text1.Visible && Ukaž textbox
   ENDPROC
ENDDEFINE

VFP je bohužel u gridu velmi citlivá, pokud ji uzavřeme zdroj dat. Hodil by se spíše výraz "Velmi zmatená","Vhodná do blázince" a podobně. Proto je nutné, předtím než uzavřeme zdroj dat, grid vyčistit.

Zdrojový kód:

FOR lii=loGrid.ColumnCount TO 1 STEP -1
    loGrid.DeleteColumn(lii) && Odstraň sloupec
NEXT
loGrid.RecordSource="" && Vymaž zdroj dat

Jednodušší variantou je, pokud je grid vytvořen pouze jednou (zdroj dat se sice mění, ale jde o zdroje se stejnou strukturou dat) a podle potřeby je obnovován. Generování gridu je stejné jako v předchozím případě. Rozdíl je při uzavírání zdroje dat. Grid se nečistí, pouze se využije nedokumentovaného chování gridu (Softwarový QUAS 99/28 s.16/17)a zapamatují se některé vlastnosti sloupců. Tento "fígl" zajistí, že si grid zapamatuje informace o sloupcích (bohužel ne všechny).

Vytvořme si ve vlastní třídě gridu metodu SaveEnv() (uložení informací o sloupcích) a LoadEnv() (načtení informací sloupcích). Také budeme potřebovat založit matici aColumnGrid[] jako úložiště informací.

metoda SaveEnv() - Zdrojový kód:

LOCAL lii
DIME This.aColumnGrid(This.ColumnCount,3)
FOR lii=This.ColumnCount TO 1 STEP -1
    This.aColumnGrid(lii,1)=This.Columns(lii).Width && Zapamatuj si šířku
    This.aColumnGrid(lii,2)=This.Columns(lii).ColumnOrder && Zapamatuj si pořadí
    This.aColumnGrid(lii,3)=This.Columns(lii).ControlSource && Zapamatuj si zdroj dat
NEXT

metoda LoadEnv() - Zdrojový kód:

LOCAL lii,loCol
FOR lii=This.ColumnCount TO 1 STEP -1
    loCol=This.Columns(lii)
    loCol.Width=This.aColumnGrid(lii,1) && Nastav šířku šířku
    loCol.ColumnOrder=This.aColumnGrid(lii,2) && Nastav pořadí
    loCol.ControlSource=This.aColumnGrid(lii,3) && Nastav zdroj dat
NEXT

Ukázka:

loGrid.SaveEnv() && Ulož nastavení sloupců
loGrid.RecordSource="" && Vymaž zdroj dat

* Tady se může zdroj dat uzavřít, otevřít jiný podobný atd.

loGrid.LoadEnv() && Načti nastavení sloupců

Následující díl >>