pátek 13. června 2014

LiveBindings IV - Pokročilejší nastavení II

Uživatelské formátování (Custom Format)

Dalším požadavkem, se kterým se můžeme setkat při propojování vizuálních komponent a dat je potřeba zobrazení dat v určitém požadovaném tvaru. Může se jednat například o prezentaci telefonních či směrovacích čísel, peněžních částek, položek typu datum a podobně.

LiveBindings Methods a Output Converters 

Uvnitř LiveBindings výrazů lze s předávanými parametry pracovat za pomoci dvou skupin vestavěných funkcí. Jedna (Output Converters) sdružuje funkce pro převod datových typů, druhá (Methods) pak především funkce pro zpracování a úpravu předávaných dat.

LiveBindings Konverzní funkce & metody

LiveBindings nabízí řadu vestavěných funkcí. Pokud by funkce kolidovala s funkcí či metodou používanou dotčeným objektem, lze ji deaktivovat. Dialogy pro aktivaci/deaktivaci funkcí a převodníků lze otevřít z "Inspektora Objektů". Na formuláři musí být umístěna a vybrána komponenta "BindingList".

Příklady formátování výstupu

Mějme jednoduchou aplikaci, která bude zobrazovat data z databáze. Struktura databázové tabulky je následující:

CREATE TABLE LB_DEMO2
(
  ID Integer NOT NULL,
  ZBOZI1 Varchar(20),
  ZBOZI2 Varchar(20),
  CENA Numeric(7,2),
  DATUM Date DEFAULT current_date,
  CONSTRAINT PK_LB2 PRIMARY KEY (ID)
);

Formulář pak může vypadat zhruba takto:

Návrh formuláře

Formátování řetězců

Pokud bychom potřebovali běžné formátovací funkce jako je například převod na malá nebo velká písmena, stačí otevřít "Object Inspector" a do "Custom Format" zapsat příslušný předpis s využitím příslušné funkce LiveBindings.

Object Inspector

Výraz "%s" odkazuje na zpracovávaný řetězec v původním tvaru, tak jak byl přijat od zdrojové komponenty.


V praxi může vyvstat potřeba zpracování více než jednoho řetězce. Například budeme požadovat sloučení polí "ZBOZI1" a "ZBOZI2" z naší tabulky a zobrazení výsledného řetězce v komponentě "Label".
Protože LiveBindings engine standardně umožňuje definovat pro vazbu pouze jeden "zdrojový" a jeden "cílový" objekt, musíme použít drobnou lest. V "BindingsList" vytvoříme nový "BindLink". Jako zdrojovou komponentu vybereme "BindSourceDB". Ta reprezentuje datovou sadu (tedy nadřízený objekt), v které jsou obě databázová pole definována. Tím získáme přístup k metodám, které budeme pro manipulaci s daty potřebovat. Nyní již stačí jen zapsat výraz pro sloučení získaných řetězců, např.:

UpperCase(self.FieldByName('ZBOZI1').Text)  + " " +
self.FieldByName('ZBOZI2').Text

BindingsList

"Self" odkazuje na zdrojový objekt a zpřístupňuje tak všechna data ze zdrojového objektu.


Formátování číselných hodnot

Pro formátování čísel můžeme použít dva přístupy. Pokud je zdrojem dat databáze, lze způsob zobrazení určit přímo pro daný sloupec. V okně "Structure" si zobrazíme pro datovou sadu (v naší aplikaci komponenta "Table") všechny sloupce.

Okno "Structure"

Následně označíme sloupec "CENA", pro který hodláme změnit formátování a v okně "Object Inspector" odpovídajícím způsobem nastavíme vlastnost "DisplayFormat". Zde např. "### ###.00".

Nastavení "DisplayFormat"

Stejného výsledku dosáhneme, pokud podobně jako u formátování řetězců nastavíme v okně "Object Inspector" vlastnost "CustomFormat". Formátování nelze nastavit přímo, ale za pomoci funkce "Format()". Pro zobrazení s přesností na dvě desetinná místa tedy například "Format('%%.2f', value)".


Úplný přehled argumentů funkce "Format()" je uveden v Embarcadero docwiki.


Pokud má být spolu s číslem zobrazen další symbol (procenta, měna, apod.), stačí pouze připojit patřičný string. V případě procent je třeba znak uvádět zdvojeně.

Format('%%.2f', value) + ' %%'
Format('%%.2f', value) + ' Kč'


Protože LiveBindings pracuje s ObjectPascalem i C++, lze v předpisu pro formátování použít jak jednoduché tak dvojité apostrofy. Akceptován tak bude zápis Format('%%.2f', value) i Format("%%.2f", value).

Datum a čas

Stejným způsobem je možné formátovat i položky typu datum či čas. Pouze místo funkce "Format()" je třeba použít funkci "FormatDateTime". Zápis formátování pro úplné zobrazení pro položku "DATUM" tak může vypadat následovně:

FormatDateTime('dd/mm/yyyy hh:nn:ss AM/PM', value)

Finální zobrazení

úterý 3. června 2014

LiveBindings III - Custom Parse

V minulých příspěvcích jsem popisoval vizuální návrh propojení za pomoci LiveBindings Designeru nebo průvodce "LiveBindings Wizard". V praxi se však můžeme setkat s požadavky, které vizuálním návrhem nelze jednoduše realizovat.

Uživatelské zpracování (Custom Parse)

Custom Parse umožňuje řešit situace, kdy je třeba data předávaná mezi objekty upravit do formy, kterou je cílový objekt schopen akceptovat. Typicky se jedná o převody mezi různými datovými typy, nebo o úpravu dat do podoby odpovídající definované masce. S tímto požadavkem se můžeme často setkat například při návrhu databázových aplikací v prostředí FireMonkey.

Příklad:

Vytvořme si jednoduchou FireMonkey aplikaci, která bude sloužit k editaci záznamů databázové tabulky s následující strukturou:
CREATE TABLE LBDEMO ( KONTAKT_ID Integer NOT NULL, PRIJMENI Varchar(50), ZEME Char(2), AKTIVNI Integer, CONSTRAINT PK_KONTAKT_ID PRIMARY KEY (KONTAKT_ID) );
Nejprve si v Delphi nebo C++ Builderu navrhneme formulář pro editaci dat (viz obrázek níže). Pole "AKTIVNÍ", které je v databázi reprezentováno jako integer, bude ve formuláři zobrazeno za pomoci komponenty "CheckBox".

Formulář aplikace

Pro propojení jednotlivých komponent se zdrojem dat použijeme LiveBindings Designer (viz následující diagram).

Nastavení LiveBindings

Pokud takový projekt přeložíme, a pokusíme se změnit hodnotu zaškrtnutím nebo naopak odškrtnutím "CheckBoxu", bude zobrazena chyba. Automatická konverze převede typ boolean na string (defaultní datový typ pro všechny výrazy LiveBindings), který databázový stroj očekávající integer nedokáže zpracovat.

Chyba konverze

Řešením je zmiňovaná uživatelská konfigurace propojení. Nejprve v "LiveBindings Designeru" odstraníme nevyhovující vazbu (na symbol vazby klikneme pravým tlačítkem myši) a zvolíme příkaz "Remove Link".

Odstranění vazby

Následně otevřeme "LiveBindings Wizard" a definujeme nový "BindLink". Alternativně jej můžeme vytvořit pomocí dvojkliku na komponentě "BindingsList" (otevře se okno pro editaci LiveBindings propojení), kde z nabídky vybereme volbu "New Binding => BindLink".
V okně "Object Inspektor" nastavíme jako zdrojovou komponentu datový zdroj, v tomto případě "BindSourceDB1". Vlastnost "SourceMemberName" umožňuje vybrat požadovaný sloupec tabulky, zde sloupec s názvem "AKTIVNI". Nakonec určíme komponentu pro zobrazení dat "ControlComponent". Bude jím komponenta "CheckBox1". 

Konfigurace BindLink

Nyní je třeba doplnit výraz "ParseExpressions" pro uložení dat zpět do databáze. To můžeme provést rovněž prostřednictvím "Inspektora Objektů", nebo lépe v okně pro editaci propojení. Výhodou je možnost okamžité validace definovaných výrazů.

Okno BindingsList

V seznamu propojení klikneme dvakrát na v předchozím kroku vytvořený BindLink a do zatím prázdné kolekce přidáme výraz pro "Parse":

Přidání nového výrazu

Do pole pro "Control Expression" vložíme výraz "IfThen(Self.IsChecked, '1', '0')", který vyhodnotí stav komponenty "CheckBox1". Pokud bude zaškrtnuta (vlastnost "IsChecked" bude mít hodnotu "True"), bude výsledkem výrazu text "1", v opačném případě pak text "0". Do pole pro "Source Expression" napíšeme pouze "Text". Datový zdroj je tak informován o tom, že data obdrží jako string a do požadovaného typu (v tomto případě Integer) si je musí převést.

Úprava výrazů

Vyhodnocení vytvořeného výrazu si lze ověřit za pomoci tlačítek "Eval Control" a "Eval Source". Tlačítka "Assign to Control" a "Assign to Source" pak testují vlastní přiřazení hodnoty.

Validace pomocí "Eval Control"

Nyní můžeme aplikaci přeložit a ověřit si, že nyní již LiveBindings hodnotu zadanou prostřednictvím komponenty "CheckBox" interpretují správně a editované záznamy budou korektně uloženy do databáze.