|
|
Jenže jsem si řekl, že takovou aplikaci bych chtěl ještě rozšířit. Tak například bych chtěl aby aplikace získala následující rysy:
Z výše uvedeného plyne potřeba použít další znalosti možností WPF a C#. Hledal jsem místo, kde bych mohl ozkoušet LINQ, aby to mělo praktický rozměr. LINQ se mi hodil hned několikrát. XML soubor se v aplikaci pomocí objektu XDocument načte a pak následně přes LiNQ se vytvoří kolekce se závislostmi. Pro interpretaci dat v XML souboru jsem vytvořil několik maličkých objektíčků. Objekt Unit udržuje informace o jednotlivé jednotce (veličině). Objekt Kind odpovídá záložce, tedy skupině veličin a obsahuje dva seznamy pro listoboxy. Inputa Output. Z XML jsem chtěl vyčítat seznamy jednotek jen jednou a proto objekt Unit implementuje rozhraní ICloneable. Diky LINQ pak vytvoření seznamu s typy jednotek a zároveň vnořených seznamů jednotek pro listboxy zajistí takováto pěkná konstrukce: (více okolo ní se dozvíte ze zdrojových kódů, na které je odkaz níže)
IList<Kind> kinds;
// Přes LINQ vytáhnu data z XML a naláduju je do kolekcí objektů Kind a Unit.
kinds = (from knds in xdoc.Element("ConversionReceipt").Element("Kinds").Elements("Kind")
where !excludedKinds.Contains(knds.Element("Name").Value)
select new Kind
{
Name = knds.Element("Name").Value,
// Setter pro IntputUnits nastavi pomoci klonovani hodnotu pro OutputUnits.
// Proto zde ctu data ze XML jen jednou.
InputUnits = (from unts in knds.Elements("Unit")
select new Unit
{
Name = unts.Element("Name").Value,
Short = unts.Element("Short").Value,
Ratio = decimal.Parse(unts.Element("Ratio").Value.ToString(), System.Globalization.CultureInfo.InvariantCulture),
}).ToList(),
}).ToList();
Ikdyž LINQ umí vytvářet anonymní typy, šel jsem cestou vlastní implementace, protože později v implementaci potřebuji mít typy známé. Navíc dialog Preferences umožňuje resetovat viditelnost jednotlivých záložek, což je v GUI řešeno jako listbox s položkami obsahujícími checkbox. Objekt KindSetup (podobně jako Kind, ale pro účely dialogu Prefrnces) má vlastnost Visibility, která je mapovaná právě na zmíněný chceckbox. Když metoda buttonReset_Click nastaví hodnotu true do všech položek, je nutné aby i v listboxu se přenastavily všechny checkboxy, proto objekt KindSetup implementuje rozhraní INotifyPropertyChanged. To by u anonymního typu nešlo.
Ve snipetu výše je navic dobře vidět konstrukce pro omezení výběru ze XML pomocí příkazu WHERE, kde pracuji s jinou kolekcí, která obsahuje názvy skupin jednotek, které uživatel vidět nechce. Proto se vyloučí z kolekce kind. To je moc pěkná ukázka jak snadno a efektivně lze pracovat s kolekcemi. Kolekce excludedKinds má svůj zdroj v nastavení aplikace. Definoval jsem pro user-scope položku s názvem ExcludeKinds a její typ definoval jako Specialized.StringCollection.
Při načítání XML do kolekcí provádím konverzi koeficientů z textu na typ decimal a proto je i maličko jiná implementace convertoru RatioConverter.
Za zmíňku stojí i objekt AppCommands, jenž vznikl abych si ozkoušel jak pracuji commandy ve WPF. Commandy jsou výborná věc a aplikace Converter2 je příliž maličká aby v ní commandy vynikly. Command by se dalo říct zastupuje task na úrovni aplikace. Lze ho volat z různých míst, například z kódu, z menu, z tlačítka, klávesovou zkratkou. V aplikaci Converter2 je několik commandů a například klávesová zkratka CTRL+C, CTRL+I a ALT+X jsou gesta přiřazená ke commandům.
Aplikaci jsem realizoval abych natrénoval co jsem se naučil, pokud by mohla její implementace být pro někoho inspirací nebo návodem, račte použít, nahlédnout. Zdrojáky jsou opět plné komentářů aby byla funkčnost jasná.
Aktualizováno (4.4.2012):
Archiv byl občerstven a navíc obsahuje složku "doc", v které najdete kompilovanou dokumentaci ve formátu CHM a dále podadresář "doc/html" v které jsou zdroje nápovědy vygenerované nástrojem DoxyGen.
Vygenerovaná nápověda je k okamžitému nahlédnutí také na tomto odkazu.
O dokumentačním nástroji DoxyGen jsem napsal krátký článek, přečtěte si ho pokud máte zájem zde .