Saját E-mail Kliens fejlesztése WPF technológia használatával
1.0 Bevezetés Feladatom A WPF, azaz Windows Presentation Foundation tanulmányozása volt, illetve működésének ismertetése. Ezen kívül pedig készítenem kellett egy saját E-mail klienst a WPF technológia segítségével. A WPF egy windows programozási platform, ami a windows forms-ot váltotta fel. Segítségével szép és látványos alkalmazásokat fejleszthetünk, animációkkal és aprólékos design-al. Futtatása nem igényel különösebben sokat, csupán csak a Microsoft .NET Framework 3.0-t, illetve hardver oldalon lehetnek DirectX igényei, de ezek mind könnyen orvosolhatóak, nem jelentenek különösebb gondot. A 3.0-s Framework támogatását már a Visual Studio 2008-ban beépítette a Microsoft, így láthatjuk, hogy ez nem számít újdonságnak. Ami az E-mail klienst illeti, az ötlet egy saját program készítésére egy Google Chrome bővítménytől ered, ami a Gmail-re érkező új, még olvasatlan levelek jelenlétét és számát jelzi. Miután beszéltem több ismerősömmel is, arra jutottam, hogy egy olyan program, ami egyszerre lenne képes figyelni az összes E-mail fiókunkat és jelezni tudná hasonló módon az új üzenetek érkezését, hasznos, kellemes és időt spóroló lenne, hisz nem kéne állandóan ellenőriznünk, hogy érkezett-e új üzenet számunkra vagy sem minden egyes e-mail címet illetően. A kliens futtatásához a már említett követelményeken felül csak két .dll-re van szükségünk, ezek felelősek a POP3 és az IMAP kapcsolatok létrehozásáért és fenntartásáért. Ezeket a későbbiekben részletezném. A programot a cél érdekében csak két fiók figyelésére állítottam be, Hotmail illetve Gmail. Ezekkel mind a két módot (POP3/IMAP) képes voltam bemutatni és mivel ezekkel bármilyen fiókhoz képesek lehetünk csatlakozni, így a programot a későbbiekben több fiók megfigyelésére is ki lehet egészíteni. Természetesen az általam elkészített kliens nem csak annyit tud, hogy jelzést küld új üzenet érkezésekor, hanem képes az összes üzenet letöltésére, azok táblázatos megjelenítésére, csakúgy, ahogy azt az ismert kliensek is teszik, illetve képes ezeket az üzeneteket megnyitni, és akár még a csatolmányt is letölthetjük. A dolgozat felépítése a következő, először A WPF-et mutatom be alapjaiban, ez kilenc alpontot foglal el. Ezután az MVVM sémát mutatom be röviden két alfejezetben. Ezt követően az E-mailekről és az alapvető két protokolljáról beszélek hat alfejezetben, majd az általam készített kliens bemutatása jön hat alfejezetben. Végül az Összefoglalóval zárok.
1
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.0 A WPF Alapjai
2.1 A WPF kialakulásának okai, és a DirectX
A WPF előtt a windowsos alkalmazások fejlesztését elsősorban két elem segítette, ezek voltak a fejlesztés alapjai: User32: Felelős az alapvető Windows felhasználói interfész elemeinek létrehozásáért és ezek kezeléséért. (ablakok, menük, stb) Ezáltal implementálhatunk olyan grafikus interfészeket, amik a Windows érzést visszaadják. Főbb funkciói között vannak: o ablakok létrehozása és kezelése o ablaküzenetek fogadása (egérkattintás, billentyű lenyomás, stb.) o üzenet megjelenítése egy ablakban o üzenetdobozok megjelenítése GDI32: Alapvető rajzolási funkciókat lát el. (rajzolás, szöveg megjelenítés, stb.) Ezek csak egy részét képezték a Win32 API-nak. Ezeken kívül még a Kernel32 és a COMCTL32 is ezen API része volt. Ezek először a Windows 95-ben jelentek meg, amely az első 32 bites Windows verzió volt. A WPF egyik nagy előnye az az, hogy nem a fent említett GDI32-t használja, hanem a DirectX-et. A DirectX a Microsoft egy csomagja a Windowshoz, amely nem sokkal a Windows 95 után jelent meg, és azóta is alapvető része a Windowsnak. A DirectX nem csak abban segít, hogy nem kell primitív funkciókat hívnia a programozóknak a GDI32-ből, hanem abban is, hogy hardverfüggetlen programot tud írni. Ez alapján is már lehet látni, hogy a DirectX-nek rengeteg előnye van. Ezeket elsősorban a játékok fejlesztői használják ki, mivel a DirectX jelentős mennyiségben használja ki a videókártya képességeit. Ez természetesen oda vezetett, hogy a Microsoft már jó ideje együttműködik a videókártyákat készítő cégekkel, ennek fő célja az pedig az, hogy a videókártya fejlesztők és a DirectX fejlesztői is képesek együtt reagálni a szoftveres igényekre. Ahogy azt már említettem, WPF nem a GDI-t használja a megjelenítéshez, hanem a DirectX-et. Ez azért is annyira jelentős, mert ez azt is magával vonta, hogy a User32 is újraírásra került. A funkcionalitás különösebben nem változott, azonban néhány, már korábbi években felfedezett, hibát és rendellenes működést kijavítottak.
2
Saját E-mail Kliens fejlesztése WPF technológia használatával
A DirectX előnyei közé sorolható az a tény is, hogy a DirectX képes hardveresen és szoftveresen is renderelni. Természetesen elsősorban mindig a hardveres gyorsítást fogja használni a WPF, de bizonyos esetekben kénytelen szoftveres gyorsítást alkalmazni, ezt azonban az alkalmazás van, hogy nem is észleli. Általános esetek, amikor szoftveres gyorsításra kerül sor: a videókártya drivere elavult (2004 előtti) a WPF „Tier 0”-ás grafikus kártyát észlelt (ez azt jelenti, hogy a hardveres gyorsítás nem támogatott és a DirectX verziója 7-esnél alacsonyabb) a renderelt ablak mérete meghaladja a videókártya maximális textúra méretét (egy általános példa erre az, amikor egy ablakot több monitoron jelenítenek meg) virtuális gépen való rendereléskor grafikus hardver hiba, mint például „Out of Video Memory”, ekkor a WPF meg fog próbálni felszabadítani memóriát, hogy végrehajthassa a hardveres renderelést, de ez nem mindig sikeres Ha meg szeretnénk tudni, hogy a WPF milyen szinten képes futni a gépünkön, akkor ezt kideríthetjük az alábbi kóddal: int szint = (System.Windows.Media.RenderCapability.Tier >> 16); switch(szint) { case 0: ....; break; case 1: ....; break; case 2: ....; break; }
3 szintet különböztetünk meg: 0. szint: a videókártyánk nem képes hardveres renderelésre, tehát a WPFnek (és természetesen a DirectX-nek) mindent szoftveresen kell végrehajtania, azaz a DirectX verziószáma 7 alatti 1. szint: részleges grafikus gyorsítás támogatás, azaz a DirectX verziószáma 7 és 9 között van 2. szint: a legtöbb grafikus funkció hardveres grafikus gyorsítást végez, azaz a DirectX verziószáma 9 fölött van A WPF előtt is volt lehetőség arra, hogy a programozók a Windows alkalmazások elkészítéséhez DirectX-et használjanak, azonban ezt jelentősen gátolta az a tény, hogy a GDI vagy a User32 nem nyújtott támogatást a DirectX-nek. Ennek eredményeként csak a játékfejlesztők használtak DirectX-et.
3
Saját E-mail Kliens fejlesztése WPF technológia használatával
Ennek vetett véget a WPF. A WPF vezérlőit a Visual Studio felületén keresztül könnyen elhelyezhetjük a form-on, illetve lehetőségünk van méretezni őket, valamint a tulajdonságaikat beállíthatjuk. Az egészben a legjobb pedig az, hogy ennek az elvégzésért nem mi, a programozók, hanem a DirectX a felelős. A DirectX megléte illetve a megjelenítés újragondolása más fontosabb újdonságot is magával vont: Webes elrendezés: A webes jelölőnyelvek sikerén felbuzdulva a WPF is egy ezekhez hasonló lapelrendezési, lapösszeállítási lehetőségeket nyújt. Ezen felül az is jelentős előny, hogy nem kell az ódivatú koordináta alapú elrendezést követni, az új elemek (vezérlők, amik konténer funkciót látnak el) képesek reagálni a form méretének változására és a tartalmukat képesek az új mérethez átrendezni. Gazdagabb Rajzolási lehetőségek: A DirectX és a videókártya által ismert grafikai elemek, mint például az átlátszóság, vagy a textúra, szintén bekerültek a vezérlők alakjába, és ezekkel kódból és design-ból is könnyen lehet dolgozni. Gazdagabb szöveges lehetőségek: Magasabb szintű szövegkezelést biztosít a DirectX, mint például: o megjelenítendő szövegek stílusának beállítása o különböző grafikák beillesztése o hasábok és bekezdések kezelése és igazítása o stb. Animációk alkalmazása: Az egyik érdekes újítás, amit a DirectX behozott, az az animációk beépítése, amik által a kontrollok illetve egyéb alapvető elemek elforgathatóak vagy éppen átszínezhetőek, vagy egyéb módokon módosíthatóak. Ezeket a módosításokat sorozatba rendezhetjük, valamint időzíthejük őket, és ha ezeket megadtuk, akkor az animációkat a DirectX motor fogja végrehajtani, ennek legfontosabb pozitívuma az, hogy a programozónak nem kell megírni az animáció kivitelezéséért felelős kódot, hisz a DirectX végzi el helyettünk. Hangok és Videók: Képesek vagyunk beilleszteni az alkalmazásunkba a Windows Media Player által felismerhető file-okat, ráadásul a lejátszásuk is teljesen irányítható Stílusok és Sablonok: Csakúgy, mint a webes alkalmazásoknál itt is lehetőségünk van sablon stílusokat alkalmaznunk, amik segítségével a vezérlők bármely részének a kinézetét megváltoztathatjuk. Deklaratív tervezés: A WPF-ben rendelkezésünkre áll az úgynevezett XAML jelölőnyelv, amely segítségével lehetőségünk van arra, hogy a felületet külön tervezhessük meg. Így lehetséges, hogy egy ember programozza a kódot az alkalmazáshoz, egy másik pedig a design-on dolgozik.
4
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.2 Felbontás-függetlenség, a WPF egyik nagy előnye
Ahogy már korábban említettem, a WPF-ben az egyik jelentős változás a korábbi Windows Forms-hoz képest az volt, hogy a méretváltoztatást sokkal jobban képesek az alkalmazások kezelni. Ennek oka az, hogy a WPF vektorgrafikus. Saját mértékegysége van a WPF-nek. Nem pixelekben méri, illetve nem is milliméterben, hanem WPF egységben. Ez jelenti a legfőbb változást, ugyanis a WPF mértékegysége a DIU (Device Independent Unit), ami az inch (2.54 cm) 96-od része. Mivel az átlagos monitorok DPI értéke szintén 96, így általában 1 WPF egység 1 pixelt jelent. Fizikai méret = DPU egységekben megadott méret értéke.
* DPI beállítás
Ennek ez eredményeképp ha van egy elemünk, például egy vezérlő, akkor ha az egy olyan monitoron van megjelenítve, ami 96 DPI-s, akkor ha a szélességét 200 egységre állítjuk, akkor 200 pixel lesz a szélessége, és ami a lényeg, a tartalma szintúgy ilyen szinten változik. Fontos megjegyezni, hogy amennyiben a gépünk nem a 96-os DPI méretre van beállítva, akkor 1 WPF egység nem 1 pixel lesz, hanem nagy valószínűséggel valamilyen tört. Annak érdekében, hogy törtek kerekítése ne okozhasson gondot, a WPF mindig tört értékkel számol (double). Ezt természetesen az animációk kiszámításában is fellelhető. Érdemes megjegyezni, hogy amellett, hogy a WPF általában ezt használja, lehetőségünk van pixel alapú grafikus képek megjelenítésére,(bitmap) de mivel ezek átméretezése gondot okoz, főként a minőség terén, ezért ahol csak lehet a vektorgrafikus megoldást érdemes használni.
5
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.3 WPF Felépítése és Fontosabb Assembly-k
1. WPF felépítése
Ahogy azt már korábban említettem, a GDI-t és a User32 főbb funkcióit újraírták a DirectX megléte miatt. Ahogy azt a fentebbi ábrán (1. ábra) is láthatjuk, a következő assembly-k szolgálnak a WPF alapjaként: PresentationFoundation.dll: Ez az elég méretes assembly definiálja a WPF vezérlőket, animációkat, adatkötést, multimédiatámogatást és egyéb szolgáltatásokat. Ez a legfontosabb assembly. PresentaionCore.dll: Ez az assembly nagyon fontos a fenti, PresentationFoundation.dll számára, és rengeteg típust definiál a WPF grafikus felhasználói interfésze számára. WindowsBase.dll: A WPF alap infrastruktúráját definiálja, olyan osztályokat, mint például a DependencyObject vagy a DispatcherObject. milcore.dll: A Media Integration Layer-t tartalmazó dll a DirectX segítségével fordít át magasabb szintű grafikus elemeket DirectX elemekre. A milcore.dll-t a WPF motor magjának is tekintik. WindowsCodecs.dll: A media codec-eket tartalmazza. User32: A felhasználói inputokat kezeli. Direct3d: Ez a felelős a milcore.dll által megadott grafikus elemek képernyőn való megjelenítéséért.
6
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.4 A WPF Legfontosabb Névterei System.Windows: A WPF névterek ebben, azaz a System.Windows névtérben találhatóak. System.Windows.Controls: Ebben a névtérben találhatóak meg mindazon widget-ek, amikkel menürendszereket illetve számos layout menedzsert készíthetünk. System.Windows.Markup: Ez a névtér számos osztályt definiál, amikkel az XAML jelöléseket és a bináris megfelelőjét, a BAML-t, feldolgozhatjuk. System.Windows.Media: Ennek köszönhetően használhatunk animációkat, végezhetünk 3D renderelést, szöveg renderelést, illetve egyéb multimédiás szolgáltatásokat. System.Windows.Navigation: Segítséget nyújt az asztali/böngésző alkalmazások navigációs logikájának implementációjában. System.Windows.Shapes: Alapvető geometriai alakzatokat definiál. System.Windows.DependencyObject: A WPF elemek egy property alrendszerrel rendelkeznek, ahol egy változás képes számos másikat előidézni. Ezek a property értékek ilyen Dependecy Object példányokban vannak eltárolva. System.Threading.DispatcherObject: A WPF alkalmazások egy szálon futnak. Ez azt jelenti, hogy a teljes felhasználói felület működését egyetlen szál vezérli. Másik szálból módosításokat végrehajtani nem biztonságos. Ezen névtér segítségével detektálhatjuk, hogy a módosítás a megfelelő szálból érkezett-e, és ha nem, akkor a kérést továbbíthatjuk a megfelelő szálba.
7
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.5 Az XAML Ismertetése
Az Extensible Application Markup Language egy deklaratív XML-alapú nyelv, melyet a Microsoft Corporation fejlesztett ki és strukturált értékek és objektumok inicializálására használható. A betűszó eredetileg az „Extensible Avalon Markup Language” rövídítése volt, ahol az Avalon a WPF kódneve volt. Az XAML-t különösképpen a WPF-ben használják, ahol a felhasználói felület jelölőnyelveként szolgál, és a felhasználói felület adatelemei, adatkötés, események és más szolgáltatások definiálására szolgál valamint a Windows Workflow Foundation (WF)-ban, melyben magukat a munkafolyamatokat is lehet XAML segítségével definiálni. Az XAML-t a strukturált értékek inicializálására használják. A létrehozásának célja az volt, hogy egyszerűsítse a grafikus felületek fejlesztését a .NET Framework számára. A látható elemek létrehozhatóak XAML leírás segítségével, így a felhasználói felület kódja elválasztható a mögötte futó alkalmazás logika kódjától. Az XAML így lehetőséget nyújt arra, hogy keverjük a programkódot a leíró nyelvi elemekkel, így modellt biztosít a folyamatkezelés számára. A nyelv segítségével a designerek és az arculattervezők feladata külön választható az XAML segítségével a programozók munkájától, könnyebbé téve ezzel egy fejlesztési projekt erőforrásainak elosztását. Más leíró nyelvekkel ellentétben az XAML közvetlenül prezentálja a példányait a kezelt objektumoknak. Ez az általános tervezési alapelv egyszerűsíti a fejlesztést és a nyomkövetést az XAML által bevezetett objektumokra. Az XAML fájloknak általában az .xaml kiterjesztést adják. Az XAML előnyei általánosságban: Felhasználói interfészeket sokkal könnyebben lehet vele tervezni. XAML kóddal sokkal rövidebben le lehet írni amit akarunk, mint a korábban használatos felhasználó felületek tervezéséért felelős kódokkal. Egy eddig nem említett előny az, hogy az a felhasználói felület, ami XAMLben lett megírva, könnyen átvihető és prezentálható más környezetben is. Ilyen környezet például a web is. A XAML hasznát leginkább akkor észlelhetjük, amikor dinamikus felhasználói felületet tervezünk. Az XAML nyelvet felhasználva az is tervezhet grafikus felhasználói felületet, akinek nincsen semmilyen fogalma arról, hogy a .NET fejlesztés hogyan is zajlik, hisz csak az XAML-t kell ismernie, ennek köszönhetően szinte akárki tervezhet felületeket
8
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.6 Az XAML-ről kicsit részletesebben
Valószínűleg az emberek hajlamosak legyinteni, és azt mondani, hogy ez is csak egy újabb mód arra, hogy grafikus felületet definiáljunk XML formátumban, de ha rászánunk egy kis időt, hogy megismerjük az XAML világát, láthatjuk, hogy az XAML-ben az objektumgráfok deklarációit olyan formátumban írhatjuk le, amik az emberek és a gépek számára is könnyen olvashatók és kezelhetők. Mindez ellenére mégis felmerülhet a kérdés, hogy miért XML formátumot alkalmaztak a nyelv létrehozásakor. A válasz pedig erre egyszerű. Az XAML előtt a form design-ereknek tudni kellett vagy C#-ban vagy Visual Basic-ben programozni, hisz nem volt elkülönítve a design kódja az alkalmazásétól. Emiatt pedig nem csak kényelmetlenül nehéz, hanem lassúvá is vált a tervezés és fejlesztés, nem beszélve arról, hogy egy aprócska változtatás és elég lehetett arra, hogy az egészet elrontsuk. Egy olyan .NET nyelvre volt szükség, amivel csakis az objektumok deklarálása a célunk. Ha pedig azt szeretnénk, hogy ez a nyelv mind az emberek és mind a gépek számára könnyen kezelhető maradjon, illetve platformok és szoftverek között átvihető legyen, akkor egyértelműen az XML formátum a legjobb döntés. Nézzünk egy egyszerű példát: <Window x:Class="WpfApplication2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
Ez a kód egy egyszerű „Helló Világ!” szöveget jelenít meg egy Canvas panelen. Mint láthatjuk, a kód könnyen olvasható és kezelhető.
9
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.7 Az XAML Elementek és Attribútumok
Ahogy azt a fenti kis kódrészleten is láthatjuk, különböző element-eket használunk, amikor XAML-t írunk. A legtöbb element a System.Windows.UIElement, System.Windows.FrameworkElement, System.Windows.FrameworkContentElement and System.Windows.ContentElement osztályokból származik. Nézzük meg mik az alapvető element típusok: Gyökér elementek: Windows(ablak) és Page(oldal) elementek a leggyakoribb gyökér elementek amiket használunk. Ezek alkotják általában az XAML fájlunk gyökerét, és ezek tartalmazzák az egyéb elementeket. Panel elementek: Ezek az elementek segítenek a felhasználói interfész kialakításában. Ide tartoznak az általános panelek, mint például a StackPanel, DockPanel, Grid és a Canvas is. Ezekről még később bővebben lesz szó. Vezérlő elementek: Ezek az elementek segítenek különböző típusú vezérlőket elhelyezni a felhasználói interfészen, illetve segítenek ezek testreszabásában. Geometriai elementek: Ezek az elementek lehetővé teszik, hogy különböző alakzatokat és geometriai formákat rajzoljunk a felhasználói interfészre. Ennek többféle fajtája is van, mint például EllipseGeometry vagy LineGeometry, stb. Dokumentum elementek: Ezek az elementek akkor segítenek, hogyha egy dokumentumot kell bemutatnunk. Az Inline és a Block két meghatározó csoportja ezen elementeknek és ezek jelentős segítséget adnak abban, hogy a dokumentumunknak a kívánt külsőt megadhassuk. Az elementeknek adhatunk meg attribútumokat is. Ezek pont olyanok, mint egy .NET osztályban a property-k. Ezeket kétféleképpen is megadhatjuk. Mindkettő ugyanazt eredményezi, a különbség csak abban van, hogy amennyiben a kódunk nagyra nő, az átláthatósága a kódnak az egyik módszerrel kedvezőbb. Az első módszer az Inline megadás. Ez az általános, máshol is használt megadási mód. Ilyenkor az elementen belül adjuk meg az attribútumokat. Például: <Button Width="300"> gomb
A másik megadási mód az explicit mód. Ekkor külön elementben adjuk meg az attribútumot, ahogy azt az alábbi példán is láthatjuk: <Button> <Button.Width> 300 gomb
10
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.8 Expression Blend WPF felületek elkészítéséhez masszív xaml kódot kellene írnunk. Nyilván az ilyen jellegű fejlesztés nem túlságosan hatékony, lassú a munkafolyamat, nem kellőképpen vizuális és kényelmetlen. Itt jön képbe az Expression Blend elnevezésű termék melynek segítségével egyaránt készíthetünk Silverlight-os és WPF-es alkalmazásokat. Az ilyen típusú alkalmazások felületének készítésekor a sarkalatos pontok, amire mindenképp design-Time támogatást kell biztosítani, az adatkötés, a stílusok szerkesztése, vezérlő és adat template-k támogatása, animációk készítése, transzformációk. Ezek segítségével készíthetünk interaktív, látványos és ugyanakkor jól használható informatív felületeket. Az Expression Blend kiemelten támogatja ezen funkcionalitásokat. Felhasználói felületek építésekor a designer nincs tisztában azzal, hogy az alkalmazás a háttérben miként működik, milyen pontos adatokkal dolgozik. Számára az elsődleges szempont a felhasználói felület megalkotása. Ahhoz hogy ezt kellően sikeresen elvégezhesse, nem árt, ha van már a tervezési fázisban rendelkezésre álló adat, ún. design-time adat. Az adat tényleges tartalma nem számít, kizárólag a formátuma, tekintve, hogy az adat vizualizáció a design szerves része. Az Expression Blend kisegíti a designert és biztosít számára úgynevezett SampleDataSource-okat, avagy példa adatforrásokat, melyek segítségével pontos képet kaphat tervezési időben az adatok jellegéről. Már ezen a ponton is fontos a felhasználói input érvényességének ellenőrzése, az úgynevezett validáció. Az Expression Blend, bár egy rendkívüli termék, minden részletét nem fedheti le a WPF-nek, igy a validációs támogatás sem túl szerencsés. A WPF validációs mechanizmusa ún. ValidationRule-ok segítségével történik, ami az adatkötési fázisban ellenőrzi a bemenő információt, egy adott szabály függvényében. Ha az input érvényes, az adatkötés megtörténhet, egyébként pedig meg kell akadályozni. Továbbá a felhasználónak visszajelzést kell biztosítani arról, hogy tudja érvénytelen adatot próbált meg betáplálni, újra kell kezdenie a kitöltést. Többször előfordulhat olyan szituáció, hogy két olyan tulajdonságot szeretnénk összekötni valamilyen logika szerint, amelyek beszélő viszonyban sincsenek egymással. Például egy objektum tartalmaz egy IsRightHanded property-t, amelynek true illetve false értéke lehet, majd ennek függvényében egy szín kódot szeretnénk meghatározni, mondjuk egy négyzet kitöltéséhez. Ha adatkötést alkalmazunk az Square.Fill és a Person.IsRighHanded property-k között, melyek típusa nem egyezik meg, (Brush az egyik és Bool a másik) a kötésük sikertelen, hacsak valamiféle konverziót az adatkötési folyamatba nem építünk be. Az adatkötés folyamatában az utolsó bekapcsolódási pont az ún. ValueConverter-ek helye. Ők lesznek képesek az A típusú objektum X értékéből,
11
Saját E-mail Kliens fejlesztése WPF technológia használatával
B típusú objektum Y értékét előállítani és továbbítani az adatkötési folyamatban, akár mindkét irányba is! Az Expression Blend ezt a folyamatot is támogatja.
12
Saját E-mail Kliens fejlesztése WPF technológia használatával
2.9 WPF Layout Panelek A WPF alkalmazások használhatóságának egyik legfontosabb részét a vezérlők elrendezése jelenti. Ezeket általában nem helyezhetjük el rögzített koordinátákhoz, csak ritka és specifikus esetekben. Ennek okát már korábban többször is emlegettem, ez pedig az, hogy amint megváltozik a képernyő felbontása, avagy a betűméret, ez az elhelyezés máris nem kívánt, kellemetlenül kinéző megjelenést eredményezhet. Ezt elkerülendő a WPF biztosít számunkra előre beépített paneleket. Ezek a Layout panelek a következőek lehetnek: Canvas: megadott pixeles elhelyezést tesz lehetővé WrapPanel: az elemeket folytonosan helyezi el balról jobbra, majd ha a sor betelt új sort kezd StackPanel: vízszintesen és függőlegesen helyezhetünk el elemeket DockPanel: az elemeket a panel oldalaihoz rögzíthetjük Grid: táblázatszerű, sor és oszlop alapú, elrendezés UniformGrid: a Grid egyik speciális fajtája, ahol minden cella egyforma méretű Nézzünk meg ezekről egy kis példát, hogyan is néznek ki használat közben: Canvas: A Canvas panelen elhelyezett vezérlők helyzete abszolút pozícionálással adható meg. Pixelben adhatjuk meg a távolságot az ablak sarkaitól. Az alábbi ábrán (2. ábra) láthatunk egy példát a Canvas panel megvalósítására.
2. Canvas Layout Panelekre példa
13
Saját E-mail Kliens fejlesztése WPF technológia használatával
WrapPanel: A WrapPanel a megadott vezérlőket folytonosan balról jobbra helyezi el, ha elfogy a rendelkezésre álló hely, akkor fentről lefelé folytatja az elhelyezést. Az alábbi ábrán (3. ábra) láthatunk egy példát a WrapPanel megvalósítására.
StackPanel: A StackPanel vízszintesen vagy függőlegesen szervezi a tartalmat. Alapértelmezésben függőlegesen, de ez megváltoztatható az Orientation tulajdonság értékének átállításával. Az alábbi ábrákon (4. és 5. ábra) láthatunk két példát a StackPanel megvalósítására.
Saját E-mail Kliens fejlesztése WPF technológia használatával
5. StackPanel Layout Panel példa 2
Ennek a kódja csak egy Orientation="Horizontal".
tulajdonságban
tér
el,
ami
pedig
ez:
DockPanel: A DockPanelben található vezérlők a konténer egyes oldalaihoz csatolhatók. Az alábbi ábrán (6. ábra) láthatunk egy példát a DockPanel megvalósítására.
Ahogy az látható, a bal oldalit nem dokkoltattam, mivel alapértelmezetten oda teszi. Illetve megfigyelhető a LastChildFill="True" tulajdonság, amivel lehetőségünk van kitölteni a középső részt.
15
Saját E-mail Kliens fejlesztése WPF technológia használatával
UniformGrid: A UniformGrid egy korlátozott változata a Grid vezérlőnek, amiben minden sor és oszlop azonos méretű. Az alábbi ábrán (7. ábra) láthatunk egy példát a UniformGrid panel megvalósítására.
7. UniformGrid Layout Panel példa <Button>Button1 <Button>Button2 <Button>Button3 <Button>Button4
Grid: A Grid panelt a vezérlők táblázatos elrendezésére használják. Az oszlopok és sorok a Grid.ColumnDefinitions és a Grid.RowDefinitions elemek között kerülnek megadásra. Lehetőséget biztosít a sorok és az oszlopok egyesítésére. Az alábbi ábrán (8. ábra) láthatunk egy példát a Grid panel megvalósítására.
Saját E-mail Kliens fejlesztése WPF technológia használatával
3.0 A Model-View-ViewModel (MVVM) 3.1 Röviden az MVVM-ről
A Model-View-ViewModel egy tervezési séma, ami a Microsoft-tól ered. Az MVVM nagymértékben alapszik a Model-View-Controller sémára, és nagyban támogatja az eseményalapú programozást, ami a WPF-ben is jelen van. Az MVVM elszeparálja a grafikus felhasználói felület fejlesztését az üzleti logika tervezésétől. Az MVVM nézeti modellje egy érték konvertáló, ami azt jelenti, hogy a nézeti modell felelős azért, hogy az adat objektumokat olyan módon teszi elérhetővé a modellből, hogy azokat könnyen lehessen kezelni. Ebből a szempontból azt is mondhatnánk, hogy a nézeti modell inkább modell, mint nézet, és a nézetek megjelenítési logikáját majdnem teljes egészében kezeli. Az alábbi ábrán (9.ábra) láthatjuk hogyan is néz ki a kapcsolat a View, ViewModel és Model között.
9. MVVM elemei közötti kapcsolat
Az MVVM-et azért tervezték meg, hogy könnyebben használhassuk az adatkötési funkciókat a WPF-ben, aminek a segítségével könnyebben szét lehet választani a nézeti réteg tervezését és többi résztől azáltal, hogy elkülöníthetjük a grafikus interfész kódját. Ez lényegében azt jelenti, hogy azok a programozóknak, akik a felhasználói felületen dolgoznak, nem kell írniuk GUI(graphical user interface) kódot, hanem helyette használhatják a keretrendszer által biztosított jelölőnyelvet és ezt a nézeti modellhez köthetik, amit viszont már az alkalmazás fejlesztői csinálnak. Ez azt eredményezi, hogy a programozók szerepei jobban elkülönülnek, és azoknak, akik a felhasználói interfészt tervezik, nem kell 18
Saját E-mail Kliens fejlesztése WPF technológia használatával
belefolyniuk az üzleti logika programozásába, és ez fordítva is igaz, ezáltal pedig a munka egyszerre több részben folyhat, ami hatékonyabb fejlesztési munkát garantál. Ennek a hasznosságát jelzi az is, hogy ez a logika nem csak akkor érvényes, ha csoportosan dolgoznak egy projekten az emberek, hanem egy ember írja az egész kódot. Ez főként azért fordulhat elő, mert a fejlesztési folyamat végén, mikor a programunkat javítani szeretnénk a tesztelések alapján, akkor is könnyebben lehet a felhasználói felületet változtatni, hisz az elszeparált kódok itt is fennállnak.
19
Saját E-mail Kliens fejlesztése WPF technológia használatával
3.2 A Sémáról Részletesebben
Ahogy azt már az előző részből is megtudhattuk, az MVVM lényege, hogy megpróbálja az MVC által nyújtott szeparációs logikát is kihasználni, valamint az adatkötés előnyét is próbálja beépíteni a sémába. Érdemes megjegyezni, hogy amíg a sémát a Microsoft fejlesztette ki, addig maga az ötlet, ami mögötte van alkalmazható ennek bármilyen más implementációjához. Ezáltal a sémát bármilyen programozási nyelvben és bármilyen megjelenítési keretrendszerrel használhatjuk, ami támogatja a deklaratív adatkötést. Az alábbi (10. ábra) láthatjuk a séma részletesebb tulajdonságait.
10. Az MVVM séma elemeinek részletesebb tulajdonságai
Nézzük meg az MVVM séma elemeit: Model: A modell definiálja azokat az adatokat, amiket az alkalmazásunkban használni akarunk. Ez általában implementálja az INotifyPropertyChanged interfészt. A modell egyik jelentős feladat, hogy az alatta lévő adatforrás logikailag összeillő részeit ábrázolja, illetve egyszerűsítse. Amennyiben lehetséges, nem szabad WPF specifikus kódot használnunk ebben a részben, hisz a modellt elképzelhető, hogy más típusú projektekben is fel szeretnénk használni. Emlékezzünk rá, hogy a modell tartalmazza az adatokat, de ezek viselkedését nem. Nem az a dolga, hogy szöveget formázzon, vagy például elemek egy listáját lekérdezze. Ugyanakkor bizonyos esetekben tartalmazhat validációt. View: Ahogy az az MVC sémában is van, a nézet mindazon elemeket tartalmazhatja, amiket a GUI megjelenít, ilyenek például a gombok, címkék és egyéb vezérlők. Célszerű ezt minden esetben XAML jelölőnyelvben írni és nem belekeverni mást. Tehát az állapotadatokat és az üzleti logikát semmiképp nem illik ide írni, ezeknek a ViewModel-ben a helyük. Érdemes megemlíteni, hogy az MVVM-ben a nézet aktív, ellentétben azon társaival, amik passzívak, és teljes mértékben egy kontroller irányít. A nézet itt tartalmaz eseményeket illetve adatkötéseket, amiknek szükségük van arra, hogy tudomásuk legyen a Model-ről és a ViewModel-ről. 20
Saját E-mail Kliens fejlesztése WPF technológia használatával
ViewModel: Ahogy a nevéből is kiderül, a nézeti modell az a nézet modellje. Ez nem jelent mást, mint azt, hogy ez a nézet egy absztrakt megvalósítása. Ezen felül ez egy köztes rész a nézet és a modell között, és az adatkötések célja is az, hogy a meghatározott ViewModel-t használhassuk. A három rész közül (Model-View-ViewModel) ez a kulcsfontosságú, ugyanis ez köti össze ezt a hármast. Ha az MVC-hez szeretnénk továbbra is hasonlítani, akkor mondhatjuk, hogy a ViewModel olyan, mint a Controller az MVC-ben, azaz a modellbeli információkat nézeti információkká alakítja és a nézetből érkező parancsokat átadja a modellnek. Fontos megjegyezni, az említett három réteg közötti kapcsolat egyirányú, hiszen a View tudatában van a ViewModel-nek, a ViewModel tudatában van a Model-nek, de a Model semmit nem tud a ViewModel-ről, és a ViewModel sem tud semmit a View-ról. Amennyiben hatékonyan és gyorsan szeretnénk alkalmazást fejleszteni követve az MVVM sémát, nem árt betartani bizonyos alapelveket, amik megkönnyítik a fejlesztést. Ezek: Az Egyszerűség Alapelve: Minden View-hoz csak egy ViewModel tartozzon, és egy ViewModel csak egy View-t szolgáljon ki. Ennek az alapelvnek a célja az, hogy ne legyenek a dolgok összezavaróak, illetve hosszú távon ez könnyebb fenntarthatóságot biztosít. A Blendelhetőség Alapelve: A ViewModel-nek támogatnia kell az Expression Blend-et. Ez az alapelv annyira nem fontos mint a többi, de mindenképp segítséget nyújt és megkönnyíti a fejlesztést, amennyiben az Expression Blendet használjuk. Mivel az Expression Blend a legjobb eszköz ahhoz, hogy XAML alapú felhasználói felületet készítsünk, így célszerű használni is. Ahhoz, hogy a ViewModel támogassa az Expression Blend-et, a ViewModel osztályának tartalmaznia kell egy publikus paraméter nélküli konstruktort, valamint a View DataContext-jének XAML-ben kell megírva lennie. A Tervezhetőség Alapelve: A ViewModel-nek biztosítania kell Tervezési Idejű Adatokat. A XAML alapú alkalmazások általában jelentős mennyiségben használnak adatkötéseket. Ennek az egyik hátránya az, hogy ha egyszer az adatkötés megtörtént, akkor nehéz lehet a vezérlőket megjeleníteni például az Expression Blend eszközeivel. Azonban ha az előző alapelvet betartjuk, akkor tervezési időben létre fog jönni egy példánya a ViewModel-nek. Ez lehetővé teszi, hogy a nehézségeket áthidaljuk, azáltal, hogy tervezési időben a ViewModel példányról másolatok készülnek.
21
Saját E-mail Kliens fejlesztése WPF technológia használatával
A Tesztelhetőség Alapelve: A ViewModel-t és a Model-t tudnunk kell tesztelni. A tesztelés egy fontos része az alkalmazásfejlesztésnek. Célszerű tehát tesztelhető, de az alapelveknek megfelelő Model-t és ViewModel-t készíteni.
22
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.0 E-mail és Protokolljainak Bemutatása 4.1 E-mail története, Rövid Ismertető
Az e-mail (ejtsd: ímél) kifejezés egy angol kifejezésből származik. Ez az „electronic mail”, azaz elektronikus üzenetként, vagy elektronikus postaként fordítható le. A kifejezés egyértelműen az üzenet megírásának módjából illetve annak továbbításának módjából ered. Amíg régebben ez nem volt igaz, de manapság már egyértelműen az internet számít az elsőszámú közvetítő felületnek, illetve az is ismert, hogy ez az internet használatának egyik legelterjedtebb és legkedveltebb módja. Az e-mail kifejezés két jelentéssel is rendelkezik: -
egyrészről maga a szolgáltatás, amit nyújt számunkra másrészről pedig a konkrét üzenet, amit elküldünk
Ahogy azt már korábban említettem, régebben nem az interneten keresztül történt az e-mailek küldése, hisz az e-mail előbb jött létre, mint maga az internet. Az emailek 1965-ben jelentek meg először, amikor is egy időosztásos számítógép több felhasználója között biztosított kommunikációt. Az első ilyen rendszerek az SDC, a Q32 és az MIT CTSS-ek voltak. A már létező e-mail rendszerek adták az alapot az internet létrejöttéhez. 1966-től már lehetővé vált az e-mail-ek hálózaton belüli továbbítása is, így több gépen keresztül lehetett üzenetek váltani. Az első ilyen rendszert az AUTODIN-t tartják, de lehetséges, hogy már a SAGE is tartalmazott ehhez hasonló elemet korábban. Később 1969-ben az ARPANET számítógépes hálózat jelentősen megnövelte az e-mailek népszerűségét. Természetesen nem minden gép és hálózat volt egymással közvetlen kapcsolatban, így tehát kellett egy egységesített protokoll, mint például az UUCP, amelynek a segítségével továbbításra kerülhetett az e-mail. Ehhez tartalmaznia kellett az e-mailnek az üzenet útját, ami a küldő gépe és a fogadó gépe közötti utat írta le. A @ (kukac) jel használatának ötlete, amely a felhasználó nevének, illetve az ő gépének az azonosítójának az elválasztására szolgál, Ray Tomlinson 1972-ben találta ki. Két fontosabb e-mail programja is volt, amik jelentős lépést jelentettek az e-mailek mai formájának a létrejöttében, ezek az SNDMSG és a READMAIL voltak.
23
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.2 Internetes e-mail
A mai modern világban már szinte minden e-mail internethez kapcsolódó gépekre érkezik. A küldést DNS, MX record és SMTP segítik. A már korábban említett útmegadást a mai e-mail kiszolgálók már sem automatikus módon, sem manuális módon nem engedélyezik. Ennek fő oka az, hogy könnyű ezzel visszaélni. (Spam)
11. A Gmail üzenetküldő felülete, a különböző mezők szépen elkülönülve
A fenti ábrán (11. ábra) jól láthatjuk hogyan is néz ki egy általános e-mail küldő felület. Az internetes e-mail cím egy karaktersorozat, amely a következőképpen néz ki: [email protected] Ez két részre bontható: -
az első rész, ami jelen esetben a „valaki”, az e-mail cím birtokosának a felhasználóneve a második rész pedig annak a gépnek a neve, amelyiken az adott e-mail fiók létezik
Az e-mail üzenetek formátumát az RFC 2822 definiálja. Az üzenetek tipikusan két fő részből állnak: 24
Saját E-mail Kliens fejlesztése WPF technológia használatával
-
fejléc: (header) ez a rész kisebb, de fontos információkat tartalmaz az emailről, általában az alábbi négyet: o az e-mail küldőjének címe (from) o az e-mail fogadójának címe (to) o az e-mail üzenet tárgya (subject) o az e-mail dátuma, azaz a helyi idő és dátum, amikor az üzenetet elküldték (date) de ezeken kívül még tartalmazhat egyéb mezőket is:
-
o másolat, angolul „carbon-copy”, innen is a rövidítése, a Cc o rejtett másolat, angolul „blind carbon copy”, azaz Bcc, ez abban különbözik a sima másolattól, hogy a benne lévő címzettek nem látszanak, azaz ha rejtett másolatot küldön A-nak és B-nek, akkor A nem fogja tudni, hogy B is kapott másolatot o válaszcím (reply-to) o megérkezés (received), ez egy lista, amelybe az üzenetet kezelő kiszolgálók (számítógépek) írják be magukat, így tehát visszakövethető, hogy milyen úton jutott el az üzenet a feladótól a címzettig o content-type, ez az üzenet típusát tartalmazza, az úgynevezett MIME definíció alapján törzs: (body) ez a rész tartalmazza magát az üzenetet, a végén általában egy aláírással
25
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.3 E-mailek küldésének és fogadásának módja
Az e-mailek az úgynevezett SMTP (Simple Message Transfer Protocol) típusú kapcsolat segítségével kerülnek továbbításra. Ez egy aránylag egyszerű, szövegalapú protokoll, ahol egy üzenetnek egy vagy több címzettje is lehet. Az üzenet küldése után a fogadó fél POP illetve IMAP típusú kapcsolat segítségével letölti azt. A 12. ábra jól mutatja a küldés és fogadás lépéseit.
Az e-mailek elsősorban 7 bites ASCII szöveg átvitelére voltak alkalmasak, azonban mára már az e-maileket továbbfejlesztették a MIME szabvánnyal, amelynek a segítségével lehetőségünk van bináris adatot is továbbítani mellékletként, mint például képek és hangok, valamint képesek vagyunk HTML kódot is továbbítani, mint melléklet. Ha már említésre került a csatolmány, akkor térjünk ki kicsit részletesebben. Az e-mailekhez könnyen csatolhatunk szöveges fájlt, videót vagy képet is. De igazából bármilyen fájlt küldhetünk, amíg az megfelel a kiszolgáló által előírt szabályoknak. Ilyenek lehetnek például:
Méretbeli korlátozás: bizonyos kiszolgálók nem engednek csatolni olyan állományt, amely meghaladja a kiszolgáló által előírt mérethatárt Kiterjesztésbeli korlátozás: a legtöbb kiszolgáló nem enged .exe fájlokat küldeni a vírusveszély miatt, hiszen sok naiv felhasználó oda sem figyel, mire kattint, mit futtat 26
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.4 A modern e-mail átka, a levélszemét
Az e-mail egyik legjobb tulajdonsága, azaz az alacsony költsége és gyorsasága, egyben a legrosszabb is lehet, attól függően milyen szempontból vizsgáljuk. Ennek fő oka az e-maileket megrontó levélszemét. Levélszemétnek nevezzük a nagy számban érkező kéretlen, káros/rosszindulatú, illetve téves leveleket. A már említett alacsony költség és gyorsaság miatt az ilyen üzenetek küldői akár napi több százmillió üzenetet is küldhetnek, ezzel pedig jelentősen csökkentik az e-mail hatékonyságát. A levélszemétnek tipikus tartalma szokott lenni, amelyek gyakran keveredve szoktak megjelenni, ezek például:
A legfőbb levélszemét a kéretlen reklám, azaz a spam Az e-mail férgek is jelentős problémát jelentenek. Ezek e-maileket használnak saját maguk sokszorosítására és a védtelenebb rendszerekbe való bejutásra. Mára már kizárólag a Microsoft Windows rendszerek problémája, de eleinte a UNIX rendszereket támadtak vele Ahogy már korábban a csatolmányoknál említettem, a csatolmányokban elképzelhető, hogy egy álcázott vírust tartalmazó fájl található A levelező listáról küldött levelek is levélszemétnek számítanak, ha a felhasználó nem számít rájuk Egy szintén veszélyes fajtája a levélszemétnek az adathalászat céljából küldött üzenetek. Ezek többnyire valós és megbízható címekhez hasonló címről érkeznek, ezzel próbálva átverni a figyelmetlenebb felhasználókat és kiszedni belőlük például banki adataikat. De ebbe a kategóriába tartoznak azok az üzenetek is, amelyek valamilyen nem létező nyereményt ígérnek a címzetteknek. Végül pedig ide sorolhatjuk a szimplán téves címre elküldött üzeneteket is, amik különösen akkor jelentenek nagyobb problémát, ha a felhasználó e-mail címe hasonlít egy ismertebb címre
27
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.5 POP3 Ismertetése
A POP (Post Office Protocol) egy olyan alkalmazás szintű protokoll, amit az e-mail kliensek használnak fel arra, hogy letöltsék az e-maileket a távoli szerverről TCP/IP kapcsolat segítségével. 1985-ben jött létre a POP1, az első verziója a POP-nak, és jelenleg a harmadik verzió van érvényben, azaz a POP3. Rettenetesen elterjedt, így nem is meglepő, hogy szinte kivétel nélkül minden email kliens támogatja. Társával, az IMAP-el, ami szintén egy hasonló protokoll, a legismertebb e-mail kliensek által egyaránt támogatottak. A POP lényegében úgy működik, hogy a kapcsolatot létrehozza a kliens és a szerver között, letölti az üzeneteket, eltárolja azokat a kliens oldalán, majd törli az üzeneteket a szerverről és a kapcsolatot lezárja. Habár érdemes megemlíteni, hogy létezik opció arra is, hogy ne kerüljenek a szerveren az üzenetek törlésre. Az IMAP ilyen téren nagyobb szabadságot és lehetőséget biztosít, azonban kevesebb kliens támogatja, mint a POP-ot. A POP3 szerver a 110-es porton figyel, majd, ha a kommunikációra való felkérés megérkezik akár STLS vagy POP3S paranccsal, akkor létrehozzák a kapcsolatot a szerverrel TLS-t (Transport Layer Security) vagy SSL-t (Secure Sockets Layer) felhasználva a 995-ös TCP porton. A POP session létrejötte után a letölthető e-mailek fixek, ami azt jelenti, hogy ha a kapcsolat közben új e-mail érkezne, azt nem tudnánk a már létrejött session segítségével letölteni, azt be kéne zárni és újat létrehozni. Ez a programom kapcsán is fontos lesz. A session létrejötte után az e-maileket kétféle képen lehet azonosítani: o az üzenet száma szerint, ahol az elsőszámú a legrégebbi, a legújabb pedig n levél esetén az n-edik számot viseli o illetve azonosíthatóak a POP szerver által kiadott egyedi azonosító alapján, ami egy állandó és minden üzenetre teljesen egyedi ismertető, ami számok és betűk véletlenszerű kombinációja A POP3 kliens a tranzakció során különféle állapotba juthat, ezen állapotok közötti átmenetet pedig egyszerű parancsok kezelik. Ezek:
28
Saját E-mail Kliens fejlesztése WPF technológia használatával
Ahogy az ábrán (13. ábra) is látni, az állapotok az alábbiak: -
-
-
Zárt: ekkor a kliens és a szerver között nincs kapcsolat, a kapcsolatot a Connect() paranccsal hozhatjuk létre, amennyiben a Csatlakozott állapotban lévő kliens végrehajtja Disconnect() parancsot és a szerver nem észlel hibát, akkor a kliens a Csatlakozott állapotból visszakerül a Zárt állapotba Csatlakozott: ebben az állapotban a kliens és a szerver között a kapcsolat létrejött és a felhasználó azonosítása már megtörtént Azonosítás: a kliens és a szerver között már létezik a kapcsolat, azonban még nem történt meg a felhasználó azonosítása, ezt az Authorization() paranccsal tehetjük meg Lecsatlakozott: a kliens akkor kerül ebbe az állapotba, amennyiben a Disconnect() parancs futása közben a szerveren valami hiba történt, ebből az állapotból a Connect() utasítással ismét visszakerülhet a kliens az Azonosítás állapotba
A kliens alapvetően a Zárt (Closed) állapotban van. A kapcsolat létrehozásához a Connect() parancsot kell használnunk. Ajánlott ezt a kapcsolatot SSL segítségével létrehozni. Ez a kapcsolat még nem teszi lehetővé számunkra az üzenetek letöltését, csak a kommunikációt teszi lehetővé a kliens és a szerver között. Amint ez létrejött, a kliensnek meg kell adnia a felhasználó nevét és jelszavát annak a fióknak, amelyet el szeretne érni. Ezt az Authorization() utasítás teszi lehetővé. Ez 29
Saját E-mail Kliens fejlesztése WPF technológia használatával
a parancs igényli a felhasználó nevét és jelszavát, mint paraméter. Amennyiben hiba nélkül lefut az utasítás, azaz a paraméterben megadott adatok helyesek és nem történik egyéb hiba sem, akkor a kliens sikeresen kapcsolódik a kívánt e-mail fiókhoz és a rajta található e-maileket letöltheti.
Később még részletesebben ki fogok térni az IMAP és a POP3 közötti különbségekre, de azt érdemes itt megemlíteni, hogy a POP3 nem nyújt akkora szabadságot, mint az IMAP, illetve a kezelhetősége is nehézkesebb, ennek javítása érdekében voltak javaslatok a POP4 létrehozása érdekében. Ez változást hozna a könyvtárkezelésben, a többrészes (multipart) e-mailek kezelésében illetve a message flag menedzselésben, azonban nem történt lényegi előrelépés 2003 óta.
30
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.6 IMAP Ismertetése
Az IMAP (Internet Message Access Protocol) szintén e-mailek letöltésére szolgál, és 1986-ban Mark Crispin hozta létre a Stanfordi Egyetemen. A POP mellé egy alternatív megoldásnak szánta, ugyanakkor néhány megoldás, amit beletett a POP fölé helyezi. Az IMAP lehetővé teszi, hogy egyszerre több kliens is egyszerre lehessen csatlakozva ugyanahhoz a fiókhoz (14. ábra), és flagek segítségével a különböző kliensek képesek érzékelni, ha egy másik kliens valamilyen állapotváltozást okoz a szerveren.
14. Az IMAP egyszerre több klienst is kiszolgál - Forrás: https://corp.sonic.net/ceo/2008/01/22/imap-whats-that/
Egy IMAP szerver tipikusan a 143-as porton figyel, majd ha a kapcsolat létrehozására az igény felmerül, akkor SSL segítségével az létrehozásra kerül a 993-as porton. Az IMAP lehetővé teszi a felhasználó számára, hogy akár on-line, akár off-line módon végrehajthassa az utasításait. Az IMAP kliensek a POP3 kliensekkel ellentétben nem törlik a leveleket a szerverről, hacsak a felhasználó nem törli őket szánt szándékkal, többek között ez is teszi lehetővé, hogy egyszerre több kliens is műveletet hajthasson végre ugyanazon a fiókon. Ahogy már említettem, a legtöbb e-mail kliens a POP3 mellett támogatja az IMAP-et is, de kevesebb támogatja az IMAP-et, mint a POP3-at.
31
Saját E-mail Kliens fejlesztése WPF technológia használatával
4.7 IMAP és POP3 közötti különbségek
Nézzük meg még egyszer, pontokba szedve, mik is a főbb különbségek a két fő e-mailkezelő és letöltő protokoll között:
a POP3 szerverek egyszerre csak egy klienst tudnak egy fiókhoz csatlakoztatni, szimultán nem tud egyszerre több kliens ugyanahhoz a fiókhoz hozzáférni, míg IMAP-ben a szerverek akárhány klienst képesek ellátni az állapotflagek segítségével, amikkel képes a szerver az állapotváltozásokat a kliensek felé tudatni amennyiben egy POP3 kliens letölti az üzenetet a szerverről, az törli azt, míg egy IMAP kliens csak cache-eli az üzenetet, a szerver azonban megőrzi azt, csak akkor törli, amennyiben a felhasználó arra ad utasítást a kiszolgálón IMAP esetén több információ tárolható a már korábban említett állapotflagek segítségével, mint például: o olvasatlan-e az üzenet vagy sem o megválaszolt-e az üzenet vagy sem o az üzenetet törölték-e vagy sem POP3 esetén a kliens általában csak annyi ideig marad csatlakozva a szerverhez, amíg letölti az e-maileket, IMAP esetén azonban annyi ideig marad a kliens csatlakozva, amíg a felhasználói felület aktív, ez különösen a nagyméretű üzenetek esetében hatékony, illetve ha nagyszámú e-mailje van a felhasználónak IMAP esetében lehetőségünk van szerver oldali keresésre, azaz rákereshetünk az általunk kívánt üzenetre, és ez anélkül fog végbemenni, hogy le kellene töltenünk az üzeneteket a korábbi pontokban említett előnyök az IMAP felé egyben egy aprócska hátrányt is jelentenek, hiszen ahhoz, hogy mindezek a funkciók működjenek, egy bonyolultabb és nagyobb rendszerre van szükségünk, tehát ez lényegében annyit jelent, hogy egy POP3 szerver és kliens létrehozása lényegesen egyszerűbb és olcsóbb, mint egy IMAP-é emellett pedig az is megállapítható, hogy ha nem megfelelően van az IMAP szerver beállítva, nagyban csökkenthetjük a működésének hatékonyságát, hisz a rengeteg adatforgalom, amit a folyamatos kapcsolat, letöltések és keresések jelentenek, jelentős időtartamba telhetnek
32
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.0 Saját E-mail kliens Készítése A korábbiakban csak az e-mailekről formálisan beszéltem, de nem említettem meg semmilyen konkrét klienst. Volt szó a letöltésüket segítő protokollokról, amik ebben a programban is fontosak lesznek. A kliens létrehozásának oka az a kellemetlen tény, hogy ahhoz, hogy meg tudjuk nézni kaptunk-e új üzenetet, be kell lépnünk az e-mail fiókunkba, és ellenőrizni személyesen, hogy kaptunk-e új üzenetet vagy sem. Ez pedig akkor jelent kifejezetten nagy kellemetlenséget, amikor az embernek több, akár 4-5 vagy annál is több fiókja van. Mindegyiket ellenőrizni megadott időközönként elég nagy kellemetlenséget és időt jelent. Ezért gondoltam arra, hogy jó lenne egy program, ahol az általam megadott e-mail fiókokat a program folyamatosan figyelné, és jelezné számomra, hogyha valamelyikre érkezett egy új üzenet, többek között. Ahhoz, hogy ez valóban annyira hatékony legyen, természetesen szükségesnek tartottam, hogy mind POP3, mind IMAP protokollt támogasson. Amíg a POP3 szinte minden esetben jó lenne, de az IMAP hasznos tulajdonságai segítenék az IMAP protokollt támogató kiszolgálókkal való kommunikációt. Szintén egy célkitűzés volt, hogy egy könnyen használható és egyszerű program legyen, ezáltal pedig jelentősen növeljük a felhasználói élményt. A Microsoft Outlook, ami egy hasonló program, például aránylag nagyméretű, és nem biztosít többféle kiszolgáló felé támogatást. Kiegészítőkkel ugyan megoldható, hogy például a hotmail-t is támogassa, de ez csak további munkát és kellemetlenséget jelent, ha hozzá akarjuk adni az alap programhoz.
33
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.1 OpenPop.Net
Az OpenPOP egy ingyenesen letölthető .dll fájl, ami erről az oldalról http://hpop.sourceforge.net/ egyszerűen letölthető. Ez a .dll lehetővé teszi, hogy egyszerű metódusok segítségével kapcsolódhassunk POP3 kiszolgálókhoz és letölthessük az e-mailjeinket. A már korábban leírt módon történik meg itt is a kapcsolódás. Azaz van egy Connect() metódus, ami létrehozza a kapcsolatot, majd egy Authenticate() metódussal bejelentkezünk a megfelelő fiókba. Az üzeneteket a GetMessage() metódus segítségével tölthetjük le. Ez csak egy üzenetet tud egyszerre letölteni, és nincs is külön metódus az összes letöltésére, így hát egy for ciklust kell használnunk, ha ezt el akarjuk érni, amelynek a GetMessageCount() metódus által megadott számot kell beállítani az iterációk számának. Ez eddig egyszerűen megvalósítható, a gond azonban akkor lép fel, ha azt szeretnénk megkapni, hogy van-e olvasatlan üzenetünk. Ahogy már korábban is említettem, ez azért okoz problémát, mert a POP3-ban nincsenek állapotflagek, tehát nem lehet egyszerűen megkapni, hogy van-e olvasatlan üzenet vagy sem. Ahhoz, hogy ezt a problémát kiküszöböljük, le kell töltenünk az összes e-mailt, majd beállítani egy metódust, ami periodikusan letölti az e-maileket egyesével, és össze kell hasonlítanunk, hogy a szerveren lévő legújabb e-mail megegyezik-e a nálunk eltárolt legújabb e-maillel. Ezen felül még arra is oda kell figyelnünk, hogy egy már létrejött POP3 kapcsolat nem tud frissülni, ha egyszer létrejött, akkor az abban a pillanatban a szerveren lévő e-maileket letölthetjük, de újonnan érkezetteket nem. Tehát minden egyes ilyen periodikus ellenőrzés során új kapcsolatot kell létrehoznunk, majd az ellenőrzés befejeztével a kapcsolatot le kell zárnunk.
34
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.2 E-mail-ek megfelelő tárolása
Az egyik legfontosabb kérdés, amit meg kellett válaszolnom a feladat elkezdésekor az az volt, hogy a letöltendő e-mailek tartalmát, azok tulajdonságait hogyan és milyen módon tároljam. Erre az egyszerű válasz persze az, hogy a szükséges információkat le kell tölteni, el kell menteni, és ha ez megvan, akkor ezt bármikor újra fel lehet használni. Ennek amiatt láttam volna hasznát, hogy a gépen a lehető legkevesebb helyet foglalták volna az üzenetek. Ezt úgy csináltam, hogy miután kapcsolatot létesítettem a szerverrel, letöltöttem az üzeneteket, kiszedtem a számomra szükséges információkat illetve a tényleges üzenetet, majd ezeket egy-egy fájlba írtam. Ezáltal elértem, hogy a program sokadlagos futásakor nem kell minden üzenetet letölteni, csak az újakat, hisz az előzőek már le vannak mentve. A fájlba mentés ezek alapján az alábbi módon történt volna. builder.AppendLine(message.Headers.From.ToString()); builder.AppendLine(message.Headers.Subject); builder.AppendLine(message.Headers.DateSent.ToString()); builder.Append(plainHtml.GetBodyAsText()); text = builder.ToString(); System.IO.StreamWriter file = new System.IO.StreamWriter("d://Szakdolgozat/a" + date.Replace(":", "").Replace(".", "").Replace(" ", "") + ".html"); file.Write(text); file.Close();
Majd ezek után, ha fájlból szerettük volna visszakapni az adatokat, akkor az alábbi kódot használtuk volna. StreamReader reader = new StreamReader(fileList[i - 1]); for (int j = 0; j < 3; j++) { builder.AppendLine(reader.ReadLine()); } from = builder.ToString().Split('\n')[0]; subject = builder.ToString().Split('\n')[1]; date = builder.ToString().Split('\n')[2];
A csatolmányt azonban nem szerettem volna minden e-mailhez letölteni, szerettem volna ezt a lehetőséget megadni a felhasználónak, hogy eldönthesse, le akarja-e tölteni vagy sem. A csatolmány letöltéséhez viszont így újból le kellett tölteni az e-mailt, amit fölösleges erőforrás pocsékolásnak gondoltam. Ezen felül az a probléma is felmerült, ami egy általános problémaként is jelentkezett volna az előzőleg elmondott tárolási mód esetében, hogy amennyiben az e-mailt újra le kell tölteni, az adott e-mail azonosítása a szerveren gondot okozhat. Ennek oka az, hogy POP3-ban az e-maileket csak a sorszámuk alapján lehet specifikusan letölteni. Amennyiben én ezt lementem és közben a szerveren ez valamilyen okból 35
Saját E-mail Kliens fejlesztése WPF technológia használatával
kifolyólag megváltozik, akkor nem tudom már többé azonosítani a letölteni kívánt e-mailt. Ezek után arra a megoldásra jutottam, hogy a message típusú objektumokat, amikbe az üzenetek letöltődnek, fájlba lementem a message.save() metódus segítségével. Ezeket a fájlokat aztán később a message.load() metódussal vissza lehet tölteni, aminek az eredményeként visszakapunk ugyanolyan message típusú objektumokat, amikből kiindultunk, és amikből az információk ugyanúgy kiolvashatóak, mint korábban, és a csatolmányt és ki lehet szedni. Ahogy az valószínűleg kiderült ebből, a csatolmányokat így legalább kétszer kell letölteni, hogy meg lehessen nyitni őket. Ezáltal kicsit több helyet foglalnak az üzenetek, mint ahogy azt eredetileg terveztem, de ezáltal stabilabb lett a rendszer, hisz kevesebb helyen fordulhat elő hiba.
36
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.3 E-mail üzenetek megjelenítése
Az e-mailek üzenetének megjelenítését először nem tudtam, hogyan fogom megoldani, ugyanis sok olyan üzenet érkezik manapság, ami nem sima szöveget tartalmaz, hanem valamilyen html tartalmat. Ennek a megoldásához úgy fogtam hozzá először, hogy megpróbáltam keresni valamilyen olyan metódust, ami képes értelmezni html tartalmat, és annak jelentését visszaadni, tehát lényegében megjeleníti a html kódot. Erre nem találtam választ, azonban találtam egy olyan metódust, amivel a felhasználó képes nyitni egy böngésző ablakot, és abban megnyitni fájlt, vagy megjeleníteni nyers kódot. if (System.IO.Path.GetExtension(filePath) == ".html") { message = Message.Load(new FileInfo(filePath)); window1.MainBrowser.Name = name; window1.MainBrowser.NavigateToString(message.FindFirstHtmlVersion().GetBodyAsText()) ; } else { message = Message.Load(new FileInfo(filePath)); window1.MainBrowser.Name = name; window1.MainBrowser.NavigateToString(message.FindFirstPlainTextVersion().GetBodyAsTe xt()); }
Ahogy azt a fenti kódban is látni, a html-t tartalmazó e-maileket és a text-et tartalmazóakat a mentett fájlok kiterjesztésével különböztettem meg, majd ezek betöltése után a window1.MainBrowser.NavigateToString(message.FindFirstPlainTextVersion().GetBodyAsTe xt());
vagy window1.MainBrowser.NavigateToString(message.FindFirstHtmlVersion().GetBodyAsText()) ;
kóddal megjelenítem az üzenetet egy új ablakban, ami tartalmaz egy grid-et, amiben található egy MainBrowser nevű böngésző ablak. Ebben a böngészőben jelenik meg az általunk betöltött szöveg vagy html. Ez azért is volt egy kulcsfontosságú megoldás, mert nem csak a html megjelenítésével voltak gondok, hanem az egyszerű szöveggel is. A különböző e-mailek különböző karakterkódolásúak voltak, és csak bizonyos típusú szöveget engedett stringként lementeni, a többire hibát dobott ki. A gond így az volt, hogy a rendelkezésemre álló függvények között, azaz se a Message, se a MessagePart 37
Saját E-mail Kliens fejlesztése WPF technológia használatával
osztályban nem volt olyan, amivel konvertálhatttam volna az üzenet szövegét. A böngésző behozatala azonban megoldotta ezt is, hiszem a böngészők számára nem okoznak gondot a különböző kódolású szövegek.
38
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.4 Gmail és az Imap
Miután sikerült megoldanom a POP3 szerverrel való kommunikációt, illetve az e-mail tárolás és megjelenítés problémáját, rátértem a Gmail-ről való letöltésre. Itt hamar hibába is ütköztem, és amíg a problémára egyszerű lett a megoldás, sok időbe telt amíg megtaláltam, mert amint az számomra kiderült, kevesen foglalkoznak ezzel a témával, plusz egy aránylag új dologról is van szó, így kevés utalást találtam rá a kereséseim során. Ez a hiba nem más volt, mint az, hogy a Gmail nem engedte, hogy külső forrásból jelentkeztessem be a felhasználót, és Web Login Required hibaüzenettel elszállt a program. Először azt hittem, talán az IMAP kódommal van baj, és POP3-al próbálkoztam, hisz a Gmail szerencsére mindkét módon elérhető, de a probléma így is fennállt. A problémát azért is volt olyan kellemetlen megoldani, mert az interneten sok különböző megoldást találtam, ami a megoldást posztolók számára megoldotta a problémát, de számomra nem. A megoldást végül egy biztonsági beállítás jelentette, amit a Gmail-en belül találhatunk meg. Nem az alapbeállítások között van, így elsőre nem is találtam meg, hisz természetesen gondoltam rá, hogy esetleg valami ilyesmi jelentheti a megoldást. Be lehet állítani ugyanis, hogy a Gmail felhasználói fiókunk engedélyezze a külső forrásból történő belépést. Ez kifejezetten az olyan programok ellen van, mint például az enyém is.
39
Saját E-mail Kliens fejlesztése WPF technológia használatával
using(Imap imap = new Imap()) { imap.Connect("imap.example.com"); imap.Login("user", "password"); imap.SelectInbox(); List uids = imap.Search(Flag.Unseen); foreach (long uid in uids) { string eml = imap.GetMessageByUID(uid); IMail email = new MailBuilder() .CreateFromEml(eml); Console.WriteLine(email.Subject); Console.WriteLine(email.Text); } imap.Close();
A fenti példakód egy egyszerű módját mutatja annak, hogyan is lehet csatlakozni egy IMAP szerverhez a megfelelő felhasználónév és jelszó használatával és letölteni az e-maileket az egyedi azonosítójuk alapján. Fontosnak tartom megjegyezni, hogy ahogyan azt a kódban is lehet látni, imap segítségével az egyedi azonosító alapján is (uid – unique id) le lehet tölteni az üzeneteket.
40
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.5 E-mail lista készítése
Az e-mail kliensek általános elemén, azaz a listán, amiben az e-mailek fel vannak sorolva alap tulajdonságaik alapján, és kiválaszthatóak olvasásra, nem akartam változtatni, hisz ez egy olyan elem, ami nem hiába része minden e-mail fióknak. Egyszerű, lényegre törő és könnyű átlátni, hogy ki, mit és mikor küldött. Mivel én több fiókhoz is kívántam egy ilyen listát csinálni, de természetesen nem akartam minden listát egyszerre megjeleníteni, ezért tabcontrol-t használtam a listák megjelenítésére. Egy példakódon keresztül szemléltetném ennek a használatát. Az alábbi példakód forrása a következő link. http://www.dotnetperls.com/tabcontrol-wpf Én is ez alapján tanultam meg a használatát.
Ez az általunk is jól ismert kinézetet veszi fel, azaz egy ablak, aminek a bal felső sarkában 2 fül található. A fülekre kattintva a SelectionChanged tulajdonságban megadott metódus lesz meghívva. Jelen esetben a TabControl_SelectionChanged metódus.
41
Saját E-mail Kliens fejlesztése WPF technológia használatával
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) { var item = sender as TabControl; var selected = item.SelectedItem as TabItem; this.Title = selected.Header.ToString(); }
Minden ilyen fül egy táblázatot rejt, aminek soraiban megtalálható az e-mail küldője, a tárgy, illetve a küldés dátuma, valamint egy gomb a sor végén, amire kattintva előjön a már korábban említett ablak a böngészővel, amiben az e-mail üzenet tartalmát megjelenítem. Ennek a táblázatnak a sorait természetesen csak dinamikusan készíthetem el és tölthetem fel, hisz futás előtt nem lehet tudni, hogy hány sor fog kelleni, illetve a sorok tartalmát sem lehet tudni. Dispatcher.BeginInvoke(new Action(() => { RowDefinition rowDef = new RowDefinition(); rowDef.Height = new GridLength(30); MainGrid.RowDefinitions.Insert(MainGrid.RowDefinitions.Count - 1, rowDef); int rowIndex = MainGrid.RowDefinitions.Count - 2; ColumnDefinition colDef = new ColumnDefinition(); MainGrid.ColumnDefinitions.Insert(MainGrid.ColumnDefinitions.Count, colDef); TextBox textBox = new TextBox(); Grid.SetRow(textBox, rowIndex); Grid.SetColumn(textBox, 0); Grid.SetRowSpan(textBox, 1); Grid.SetColumnSpan(textBox, 1); MainGrid.Children.Add(textBox); textBox.Focusable = false; textBox.Text = from;
A fenti kód mutatja hogyan is történik ez nagyjából, ez egy sort szúr be a grid-be, majd abba a sorba egy oszlopot tesz és abba az oszlopba egy textboxot tesz. A kód első sora az egyik legfontosabb része. Nélküle meg kéne várnunk, amíg a program megcsinálja az összes sort, feltölti azokat, és csak azután jelenne meg a táblázat, addig csak folyamatos töltést érzékelnénk. Ez különösen akkor lenne kellemetlen, ha több száz vagy ezer e-mailt is be kell szúrni a táblázatba. Így azonban minden egyes sor elkészülte után a sor megjelenik a táblázatban és használható is, ezáltal nincs sok holtidő és a felhasználó számára is kellemesebb a használat.
42
Saját E-mail Kliens fejlesztése WPF technológia használatával
5.6 Működés képekben
Kinézetben nem törekedtem nagyot alkotni, gondoltam az alap kinézet, ami egyszerű és letisztult, megfelel a feladat céljából.
15. Üzenő ablak figyelmeztet, hogy még nem adtunk meg minden e-mail címet
Az első elinduláskor, illetve minden olyan induláskor, amikor még nincs mindkét email fiók megadva, ez az üzenő ablak fogad minket (15. ábra). Jelzi, hogy még nem adtuk meg valamelyik e-mail címet.
16. Felhasználói adatok felvételére szolgáló ablak
Amint a 15. ábrán látható ablakon az OK-ra kattintunk, a 16. ábrán látható ablak tárul elénk. Itt adhatjuk meg az e-mail címünk és jelszavunk, ami az Add E-mail Address gombra kattintva elmentődik.
43
Saját E-mail Kliens fejlesztése WPF technológia használatával
17. A kitöltetlen táblázat, amelybe az e-mailek sora jön
Ahogy azt a 17. ábrán láthatjuk, az adatok megadása után a következő táblázat tárul elénk feltöltetlenül, a méret pedig még változatlan. A fülek segítségével válthatunk a Hotmail és a Gmail fiókok között. A táblázat feltöltését, és a figyelést a Start gomb megnyomásával kezdhetjük el, a Cancel pedig ennek a folyamatnak vet véget.
18. A kliens táblázata feltöltve
A táblázat egy részét láthatjuk a 18. ábrán, az egészet a méreténél fogva nem lenne célszerű ide beszúrnom. Ahogy az látható, a különböző sorok szépen beszúródnak, jelezve az adatokat, azaz a küldő kilétét, a tárgyat, a küldés dátumát illetve, hogy van-e csatolmány vagy nincs.
44
Saját E-mail Kliens fejlesztése WPF technológia használatával
19. Üzenet megnyitásakor nyíló ablak
Amennyiben el szeretnénk olvasni egy üzenetet, a 18. ábrán látható Read gombra kell kattintanunk. Ha ezt megtesszük, akkor a 19. ábrán látható ablak tárul elénk. Jelen esetben egy Visual Studio által küldött e-mailt láthatunk. Megfigyelhetjük, hogy az Attachment Download cella üres. Ez azért van, mert az üzenet nem tartalmaz csatolmányt. Ha mégis tartalmazna, akkor egy Download feliratú gomb lenne a cellában, amire kattintva a csatolt állomány letöltődik.
20. Üzenő ablak jelzi, hogy új üzenetünk érkezett
A 20. ábrán láthatjuk, ahogy a figyelő metódusunk eredménye képen felugrott ez üzenő ablak, jelezve, hogy új üzenetünk érkezett.
45
Saját E-mail Kliens fejlesztése WPF technológia használatával
6.0 Összefoglalás A munkám során számos gond merült fel, ezek jellegük szerint két csoportba oszthatóak. Egyrészről akadtak technikai gondok, azaz valamit nem tudtam megoldani egyből, utána kellett olvasnom, próbálkozgatnom kellett, míg végül meg nem találtam a megoldást. Másrészről akadtak olyan holtpontok, amikor kérdések merültek fel a megvalósítás módjával kapcsolatban. Ezekre nem igazán talál általában megoldást az ember könyvekben vagy az interneten, legtöbbször a legjobb orvosság erre az, ha leülünk és gondolkodunk. Érdekesnek tartom, hogy a legtöbb gondom nem magával az e-mail-ekkel volt, hanem az XAML megfelelő kinézetével. Ennek eredményeként elég részletes belátást kaptam ebbe a világba, hisz az időm jelentős részét a különböző XAML kialakítások vették el. Tapasztalatom e téren az, hogy az XAML nem annyira részletes és könnyen kezelhető, amennyire azt előre hittem. Ez az előítéletem abból eredt, amit a WPFről általánosságban hallani/olvasni. Sok a kötöttség, akadnak problémák, amikre nincs közvetlen megoldás. Ez különösen azért volt zavaró, mert triviális dolgokat sem lehet mindig megoldani triviális módon. Erre példa volt számomra az, hogy szerettem volna, ha a táblázatom mindig az ablak méretéhez igazodik. Én nem látok okot arra, mért ne lehetne egy olyan tulajdonság, ami egy egyszerű Enabled vagy True opcióval ezt megvalósítaná. Ehelyett bonyolult módon dinamikusan kell állítanunk a méretet, és még így is vannak kódok, amik nem működnek ideális módon. Természetesen lehet az is, hogy csak én nem jöttem rá valamire, vagy csak bizonyos dolgok nem úgy működnek, ahogy én azt gondolom. Ilyen például a teljes képernyő gomb. Ennek megnyomása nem aktiválja azt a metódust, ami a képernyő méretének változásakor aktiválódik. Ilyen apróságok elég nagy kellemetlenséget tudnak okozni. Ami a későbbi fejleszthetőséget illeti, már a bevezetésben említettem egyet. Amennyiben igény lenne rá, a figyelhető e-mail fiókok számát ki lehet bővíteni, a POP3 és az IMAP alapok már megvannak, és általuk bármely e-mail címhez képesek lehetünk csatlakozni. Ezen kívül be lehet esetleg építeni egy e-mail küldő funkciót is, ez azonban egy bonyolultabb kiegészítés lenne, legfőképpen a csatolmányok küldése miatt.
46
Saját E-mail Kliens fejlesztése WPF technológia használatával
7.0 Summary During my work, there have been many times where I got stuck and had to work through the trouble. These occurences can be categorized into two categories. The first one is the technical difficulties, where I made mistakes in the code and i had to spend time to find them. The other category is the speculative problems, where I didn’t know how to proceed with my work not because of a mistake in the code, but because I didn’t know how to approach the problem, so I had to spend time just thinking about it and trying to find a solution. One of the more interesting things I found out during my work is that working with e-mails wasn’t the difficult part of the project. It was actually the XAML part, and because of this, I had an opportunity to get a deeper understanding of it. My experience is this. As much as freedom and easier designing methods are advertised, XAML has some flaws that are hard to not notice. When something trivial has no trivial solution. For example, I wanted to the size of my grid to always be the size of the window. So I created a method that changed the size of the grid whenever the window size was changed by utilizing the SizeChanged method of the window. Everything works well until I change my window’s size to full screen. For some reason, the method doesn’t get invoked. I would think that this is such a common thing, that is should be able to be enabled or disabled in the grid properties. I might be wrong altogether of course, and there is some easy option to achieve this result, but I couldn’t find it, and that alone is a problem, because I’ve been looking for a solution for a long time. As for improvements on the project in the future, I think it can be expanded with more email clients to watch, because the cornerstone methods are in place from both the POP3 side and the IMAP side of things. Plus it can be further improved with an email sending function. While sending text is not hard, but as far as my knowledge goes, it isn’t easy to send attachments, but it would probably be the most useful addition to the software.
47
Saját E-mail Kliens fejlesztése WPF technológia használatával
Saját E-mail Kliens fejlesztése WPF technológia használatával
Ábrajegyzék
1.
WPF felépítése
2.
Canvas Layout Panelekre példa
3.
WrapPanel Layout Panel példa
4.
StackPanel Layout Panel példa 1
5.
StackPanel Layout Panel példa 2
6.
DockPanel Layout Panel példa
7.
UniformGrid Layout Panel példa
8.
Grid Layout Panel példa
9.
MVVM elemei közötti kapcsolat
10.
Az MVVM séma elemeinek részletesebb tulajdonságai
11.
A Gmail üzenetküldő felülete, a különböző mezők szépen elkülönülve
12.
E-mail küldésének lépései
13.
Pop3 kapcsolattartási állapotok
14.
Az IMAP egyszerre több klienst is kiszolgál
15.
Üzenő ablak figyelmeztet, hogy még nem adtunk meg minden e-mail
16.
Felhasználói adatok felvételére szolgáló ablak
17.
A kitöltetlen táblázat, amelybe az e-mailek sora jön
18.
A kliens táblázata feltöltve
19.
Üzenet megnyitásakor nyíló ablak
20.
Üzenő ablak jelzi, hogy új üzenetünk érkezett
49
Saját E-mail Kliens fejlesztése WPF technológia használatával
CD melléklet tartalma Egy Dolgozat nevű katalógusban az alábbi fájlok: -
-
A dolgozatot tartalmazó file, a használt szerkesztő formátumában A dolgozatot tartalmazó file, PDF formátumban, .pdf kiterjesztéssel A kiírás, külön file-ban. A dolgozatból kiemelve, egy-egy külön file-ban a magyar és az angol nyelvű összefoglalót, a használt szerkesztő formátumában és PDF formátumban is. Külön katalógusban, amelynek neve Email Kliens, megtalálható a program forráskódja, amely futtatható