Grid - část první ( dokončení)

Co by ve třídě gridu nemělo chybět.

V minulém díle jsme vytvořili vlastní třídu gridu. Pro dynamické generování gridu to však nebyly všechny metody. Také zde vytvoříme i několik dalších metod, sice nesouvisejicími s generováním gridu, ale jsou užitečné, neboť ne vše je optimální.

Vzpomněl jsem si ještě na jeden podraz ve VFP 6.0 (ve VFP 5.0 to funguje bez problemů) při dynamickém generování gridu. Předtím, než se budou přiřazovat zdroje dat sloupcům, musí být aktivní oblast, ze které grid tahá data. Pokud tomu tak není, VFP vyhlásí chybu při přiřazení funkce/metody/procedury jako zdroj dat sloupci, popřípadě jsou všechny sloupce Read Only (samotný grid nikoliv).

1) Dynamické generování
K dynamickému generování gridu patří metoda Clear() a Generate(). Metoda Clear() slouží pro korektní likvidaci sloupců (i vymazání zdroje dat ) a Generate() pro vygenerování n sloupců určité třídy (maže původní obsah gridu) a vlastnost ColumnClass (název třídy sloupce pro generování).

Metoda Clear() - zdrojový kód:

LPARAM llClearResource
* llClearResource - Příznak zda se má vymazat vlast. RecordSource
LOCAL lii,lols
lols=CREATEOBJECT("_setls",Thisform)
* Nyní smaž všechny sloupce
FOR lii=This.ColumnCount TO 1 STEP -1
    This.RemoveObject(This.Columns(lii).Name)
NEXT
IF !EMPTY(llClearResource)
   This.RecordSource="" && Vymaž ještě zdroj dat
ENDIF

Výklad:
Jako parametr je přijímána proměnná typu Boolean. Vytvoří se objekt pro zablokování překreslování formuláře. Postupně se mažou sloupce (odzadu). Pokud je předaný parametr .T. , vymaže se i vlastnost RecordSource.

Metoda Generate() - zdrojový kód:

LPARAM lcAlias, liColumnCount
* Pokud zadáme lcAlias="" a liColumns=0, grid pouze vymaže všechny své sloupce.
IF EMPTY(lcAlias) AND !EMPTY(liColumnCount) && Pokud nejsou správně parametry
   RETURN ErrFewArguments
ENDIF
IF EMPTY(liColumnCount)
   liColumnCount=0 && Pak vypni generování sloupců
ENDIF

LOCAL lii,lols
lols=CREATEOBJECT("_setls",Thisform)
This.ColumnCount=0
This.RecordSource=lcAlias && Zapiš zdroj dat
This.Clear() && Smaž grid
IF liColumnCount>0
   FOR lii=1 TO liColumnCount
       This.AddObject("Column"+LTRIM(STR(lii,6)),This.ColumnClass)
   NEXT
   This.SetAll("Visible",.T.) && Zobraz všechny objekty
ENDIF
This.FontName="MS Sans Serif"
This.FontSize=8
RETURN ErrOK

Výklad:
Jako parametr je přijímána proměnná typu String (zdrojový alias) a Integer (počet sloupců). Vytvoří se objekt pro zablokování překreslování formuláře, nastaví se počet sloupců na 0, zdrojový alias a zavolá se metoda Clear() bez parametru. Potom se přidají sloupce podle třídy, jejíž název je uložen ve vlastnosti ColumnClass. Pak se už jen nastaví vlastnost Visible všech objektu na .T., název a velikost fontu celého gridu.

Popis třídy _Setls - zdrojový kód:

DEFINE CLASS _setls AS DataEnvironment
   Name = "_setls"
   PROTECTED oform && Zkratka na předávaný formulář

   PROCEDURE Destroy
      This.oForm.LockScreen=.F. && Pak ho povol ( navrať původní hodnotu )
      This.oForm=.NULL. && Vymaž zkratku na formulář
   ENDPROC

   PROCEDURE Init
      LPARAM loForm
      IF loForm.LockScreen && Pokud je blokováno překreslování
         RETURN .F. && Pak vypadni ( objekt se nevytvoří, protože to není potřeba)
      ENDIF
      This.oForm=loForm && Vytvoř zkratku na formulář
      loForm.LockScreen=.T. && Pak ho zakaž
   ENDPROC
ENDDEFINE

Výklad:
Tato třída slouží pro nastavení vlastnosti LockScreen na formuláři. Tato třída si kontroluje zda již byla vlastnost nastavena na .T. .Pokud ano, pak se vratí .F. a objekt se nevytvoří. Pokud ne, pak se vlastnost LockScreen nastaví na .T. a na vlastnost oForm se nalinkuje formulář předaný jako parametr.
V události Destroy() se nastaví daná vlastnost formuláře na .F. a uvolní se link na vlastnosti oForm.

Jedná se o velmi příjemný způsob nastavení vlastnosti LockScreen v kaskádě, kde by bylo velmi náročné to zajistit tradičním způsobem. Bohužel jde o velmi časově náročnou činnost (na rozdíl od tradičního způsobu).

2) Úprava události AfterRowColChange()
Pohyb po gridu má jednu velkou "nevýhodu", neboť je vyvolána událost AfterRowColChange(), ale bez možnosti zjištění (nativního) zda došlo pouze ke změně řádku a ne sloupce. Vytvoříme si vlastní událost AfterRecordChange() a pomocnou vlastnost Recno.

Úprava události AfterRowColChange() - zdrojový kód:

LPARAMETERS nColIndex
DODEFAULT(nColIndex)
LOCAL liRecNo
liRecNo = RECNO(This.RecordSource) && Číslo aktuální věty ve zdroji dat
IF This.RecNo # liRecNo && Pokud se to liší od uložené hodnoty
   This.AfterRecordChange() && Pak zavolje metodu
   This.RecNo = liRecNo && A zapiš si novou větu
ENDIF

Výklad:
Jako parametr je přijímána proměnná typu Integer (Index sloupce) a volá se původní kód. Pak se načte číslo aktuální věty. Pokud se číslo aktuální věty liší od poslední zapsané hodnoty, vyvolá se událost AfterRecordChange() a číslo aktuální věty se uloží do vlastnosti Recno.

Úprava události Refresh() - zdrojový kód:

DODEFAULT() && Volání původní metody
LOCAL lcSource
lcSource=This.RecordSource
IF !EMPTY(lcSource) AND USED(lcSource)
   This.RecNo = RECNO(lcSource) && Schovej si číslo věty
ENDIF

Výklad:
Provede se původní kód. Pokud je zdroj dat definován a existuje , pak se do vlastnosti Recno zapíše číslo aktuální věty.

3) Metoda GetVisibleRow()
Tato metoda vrátí počet viditelných řádku v gridu.

Metoda GetVisibleRow() - zdrojový kód:

RETURN INT((This.Height-This.HeaderHeight-IIF(INLIST(This.ScrollBars,1,3),16,0))/This.RowHeight)

4) Metoda SplitLineHitTest()
Tato metoda vrátí, zda je ukazatel myši nad čárou sloužící k oddělení sloupců.

Metoda SplitLineHitTest() - zdrojový kód:

* Zjistí, zda se myš (v okamžiku kliknutí na header) nachází nad čarou oddělující sloupce
LPARAM loHeader

LOCAL liMRow, liMRowMax
liMRow=MCOL(Thisform.Name,3) && Pozice myši
liMRowMax=OBJTOCLIENT(loHeader,2)+loHeader.Parent.Width+1 && Pozice sloupce + šířka sloupce převedeno na formulář
* Pokuď seš mimo
RETURN BETWEEN(liMRow,liMRowMax-5,liMRowMax+5)

Výklad:
Jako parametr je přijímána proměnná typu Objekt (Hlavička sloupce). Zjistí se X souřadnice myši na formulářem. Pomocí funkce OBJTOCLIENT() se převede pravá pozice hlavičky na pozici vůči formuláři. Pomocí RETURNu se vrací zda je pozice myši v rámci daného intervalu daného pravou pozicí hlavičky.

Použité konstanty:
ErrOK - (0) - vše je v pořádku
ErrFewArguments - (-4) - Příliš málo parametrů

<< Předchozí díl Následující díl >>