Grafické styly, resp. témata jsou ve WPF silným nástrojem, který umožňuje snadno převléknout view aplikace, aniž by se muselo zasahovat do aplikační logiky. Funguje to na stejném principu jako CSS na webu, jen je to o poznání propracovanější. Témata ve WPF umí různé grafické vychytávky, od stínování či kulatých rožků, až po pokročilé animace či vázání vlastností.
V základu vypadá aplikace ve WPF obyčejně – defaultně je aplikován styl podle prostředí. Tedy s aktivním Aerem je použit styl Aero, v opačném případě styl Classic. Bavíme se o .NET 4.0, kde už je WPF Toolkit obsažen v základu.
Vypadá to úplně normálně a dá se to normálně používat. Ale na druhou stranu, proč bychom používali prezentační framework s takovou silou, kdybychom chtěli pracovat s aplikacemi, které vypadají obyčejně. To je jako vzít si na sebe luxusní hadry za dvacet tisíc a pak si přes ně přehodit obyčejný pršiplášť. Klidně můžeme tu aplikaci udělat ve Windows Forms a bude to sloužit stejně. My ale chceme, aby ta aplikace vypadala cool.
Vytvořit styl, aby vypadal k světu, však není sranda. Potřebujete grafika.
Můžete si samozřejmě koupit nějaký profesionální styl, ale ty stojí nemalé peníze.
Ještě je však možnost použít styl, který někdo dal k dispozici zdarma. Pár se jich najít dá. Microsoft vydal už před pár lety pro WPF sadu základních stylů, resp. jsou to konverze ze Silverlightu, ale zcela dostačují. Dají se stáhnout z Codeplexu, anebo od léta už i přes NuGet. Vypadají dobře, svou roli plní a jsou plně funkční… tedy až na pár drobností – o tom však jindy…
Zásadní problém je v jedné věci – neobsahují styl pro komponentu DataGrid, což je blbé, neboť DataGrid je dost důležitá komponenta.
Já si oblíbil téma ExpressionDark a používám ho ve všech aplikacích. Bez stylů pro DataGrid to však vypadá divně.
Chvíli jsem pátral a vypátral práci nějakého nadšence, který loni zjevně řešil stejný problém. Téma WhistlerBlue, ExpressionDark a ExpressionLight jen pro DataGrid jako doplňek ke stávajícím stylům. Na první pohled to vypadalo dobře, tak jsem to vyzkoušel. Ale ouha, musel jsem od toho upustit. Jednak to není samostantý styl, ale rozšířená komponenta, druhak nezdokumentovaná, třeťak takřka bez podpory. Taky co chci zadarmo, že jo. A přitom jsem potřeboval jenom trochu obarvit stávající DataGrid. Zkusil jsem použít jen to téma, chvíli to vypadalo dobře, ale jen do doby, než jsem zkusil zobrazit tabulku o třech tisících řádků.
DataGrid má v základním nastavení zapnutou takzvanou Virtualizaci UI. Notesáci to jistě také znají, stejně jako vývojáři ve Flexu. Jde o to, že vygenerovat najednou UI grid pro velké množství dat je velmi náročný proces jak pro paměť, tak i na čas. A navíc je to naprosto zbytečné. Proč zobrazovat data, která jsou mimo viewport uživatele, takže ten je stejně neuvidí? Proto se zobrazí určité množství řádek nad, uvnitř a pod viewportem, třeba 50 a jak uživatel scrolluje, generují se další a další řádky. V Lotus Notes je to vidět při rychlém scrollování, nebo při PageUp/Down – není to plynulé, občas se to zasekává, jak si pohled fetchuje další záznamy. Ve WPF DataGridu je to vidět když necháte šířku sloupců na Auto a sledujete, jak se při scrollování šířka postupně přizpůsobuje nejširším záznamům, jak se postupně objevují.
Jinak hezky popsaná je UI Virtualizace WPF DataGridu popsána zde.
S tématem, které jsem použil, se tato virtualizace vypnula a grid na počátku renderoval všechny řádky najednou – se třemi tisíci řádků to na mém notebooku s 8G paměti a i7 procesorem trvalo skoro minutu. To je nepoužitelné.
Tak jsem si sednul a splácal vlastní téma pro WPF DataGrid, based on ExpressionDark. Zabralo mi pár hodin, než jsem do toho proniknul a navíc to téma není hotové – dal jsem tam jen to, co jsem aktuálně potřeboval. Tudíž tam není třeba RowHeader a návazná funkcionalita. Ale prozatím to stačí.
Vypadá to docela dobře, ne? Pokud má někdo zájem, může si ten styl stáhnout. Pak ho stačí přiložit k aplikaci a přidat další řádek do App.xaml… enjoy.
1 2 3 4 5 6 7 8 |
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\ExpressionDark.xaml" />
<ResourceDictionary Source="Themes\ExpressionDarkDataGrid.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources> |
Komentování je uzavřeno.