Sunteți pe pagina 1din 65

MINISTERUL EDUCAŢIEI AL REPUBLICII MOLDOVA

UNIVERSITATEA DE STAT DIN MOLDOVA

Facultatea de Matematică și Informatică Catedra Tehnologii de programare

TEZĂ DE LICENȚĂ

Elaborarea unui manual electronic la disciplina Structuri de date și algoritmi

A elaborat:

Palancica Pavel student al anului III, grupa I-32 Specialitatea Informatică

Conducător științific:

Seiciuc Eleonora dr., lector superior, Catedra Tehnologii de programare

Chişinău - 2011

SARCINA TEZEI

Să se studieze manualele electronice, funcțiile de bază, tipurile și metodele de elaborare a acestora. Să se cerceteze metodele de stocare a informațiilor și modurile de accesibilitate a utilizatorului la informațiile prezentate. Să se aleagă un manual electronic existent la disciplina Structuri de date și algoritmi, și să se selecteze conținutul relevant din cadrul acestuia, pentru realizarea unui nou manual electronic. În partea practică a tezei, să se implementeze un manual electronic propriu. Manualul va trebui să satisfacă următoarele cerințe funcționale:

Să aibă un cuprins, unde denumirile temelor vor fi texte referințe, la tastarea cărora vom fi redirectați la pagina cu conținutul respective.

posede un index, adică o pagină unde să se afle conceptele de bază prezentate în manual și paginile respective unde pot fi găsite. Acești indecși vor fi de asemenea texte-referință.

Să conțină o funcție de căutare avansată a anumitor teme.

Aplicația trebuie, de asemenea, să posede butoanele funcționale de maximizare, minimizare și de închidere a programului.

La tastarea butonului ENTER, fereastra aplicație trebuie să se transforme în modul full-screen sau, respectiv, să revină la poziția normal.

La tastarea butonului ESC, aplicația trebuie să se finiseze.

ADNOTARE

la teza de licență „Elaborarea unui manual electronic la disciplina Structuri de date și algoritmi” a studentului Palancica Pavel, grupa I-32, specialitatea Informatică.

Cuvinte-cheie: manual electronic, obiect grafic, clasă, interfață, interfață grafică, spațiu de nume, obiect, obiect grafic, paletă de culori, evenimente Windows, flip-page. Teza constă din introducere, patru capitole și concluzii. Primul capitol reprezintă un studiu al situației actuale în domeniul cercetat. Sunt cercetate tipurile de manuale electronice, funcțiile de bază ale acestora, metodele de păstrare a informațiilor și cîteva formate de manuale electronice existente. Al doilea capitol descrie succint disciplina Structuri de date și algoritmi. Sunt descrise succint principalele structuri de date și algoritmii de implementarea a acestora. Al treilea capitol descrie tehnologia cu care se va realiza aplicația din cadrul tezei. Sunt explicate cele mai generale concepte din cadrul acesteia. De asemenea, este explicat pe scurt limbajul XAML – limbajul folosit în cadrul WPF, pentru crearea interfețelor grafice utilizator. În al patrulea capitol este descrisă realizarea produsului soft final. Sunt descrise proiectele elaborate în cadrul soluției, este prezentat codul celor mai importante clase și metode și sunt prezentate screenshot-uri cu exemple de interfață a utilizatorului. Am ales C# ca limbaj de implementare a acestei teze, dat fiind faptul că acesta este relativ nou, pur obiectual, care a eliminat deficiențele limbajelor C/C++ și Java și care e folosit de un număr tot mai mare de programatori.

Teza de licență cuprinde 65 de pagini în format A4, conține 3 figuri, 5 tabele și 4

anexe.

CUPRINS

SARCINA TEZEI………………………………………………………………2

ADNOTARE………………………………………………………………….3

CUPRINS……………………………………………………………………… 4

INTRODUCERE……………………………………………………………

6

I. MANUALE ELECTRONICE………………………………………… 1.1Calculatorul instrument didactic

……… 1.2Tipuri de manuale electronice………………………………….……

………………………

8

8

9

II. STRUCTURI DE DATE ȘI ALGORITMI…………………….………12

…………………………………….……….13

… …13

2.1 Tipuri de date abstracte

2.1.1 Caracteristici……………………………………………

2.1.2 Avantaje………………………………………………

……

14

2.1.3 Stiva……………………………………………………………

14

III. PREZENTAREA TEHNOLOGIEI WPF…………………….……

18

3.1Caracteristicile WPF………………………………………

…….20

3.1.1

Interfață utilizator declarativă (Declarative UI)……

………… 20

3.1.2

Poziționare inteligentă……………………………

…………

21

3.1.3

Grafică scalabilă……………………………….………………

21

3.1.4

Template-uri (Șabloane)

22

3.1.5

Legarea (Binding)

23

3.1.6

Stilizarea (Styling)……………………………………………….24

3.1.7

Declanșatoare (Triggers)………………………………………

24

3.1.8

Animație…………………………………………………………24

3.1.9 3D…………………………………….…………………………25

3.1.10 De ce să utilizăm WPF………………………………………

25

3.1.11 Compararea WPF cu alte opțiuni……………………………

26

3.1.12 Părțile componente și versiunile .NET Framework…………

27

3.1.13 Caracteristici incluse în versiunile .NET Framework………….28

3.1.14 Instrumente pentru WPF………………………………………30

……….32

3.1.15 WPF în contrast cu Silverlight………………………

3.2 Limbajul XAML………………………………………………………32

3.2.1

Definiția XAML…………………………………………….33

3.1.1

Sintaxa XAML……………………………………………

35

3.1.2

Setarea proprietăților care nu sunt tipuri simple……………36

3.1.3

Proprietatea Content………………………………………

37

3.1.4

Extensii de Markup…………………………………………38

IV. REALIZAREA MANUALULUI ELECTRONIC………………………41

41

4.1.1 Modulul cu tipuri de date auxiliare.………………………41

4.1 Proiectul WpfBookControls………………….…………

…………

4.1.2 Controlul BookPage

43

4.1.3 Controlul Book

47

4.2 Proiectul WpfAppTezaDeLicenta………….……………………………….49

4.2.1

Clasa StartWindow………………………………………………

49

CONCLUZII……………………………………

………………………………

54

BIBLIOGRAFIE……………………………………………………………….

55

ANEXE……………………………………………

………………………………56

INTRODUCERE

Trăim într-o lume dinamică, ce se află în continuă schimbare, la viteze greu de imaginat cu cîteva decenii în urmă. Cantitatea de cunoștințe acumulate de omenire pe parcursul existenței sale a ajuns în epoca contemporană la un volum care-l face practic inaccesibil integral unei singure persoane. Învățămîntul este și el cuprins în acest vîrtej al schimbărilor, cu responsabilități sporite, deoarece bagajul de cunoștințe minime ce trebuiesc transmise generațiilor ce urmează cuprinde o cantitate de informație ce pare a se amplifica exponențial la intervale tot mai mici. Este o eră a tehnologiilor avansate, a împlinirii celor mai interesante idei gîndite de mintea omenească.

Ultimul deceniu al secolului trecut a adus multe schimbări în diferite domenii. Una din modificările substanțiale, deosebit de utile, poate fi considerată generealizarea utilizării calculatoarelor personale și accesibilitatea tot mai largă publicului. Pătrunderea acestor instrumente de hardware și de software în domeniul lucrărilor de birotică, de proiectare, în școli și institute n-a putut să nu reflecte și crearea cursurilor electronice, adică crearea manualelor electronice.

Din acest motiv, programatorii care au lucrat pe aceste PC-uri căutau posibilitățile de a realiza primele manuale electronice. Realizate de diferite firme creatoare de soft cu

renume mondial, in prezent există diferite formate digitale de realizare a manualelor electronice, cum ar fi .pdf, .djvu, .chm și altele. De asemenea, un manual electronic se poate crea în limbajul de marcare html, aceasta se folosește mai des pentru realizarea documentației pentru diferite produse soft.

Manualele electronice sunt instrumente eficiente de păstrare a informației din diversite domenii, permițindu-ne să stocăm un volum destul de mare de date, ceea ce dacă ar fi imprimat pe hîrtie, ar duce la cheltuieli mult mai mari.

Un manual electronic la o anumită disciplină, elaborat conform exigențelor moderne, este o sursă excelentă de studiere sau informare și de identificare rapidă a informațiilor solicitate. Pe scurt, manualele electronice ne ușurează experiența prin oferirea unui mijloc sigur și eficient de păstrare a datelor și de acces la acestea.

I. MANUALE ELECTRONICE

Folosirea calculatorului în procesul de învăţămînt se dovedeşte a fi o necesitate în condiţiile dezvoltării în ritm accelerat a tehnologiei informaţiei. Pentru noile generaţii de elevi şi studenţi, a devenit o cerinţă conceptul de asistare a procesului de învăţămînt cu calculatorul, în condiţiile avalanşei de informaţii multimedia. Manualele electronice sunt aplicații care reprezintă un mod de păstrare a datelor în calculator. Aceaste aplicații facilitează accesul la aceste date, conțin funcții avansate de căutare, cuprins, index, funcții de acces aleator la o anumită pagină, funcții de mărire/micșorare a conținutului, funcții de creare a notițelor și altele, în dependență de cerințele utilizatorilor.

1.1 Calculatorul instrument didactic

Se remarcă mai multe modalităţi de apariţie a calculatorului în procesul de predare/învățare:

Utilizarea calculatorului pentru tehnoredactarea computerizată a documentelor şcolare, cum ar fi cele care reprezintă rezultate ale proiectării didactice la nivel

micro, adică: planificări, proiecte de unităţi de învăţare, proiecte de lecţie, cît şi a unor documente de evidenţă şcolară cum ar fi cele legate de prezenţa la anumite activităţi didactice sau notarea evoluţiei elevilor la activităţile de verificare şi evaluare a cunoştinţelor.

Utilizarea calculatorului ca mijloc de predare în cadrul lecţiilor de comunicare de noi cunoştinţe, de recapitulare sau a prelegerilor în care calculatorul poate reprezenta suport al unor sinteze, imagini, figuri ce pot fi proiectate în scopul transmiterii de cunoştinţe. În felul acesta elevii au posibilitatea să vizioneze o expunere concretă şi clară a teoremelor, pot să aibă pe ecran imaginea unor fenomene sau procese simulate pe calculator.

Realizarea unor calcule numerice, mai mult sau mai puţin complicate, în scopul formării deprinderilor de calcul sau al eliberării de etapa calculatorie în rezolvarea unor probleme, prelucrarea unor date.

Realizarea unor bănci de date, adică stocarea de informaţii dintr-un domeniu oarecare într-o modalitate care să permită ulterior regăsirea informaţiilor după anumite criterii.

Învăţarea unui limbaj de programare.

Realizarea unor laboratoare asistate de calculator.

1.2 Tipuri de manuale electronice

Odată cu dezvoltarea tehnologiilor informaționale a apărut un nou tip de manual - manualele electronice. Acest tip de manual reprezintă o treaptă în evoluția instruirii asistate de calculator. Tipurile existente de manuale electronice sunt foarte diverse. Această diversitate se datorează, în primul rind, existenței diferitelor firme mari producătoare de soft, cum ar fi Adobe, care a creat formatul de manual electronic cel mai cunoscut - .pdf (public document format). Interfața unui manual electronic *.pdf este prezentată în Figura 1 de mai jos:

*.pdf est e prezentată î n Figura 1 de mai jos: Figura 1 Interfața unui manual

Figura 1 Interfața unui manual electronic în format *.pdf

Pe parcursul îndepliniri tezei, se va crea un manual electronic propriu, care va avea aspectul unui cărți adevărate (de hîrtie), aceasta realizîndu-se prin efectul de răsfoire a paginilor (engl. - flip-page). Acest manual va conține informații la disciplina Structuri de date și algoritmi. Am ales disciplina dată, deoarece aceasta reprezintă baza programării, odată fiind înțelese principiile fundamentale de programare, structurile de date frecvent utilizate și

algoritmii de implementare a acestora, le putem realiza cu ușurință în orice limbaj într- un timp relativ scurt. Cu toate că, în prezent, pentru majoritatea limbajelor de programare, au fost create diferite biblioteci de clase, funcții și algoritmi, precum și diferite framework-uri (de ex., Standard Template Library pentru C++, sau .NET Framework pentru C#, Visual Basic și alte limbaje), înțelegerea modului în care acestea au fost implementate ne va face să fim mai buni specialiști în domeniul Științei Calculatoarelor și Tehnologiilor Informaționale, lărgindu-ne orizonturile.

II. STRUCTURI DE DATE ȘI ALGORITMI

Cursul la disciplina “Structuri de date și algoritmi”, care a fost utilizat pentru crearea unui manual electronic în cadrul acestei teze de licență, are următoarea structură:

1. Elemente de programare avansată în limbajul C

2. Fișiere

3. Proiectarea și dezvoltarea sistematică a programelor de mari dimensiuni

4. Recursivitatea în C

5. Metode generale de proiectare a algoritmilor și programelor

6. Structuri de date dinamice

7. Tipuri de date abstracte

8. Tehnici de căutare și sortare

Deoarece toate cele 8 capitole se referă, într-o mare măsură la limbajele C/C++ (ceea ce ține de operațiile de Input/Output, lucrul cu pointeri, structure, uniuni etc.) și, ținind cont că volumul de date prezente în curs este destul de mare (peste 400 de pagini),

în acest capitol vom descrie un singur tip abstract de date, și anume Stiva, descriind operațiile de bază asupra acesteia, cum ar fi plasarea unui item sau extragerea unui item din vîrful acesteia.

2.1 Tipuri de date abstracte

2.1.1 Caracteristici

Conceptul de dată abstractă reprezintă gruparea într-o construcție de program unitară a unor date, împreună cu operațiile prin care se prelucrează aceste date, organizate ca funcții.

Acest concept generalizează noțiunea de tip: reprezintă atît mulțimea valorilor tipului cît și operațiile care pot fi executate asupra lor.

Un tip de date abstract (TDA) este o entitate manipulată doar prin operațiile ce definesc acel tip. Utilizatorul nu trebuie să aibă acces direct la reprezentarea internă a obiectului, ci numai prin intermediul acestor operații.

Limbajul C nu suportă direct datele abstracte.Tipurile abstracte pot fi totuși simulate folosind fișiere independente. Acest mod are propriile sale limitări: nu se pot defini tablouri de tipuri abstracte și nu se pot transmite parametri avînd ca și tip un tip abstract.

2.1.2 Avantaje

Avantajele utilizării tipurilor abstracte de date sunt:

1. Programele devin independente de modul de reprezentare a datelor (de exemplu, o mulțime poate fi implementată printr-un tablou sau printr-o listă ordonată, dar partea de program ce definește operatorii tipului abstract rămîne neschimbată.

2. Se previne violarea accidentală a datelor. Utilizatorul tipului abstract este forțat să manipuleze datele doar prin intermediul operatorilor ce compun tipul abstract (se reduce riscul unei distrugeri a datelor).

2.1.3 Stiva

Stiva este un tip special de listă în care toate inserțiile și suprimările de noduri au loc la un singur capăt (rful stivei).

Vom defini un tip abstract stivă cu următorii operatori:

1. Inițializarea stivei.

2. Verificarea faptului că stiva este plină.

3. Verificarea faptului că stiva este goală.

4. Introducerea unui element în vărful stivei.

5. Eliminarea unui element din vârful stivei.

6. Furnizarea elementului din vârful stivei fără a-l elimina.

Stiva va fi materializată printr-un tablou de numere reale (stiva), iar vîrful stivei

este indicat de variabila ind_top.

Toate declarațiile și definițiile trebuie să fie conținute într-un singur fișier. Atît

stiva t și ind_top sunt definite cu clasa de memorare static pentru a ascunde de

utilizator detaliile de implementare a stivei.

static double stiva[MAX]; /* stiva */

static int ind_top; /* virful stivei */

Funcțiile au implicit clasa de memorare extern. Ele pot fi apelate din alte fișiere,

iar toate operațiile asupra stivei sunt realizate doar prin intermediul lor.

Inițializarea stivei:

void init(void) { int i; for (i=0; i < MAX; i++) stiva[i] = 0; /* toate elementele devin 0 */ ind_top = -1; /*varful stivei indica primul elem. ocupat */

}

Verificarea faptului că stiva este plină:

int plin(void) { return ind_top == MAX - 1;

}

Verificarea faptului că stiva este goală:

int gol(void) {

return ind_top == -1;

}

Introducerea unui element în vârful stivei:

void push(double nr) { if (plin()) /* daca stiva este plina */

{

printf(“Eroare: stiva este plina\n”);

exit(1);

}

/* noul element este introdus in virful stivei*/ stiva[++ind_top] = nr;

}

Eliminarea elementului din vârful stivei:

void pop(void) { if (gol()) /* daca stiva este goala */

{

printf(“Eroare: stiva este goala\n”);

exit(1);

}

/* decrementeaza virful stivei*/

ind _top --;

}

Furnizarea elementului din vîrful stivei (fără a-l elimina):

double top(void) { if (gol()) /* daca stiva este goala */

{

printf(“Eroare: stiva este goala\n”);

exit(1);

}

/* returneaza elementul din varf*/ return stiva[ind_top];

}

III. Prezentarea tehnologiei WPF

WPF este imens. De fapt, poate fi copleşitor, deoarece are o mulțime de părți dinamice care se interconectează reciproc. De aceea, cel mai scurt răspuns la această întrebare, este că WPF este un API pentru construirea interfețelor grafice utilizator (UI) pentru aplicațiile desktop cu ajutorul .NET Framework. Acum urmează explicația detaliată. Pentru început, WPF este o abreviere pentru Windows Presentation Foundation. Fizic, este un set de asamblări .NET și instrumente ajutătoare. Are scopul de a ne oferi un API unificat pentru crearea interfețelor utilizator sofisticate, cu conținut bogat pentru Windows XP, Windows Vista, Windows 7 și generațiile ulterioare. WPF combină cele mai bune lucruri din web development, precum foile de stil și un limbaj de marcare pentru interfețele utilizator declarative, cu lucruri bune din aplicații Internet cu conținut bogat (Rich Internet Applications), cum ar fi grafica vectorială scalabilă, animația și suportul media. Aceste trăsături bune sunt împachetate cu cele mai bune trăsături ale dezvoltării aplicațiilor Windows tradiționale – trăsături precum integrarea puternică cu Sistemul de Operare (SO) și legarea datelor (data binding). În WPF, aceste concepte sunt consolidate și unificate. Chiar toate cele menționate, nu redau intreaga măsură a WPF. Aceasta are alte faţete, așa ca suportul pentru desenarea 3D, tipografia avansată și documente portabile similare cu PDF.

De asemenea, WPF este un API unificat. Multe din chestiile pe care le putem face în WPF, le puteam face și mai înainte. Totuși, făcîndu-le pe toate într-o singură aplicație era extreme de dificil. WPF nu ne permite numai să aducem aceste trăsături împreună, dar ne oferă un API consistent pentru a realiza aceasta. WPF este doar o parte a unei imagini mai largi. Trei biblioteci adiționale au fost create ca parte componentă a .NET 3.0. Toate aceste patru biblioteci au aceeași intenție de a oferi un API consistent, unificat pentru domeniul lor. În plus, combinînd oricare dintre aceste biblioteci într-o aplicație, se pot produce niște rezultate impresionante. Cele trei biblioteci care au fost eliberate impreună cu WPF sunt redate în Tabelul 1.

WCF

Windows Presentation Foundation este concentrată pe transmiterea mesajelor. Acest API simplifică enorm toate tipurile de comunicare și transmitere a mesajelor în rețea. Cuprinde totul, de la servicii web la P2P și multe altele.

WF

O bibliotecă puternică pentru construirea aplicațiilor care permit lucrul cu workflow (flux de lucru). Folosește un limbaj de marcare pentru declararea workflow-urilor într-o aplicație și de aceea previde workflow-ul de a fi hard-coded. De asemenea, ușurează munca dezvoltatorilor de a crea task-uri workflow personalizate.

CardSpace

Cel mai puțin renumită din cele patru biblioteci, CardSpace oferă un system de identificare comun, care poate fi utilizat de aplicații desktop, site-uri web, și multe altele.

Tabelul 1 Tehnologiile lansate împreună cu WPF

Predecesorul imediat al WPF este Windows Forms, API-ul grafic disponibil dezvoltatorilor în .NET 2.0 și mai devreme. Windows Forms oferă un wrapper controlat

pentru accesarea funcțiilor grafice ale API-ului Windows tradițional. WPF diferă fundamental prin faptul că ea construiește pe baza DirectX. API-ul DirectX era concentrat inițial pe multimedia și programarea jocurilor în particular. Ca atare, în WPF suntem capabili de a construi trucuri vizuale excepționale care erau practice imposibile în Windows Forms. Aceasta înseamnă, de asemenea, că WPF va profita de accelerearea hardware cînd aceasta va fi disponibilă. WPF mai are cîteva similitudini cu Windows Forms (și chiar cu ASP.NET Web Forms). Microsoft oferă o bibliotecă cu controale de bază așa ca casete de text și butoane. De asemenea, vom întîlni concept familiare, precum data binding și fișiere code-behind. Toate aceste concepte au fost rafinate și înbunătățite pentr WPF.

3.1 Caracteristicile WPF

În acest paragraf se vor descrie succint principalele caracteristici ale WPF.

3.1.1 Interfață utilizator declarativă (Declarative UI)

WPF ne permite să construim interfața utilizînd un limbaj de marcare numit XAML (se pronunță zammel, rimează cu cammel). Ne vom aprofunda în XAML în capitolul în care se crează aplicația, dar dacă am lucrat vreodată cu HTML, suntem déjà familiarizați cu aceste concepte. XAML este un limbaj de marcare mult mai bogat decît HTML, și are mai puțină ambiguitate. Visual Studio, precum și alți membri ai familiei de produse Expression, sunt capabile de a genara XAML nativ. XAML oferă un mediu comun de a interacționa cu designerii.

3.1.2

Poziționare inteligentă

Aranjarea pe ecran a diverselor componente ale unei aplicații poate fi complicată, iar ulterior poate fi complicată din cauza multitudinilor posibilități de afișare, pe care le pot avea utilizatorii. WPF oferă un sistem de paginare extensibil pentru a aranja vizual elementele unei interfețe utilizator. Aceasta se poate rediminsiona și ajusta inteligent, în dependență de cum definim layout-ul (paginarea).

3.1.3 Grafică scalabilă

Grafica în WPF este bazată pe vectori, în contrast cu grafica bazată pe raster. Grafica vectorială este în mod inerent scalabilă și, de obicei, necesită mai puțină memorie decît o imagine raster comparabilă. WPF încă mai are mult suport pentru grafica raster, însă vectorii sunt un mod excelent de a construi interfețele utilizator. Grafica vectorială a devenit deja populară pe web, în primul rînd din cauza Adobe Flash și, într-o proporție mai mică, datorită specificației graficii vectoriale scalabile (SVG Scalable Vector Graphics). Rezultatul final pentru dezvoltatorii WPF este că aplicațiile se redimensionează estetic, fără a-și pierde calitatea vizuală.

Vector versus Raster

Un grafic raster este o imagine care este păstrată ca o grilă dreptunghiulară de pixeli, iar fiecare pixel are atribuită o culoare. Cele mai multe formate de fișiere grafice cu care suntem familiari sunt doar variații ale acestei metode. Aceasta include formate precum GIF, JPEG, BMP și PNG.

Graficele raster sunt, de asemenea, numite bitmap-uri. (A nu se confunda cu formatul de fișier BMP. Termenul bitmap este un termen general, descriind un mod particular de a păstra datele de imagini). Să presupunem că avem o imagine raster a unui cerc albastru pe un fundal alb care este de 100×100 pixeli. Calculatorul încarcă acei 10.000 de pixeli în memorie și îi afișează pe ecran. Acestea sunt multe date pentru o imagine atît de simplă. Să ne imaginăm că avem nevoie de aceea imagine, dar de două sau de tri ori mai mare. Numărul de pixeli crește exponențial. Dacă am fi putut pur și simplu să-i furnizăm calculatorului două dimensiuni, poziția și culoarea formelor, atunci, am fi avut mult mai puține date de care să avem grijă. În acest fel, grafica raster este ineficientă. Altă problemă cu imaginile raster este că ele nu se redimensionează bine. Se obține o pierdere vizibilă a calității, în special atunci cînd mărim o imagine. Să presupunem că dorim să dublăm mărimea unei imagini a noastre de 100×100. Pentru a mări dimensiunea la 200×200, am avea nevoie de 390.000 de pixeli în plus. Acești pixeli care lipsesc vor trebui să fie interpolați din cei existenți. Grafica vectorială, totuși, este păstrată ca primitive geometrice. Structura de date pentru o imagine vectorială conține informație suficientă pentru calculator pentru a desena imaginea. O imagine vectorială a unui cerc albastru pe un fundal alb ar conține poziția x și y a cercului, raza acestuia și metadatele indicînd că cercul era albastru, iar fundalul alb. Cînd un calculator redă această imagine, acesta deduce pixelii actuali on- the-fly. Aceasta înseamnă că nu este nici o diferență în calitate între imaginea vectorială de 100×100 și imaginea de 100×100, și că mărimea datelor necesare de a desena imaginea este substanțial mai mică. O regulă generală este că grafica vectorială este bună pentru imaginile geometrice sau cele din desene animate, iar raster e mai bună pentru fotografi și imagini realistice.

3.1.4 Template-uri abloane)

WPF facilitează crearea elementelor reutilizabile pentru interfețele noastre utilizator. Există două tipuri de template-uri în WPF: controale template și data template. Controalele template ne permit de a redefini modul în care arată controlul. De exemplu, dacă aplicația noastră trebuie să aibă toate list box-urile cu un fundal albastru și o margine roșie, putem utiliza un template de control pentru a redefini apariția vizuală a list box-urilor. Controalele template, de asemenea, ușurează munca designer-ilor. Ei pot să ofere “look-ul” unui list box printr-un control template, cu puțin sau nici un impact asupra procesului de dezvoltare real. Data template-urile sunt similare, cu excepția că, în loc de a defini modul în care controlul arată, ele definesc modul în care anumite tipuri de date sunt redate. Să ne imaginăm că avem o aplicație care are de a face cu oameni, precum un manager de contacte, și că noi reprezentăm oamenii în cod prin instanțe ale unei clase Person. Putem crea un data template, care definește cum o instanță a unei clase Person este redată în UI. De exemplu, o instanță a clasei Person poate fi vizualizată ca un card business cu o imagine, numele, prenumele și numărul de telefon. Dacă utilizăm un asemenea data template, ori de cite ori o instanșă Person este legată de către careva element UI, așa ca un list box, WPF va folosi template-urile de date corespunzătoare. În practică, vom afla că template-urile de date sunt într-adevăr comode atunci cînd lucrăm cu liste sau alte colecții de date.

3.1.5 Legarea (Binding)

Atunci cînd vorbim despre binding în WPF, probabil ne duce gîndul imediat la conceptul de data binding. Data binding a fost deja popular cu Windows Forms și ASP.NET Web Forms, și a demonstrat utilitatea sa acolo. Cu toate că WPF are trăsături semnificative de data binding – semnificative în sensul că depăşește cu mult predecesorii

săi – aceasta ne permite, de asemenea, să legăm declarativ alte chestii, cum ar fi comenzi, legături cu tastele, animații și evenimente. De exemplu, putem lega declarativ un control buton cu o comandă Paste.

3.1.6 Stilizarea (Styling)

WPF într-adevăr strălucește atunci cînd trebuie să facem o aplicație să arate frumos. Aceasta ne permite să creăm astfel de lucruri cum ar fi să facem fundalul unui text box roșu sau să înconjurăm un buton cu o margine albastră subțire. Stilurile în WPF sunt similare cu foile de stil în cascadă pentru HTML. Cu toate că, încă o dată, stilurile WPF sunt mai bogate și au mai puțină ambiguitate. Ele cuprind toate caracteristicile vizuale pe care le așteptăm, așa ca umplerea, marginea, poziționarea, culoarea, ș.a.m.d. Însă putem, de asemenea, utiliza stiluri pentru a declara proprietăți nonvizuale. Stilurile sunt, de asemenea, ușor de reutilizat, iar atunci cînd le combinăm cu template-uri, suntem capabili să facem niște lucruri uimitoare.

3.1.7 Declanșatoare (Triggers)

Atît template-urile, cît și stilurile în WPF suportă noțiunea de trigger-e. Un trigger ne permite să-i spunem WPF ceva de genul: “Atunci cînd mouse-ul este deasupra unui buton, fă fundalul purpuriu.” Cu alte cuvinte, trigger-ele ne permit să dirijăm declarative schimbările de stare. De asemenea, le vom găsi utile atunci cînd vom crea animații.

3.1.8 Animație

Framework-ul pentru animație în WPF este foarte impresionant, și mult mai impresionant decît ne-am putea imagina. Majoritatea proprietăților în WPF pot fi animate, și există support pentru linii de timp (timelines), cadre cheie (key frames) și interpolare. Animațiile ușor se integrează cu template-urile și stilurile. De exemplu, putem defini un stil pentru un buton care animează butonul atunci cînd mișcăm mouse- ul deasupra lui. Dezvoltatorii Flash și designer-ii vor fi impresionați cu funcțiile disponibile.

3.1.9 3D

În sfîrșit, WPF permite unele modelări și 3D de bază și animație. S-a menționat de bază, deoarece WPF nu e destinată pentru construirea aplicațiilor 3D de înaltă performanță. Nu vom construi jocuri 3D în WPF (Dacă suntem interesați în asta, trebuie să-i dăm o privire platformei Microsft XNA). Cu toate acestea, trăsăturile 3D sunt puternice și ușor integrate în orice interfață utilizator.

3.1.10 De ce să utilizăm WPF

WPF, la fel ca bibliotecile sale surori eliberate cu .NET 3.0, sunt API-uri bine- factorizate și consistente. Ele unifică multe concepte de programare și, în ansamblu, fac mai ușoare o mulțime de sarcini de programare complicate. Totuși, WPF nu este neapărat alegerea corectă pentru fiecare proiect. Unele aplicații desktop ar fi mai ușor de construit și de întreținut utilizînd Windows Forms. Însă, vom găsi multe benficii atunci cînd lucrăm cu WPF. Orice programator Windows ar trebui să înceapă a învăța WPF, deoarece aceasta va ajunge la un punct cînd va înlocui complet Windows Forms.

Urmează cîteva scenarii unde WPF într-adevăr strălucește:

Proiectul nostru necesită colaborarea cu designeri. Utilizarea XAML și instrumentelor de suport ale acestuia pot ajuta cu adevărat aici. După ce programatorii și designerii devin familiarizați cu instrumentele, echipa lor poate avea cîștiguri extraordinare în eficiență.

Aplicația noastră este conștientă de media. Dacă avem nevoie să integrăm video și audio în proiectul nostru, vom dori cu siguranţă să luăm în considerare WPF.

Hardware-ul anticipat pentru aplicația noastră are suport pentru DirectX 9 sau mai mare. WPF este construit deasupra la DirectX, iar aplicațiile noastre vor beneficia de accelerare hardaware.

Aplicația noastră necesită suport pentru tipografie avansată. WPF are suport pentru OpenType și multe alte funcții care nu sunt disponibile cu Windows Forms.

În sfîrșit, ca dezvoltatori, putem face mai multe în mai puțin timp. Chiar dacă nu suntem preocupați de toate detaliile WPF, vom fi capabili să construim software de calitate cu mai puțin efort.

3.1.11 Compararea WPF cu alte opțiuni

Dacă suntem numai programatori .NET, într-adevăr avem numai două alte opțiuni de considerat: Windows Forms și ASP.NET. Deja s-au comparat WPF și Windows

Forms pe parcursul acestui capitol. Unicele avantaje reale pe care Windows Forms le are sunt biblioteca sa imensă de controale și suport third-party semnificativ. WPF încă este “noul copil la bloc”, iar mulțimea de instrumente și materiale încă nu au avut timp să fie construite. Compararea WPF cu ASP.NET implică puțin mai multe. Întrebarea aici se centrează într-adevăr pe implementare și distribuție. WPF este, la moment, limitată la platform Windows, și, evident, nu există așa limitare într-o aplicație web. WPF necesită .NET Framework 3.0 sau mai superior, precum și un mijloc de implementare a aplicației. Dacă aplicația noastră este centralizată, necesitînd una sau mai multe component server, va trebui probabil să reducem semnificativ complexitatea, alegînd să dezvoltăm o aplicație web. În afara lumii .NET, unele din aceleași caracteristici sunt disponibile cu Adobe Flash, în primul rind cînd este vorba de media și animație. Istoric, Flash într-adevăr a fost util numai în contextul Web. Totuși, platform Adobe Air utilizează Flash pentru a dezvolta aplicații desktop cross-platform. Cu toate acestea, Flash încă mai are unele dezavantaje notabile. Mediul de dezvoltare nu este la fel de robust ca .NET, cu toate că, indiscutabil, Flash tinde să fie mai mult pritenos pentru designer. Bibliotecile de controale pentru Flash sunt mult mai limitate și greu de folosit. Este posibil ca AIR va deveni un adevărat concurrent al WPF.

3.1.12 Părțile componente și versiunile .NET Framework

Fiecare versiune a .NET Framework conține motorul comun de execuție (CLR – common language runtime) ca component sa de bază, și include component adiționale, precum bibliotecile cu clase de bază (base class libraries) și alte biblioteci managed. Aici vom descrie componentele cheie ale versiunilor .NET Framework, vom discuta despre

versiunile CLR de bază și mediile de dezvoltare asociate, și vom identifica versiunile care sunt instalate pe Windows. Figura 2 ilustrează istoria versiunilor și care versiuni sunt instalate pe Windows.

versiunilor și care versiuni sunt instalate pe Windo ws. Figura 2 Versiunile de .NET Framework 3.1.13

Figura 2 Versiunile de .NET Framework

3.1.13 Caracteristici incluse în versiunile .NET Framework

Versiunea .NET Framework

Versiunea

Versiunea

 

CLR

Visual Studio

Descrierea

   

Visual Studio

Conține prima versiune a CLR și prima versiune a base class libraries.

1.0 1.0

.NET

   

Visual Studio

Include update-uri pentru ASP.NET și ADO.NET. Această versiune a fost

1.1 1.1

.NET 2003

     

ulterior înnoită de 2 ori, cu Service Pack 1 (Sp1) și SP2. Această versiune a introdus, de asemenea, execuția side- by-side, care permite aplicațiilor pe un singur PC să ruleze pe diferite versiuni ale CLR.

   

Visual Studio

A introdus o nouă versiune a CLR cu adaosuri la base class libraries, inclusiv tipuri generice, colecții generice, și adaosuri semnificative la ASP.NET. Această versiune este ulterior înnoită cu SP1 și SP2.

2.0

2.0

.NET 2005

   

Visual Studio

Această versiune este în principal .NET Framework 2.0 cu adăugarea WPF, WCF, WF și CardSpace. A fost ulterior înnoită cu SP 1 și SP 2.

3.0

2.0

.NET 2005

   

Visual Studio

A adăugat noi caracteristici, așa ca site- uri Web AJAX-enabled și LINQ. SP1 a

3.5

2.0

.NET 2008

adăugat .NET Framework Client Profile, Dynamic Data și un mic set de înbunătățiri adiționale.

   

Visual Studio

Include o nouă versiune de CLR, a base class libraries extinse, și noi trăsături,

4

4

.NET 2010

precum Managed Extensibility Framework (MEF), dynamic language runtime (DLR) și contracte de cod.

3.1.14

Instrumente pentru WPF

La elaborarea acestei teze, am lucrat, în primul rind, cu Visual Studio 2010. În mod specific, am utilizat ediția Express, care este oferită gratis de firma Microsoft. Visual Studio 2010 oferă support nativ pentru aplicații WPF.

Ediția

Express

a

Visual

Studio

2010

este

disponibilă

la

www.microsoft.com/express/, împreună cu alte resurse.

Este posibil de construit aplicații WPF și cu versiunile precedente, adică Visual Studio 2008, Visual Studio 2005 (cu toate că în cazul Visual Studio 2005, va trebui să instalăm niște extensii Visual Studio, care n-au ajuns în realease-ul final al acestuia). De asemenea, putem utilize SharpDevelop (cunoscut și ca #develop). Este, de asemenea, un mediu integrat de dezvoltare (IDE Integrated Development Environment) open-source pentru .NET, și are suport pentru construirea aplicațiilor WPF în .NET 3.0. Este un IDE solid, însă este destul de greu să atingem nivelul de suport pentru WPF oferit de Visual Studio. Al doilea instrument major pentru crearea aplicațiilor WPF de la Microsoft este Expression Blend. Blend targhetează designerii mai degrabă decît programatorii. Lucrează cu aceleași fișiere ca și Visual Studio, așa că un designer care utilizează Blend și un programator care folosește Visual Studio, pot lucre ambii la aceleași proiecte, soluții și fișiere. Blend este oarecum comparabil cu IDE-ul pentru Adobe Flash. Vom găsi aici instrumente de desenare, linii de timp pentru animații, palete și alte funcții centrale pentru designeri. În ciuda scopului acestuia, se recomandă ca și programatorii să devină familiarizați cu Blend. Blend este, de asemenea, unul din primele produse de la Microsoft scrise cu WPF. Un produs third-party există pentru proiectarea interfețelor WPF – Aurora, creat de Mobiform Software. Acesta furnizează un set asemănător de caracteristici ca și

Expression Blend. O trăsătură notabilă este că designerul Aurora poate fi integrat în altă aplicație WPF. Deci, dacă avem nevoie de a oferi un editor XAML în aplicația noastră, putem să utilizăm acest produs. Expression Design este alt produs de la Microsoft. Acesta este destinat creării conținutului grafic bazat pe vectori, similar cu Adobe Illustrator sai Inkscape. Expression Design poate fi folosit pentru crearea de logo-uri, icon-uri și ilustrații pentru utilizarea cu WPF. Poate produce grafică ca XAML, care poate fi apoi încorporată direct în WPF. Expression Design diferă de Blend, prin faptul că scopul primar al Blend este pur și simplu crearea interfețelor utilizator. Multe alte aplicații pentru producerea artei 2D și 3D au acum plug-in-uri disponibile pentru transformarea și exportarea în XAML (XAML este limba nativă a WPF). Unele din aplicațiile care au plug-in-uri disponibile sunt Adobe Fireworks, Adobe Illustrator, Inkscape, Maya, Blender și Lightware. În afară de instrumentele 3D menționate pînă acum, este disponibil cel puțin un editor specific WPF ZAM 3D, creat de Electric Rain. ZAM 3D este foarte similar cu produsul Swift3D pentru Flash. Este mai abordabil decît majoritatea editoarelor 3D și este probabil cel mai bun loc pentru a începe pentru dezvoltatorii interesați în WPF. Un instrument final care merită menționat este Kaxaml. Acesta este un editor XAML lightweight, care oferă un live preview. Aceasta înseamnă că putem vedea cum WPF va reda markup-ul nostru în timp ce scriem. Este un instrument foarte util de avut la îndemînă, și la momentul de față este gratuit. Multe alte instrumente, utilitare, biblioteci de controale, și așa mai departe, sunt disponibile în fiecare zi. Unele sunt produse comerciale third-party, altele sunt create de comunitatea de programatori și sunt gratuite. Pentru simplicitate, vom utilize Visual Studio 2010, care oferă toate cele necesare, inclusiv funcția WYSIWYG (what-you-see- is-what-you-get).

3.1.15

WPF în contrast cu Silverlight

Silverlight este o platform pentru dezvoltarea aplicațiilor internet cu conținut bogat (RIA - Rich Internet Applications), pe cînd WPF are tendința primară pentru aplicațiile desktop. Silverlight este un competitor direct pentru Adobe Flash și pune un accent puternic pe media, compatibilitate cross-platform, precum și pe mărimea mică pentru download și instalare. La fel ca Flash, Aplicațiile Silverlight sunt găzduite într-un browser. Microsoft a proiectat intenționat Silverlight ca să fie foarte asemănător cu WPF,cu toate că acestea sunt două produse separate. De fapt, un nume inițial pentru Silverlight fusese WPF/E sau Windows Presentation Foundation / Everywhere. Dezvoltatorii familiari cu o tehnologie, vor avea un punct de pornire cu cealaltă. La fel ca WPF, Silverlight folosește XAML pentru declararea interfețelor utilizator. În versiunea 1.0, o aplicație Silverlight constă numai din fișiere textuale care conțin JavaScript și XAML. Totuși, Silverlight 2.0, va suporta un runtime mai robust și o bibliotecă de clase de bază similar cu standardul .NET BCL. Vom putea scrie aplicații Silverlight în limbajul nostrum .NET preferat și să le compilăm la asamblări pentru distribuire. Silverlight 2.0 va arăta mult mai mult ca WPF, însă trebuie să fim conștienți că există diferențe semnificative. Este aproape sigur că Silverlight nu va suporta toate caracteristicile WPF. De asemenea, codul scris pentru Silverlight poate necesita schimbări semnificative înainte de a fi compilat pentru o aplicație standard .NET. Trebuie să avem în vedere întotdeauna că runtime-ul pentru Silverlight este diferit de CLR.

3.2 Limbajul XAML

XAML, sau Extensible Aplication Markup Language (limbaj de marcare al aplicației extensibil), este un limbaj bazat pe XML creat de Microsoft. Este fundamental pentru WPF la fel ca HTML pentru dezvoltarea web.

3.2.1 Definiția XAML

XAML (pronunțat zammel) este limbajul folosit pentru crearea interfețelor utilizator în WPF. Este un limbaj bazat pe XML similar cu HTML, MXML, sau XUL. XAML are aplicabilitate reușită și în afara definirii interfețelor utilizator. De fapt, este chiar posibil de a reprezenta date cu XAML, precum un table de șiruri sau o instanță a unui obiect. XAML este utilizat, de asemenea, de Windows Workflow Foundation (WF) pentru definirea de workflow-uri. În sensul cel ma general, XAML este un limbaj pentru serializarea instanțelor obiectelor .NET într-un format lizibil omului. Chiar dacă Visual Studio 2010 oferă un editor WYSIWYG cu support drag-and- drop pentru producerea și manipularea XAML, va trebui adesea să edităm marcajul direct. Vom scrie XAML-ul nostrum cu mina aproape în întreaga aplicație. Extensia de fișier implicit este .xaml. XAML poate fi sau compilat, sau interpretat, în dependență de cum este utilizat. Unele funcții, precum încadrarea codului C# sau VB în XAML, lucrează numai cînd XAML este compilat. Atunci cînd creăm o aplicație WPF cu Visual Studio, XAML-ul folosit în aplicație este compilat în executabilul rezultat. Totuși, putem crea fișiere .xaml care intenționează să fie interpretate on-the-fly (nu este implicată nici o compilare). Aceste fișiere XAML sunt găzduite de obicei într-un browser web. Crearea unui program simplu “hello world” se poate realiza în felul următor:

1. Deschidem un editor de text preferat, cum ar fi Notepad sau Notepad++

2. Creăm un document textual simplu și introducem următorul cod:

<Page xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

<TextBlock Text=”Hello World!” /> </Page>

3. Salvăm documentul li îl numim HelloWorld.xaml

4. Facem dublu-click pe fișierul nou creat și ar trebui să se deschidă într-un

browser web. Dacă s-a deschis automat cu altă aplicație, va trebui să lansăm

mai întîi browser-ul (Internet Explorer sau Mozilla Firefox), apoi să tragem

fișierul în browser.

Astfel, am creat prima aplicație WPF, utilizînd XAML. HelloWorld.xaml este un exemplu de XAML interpretat, deoarece noi nu am compilat aplicația într-un executabil. Aplicațiile compuse numai din XAML sunt foarte

limitate, iar în viața reală vom folosi mai degrabă XAML înpreună cu C# sau VB.

În HelloWorld.xaml, observăm că elementul rădăcină este tag-ul Page. Există și

alte posibilități, cel mai frecvent fiind tag-ul Window. Cînd creăm XAML, elemntul

nostru rădăcină întotdeauna definește două spații de nume. Spațiul de nume implicit se

mapează specific în WPF, iar prefixul x: este pentru caractersiticile mai generice ale

XAML. După cum s-a mențioonat, XAML poate fi utilizat pentru reprezentarea oricăror

tipuri de date; am utilizat spațiul de nume implicit pentru a spune că reprezentăm date

despre WPF. Spațiul de nume x: reprezintă un context mai larg. Poată să pară ceva

înapoiat, însă în general nu se utilizează spațiul de nume x la fel de mult precum cel

implicit. Aceste alias-uri pentru spațiile de nume reprezintă o convenție, adoptată de

Microsoft.

Spațiile de nume în XAML sunt adesea confundabile dacă nu am lucrat cu ele mai

înainte. Ele au aceeași funcție ca și spațiile de nume în .NET, el oferă un domeniu pentru

nume unice.

Este similar ideii de a avea doi oameni numiți John Smith. Pentru a-i distinge,

trebuie să-i numim John Smith din Chicago și John Smith din Boston. Includerea locului de unde ei vin este analog cu spațiul de nume. Atunci cînd două lucruri se numesc la fel, și nu le putem distinge, se numește coliziune de nume.

3.2.2 Sintaxa XAML

Ca o regulă generală, un element în XAML este o instanță a unui obiect, iar atributele reprezintă proprietățile acelui obiect. Marcajul din Lisingul reprezintă codul unui simplu buton pe o pagină.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Button x:Name="blueButton"

Width="100"

Height="40"

Background="Blue" Content="Click Me" />

</Page>

Elementul rădăcină corespunde unei instanțe a Page, mai precis System.Windows. Controls.Page, iar orice se află în spațiul de nume System.Windows.Controls, este un control WPF. Elementul Button corespunde unei instanțe a clasei System.Windows.Controls. Button. La rîndul lor, atributele elementului Button reprezintă propritățile unei instanțe obiect. De aceea, am setat valorile pentru proprietățile Width, Height, Background și Content. Avem, de aeemenea, atributuk x:Name, care strică regula aici. x:Name nu este o propietate a clasei Button. În schimb, este un atribut special care oferă un identificator unic obiectului pentru a-l accesa în cod. Este la fel ca și cum am crea o variabilă de tipul Button cu numele blueButton. Elementul Button din exemplul precedent este echivalent cu următorul cod C#:

Button blueButton = new Button(); blueButton.Width = 100; blueButton.Height = 40; blueButton.Content = "Click Me"; blueButton.Background = new SolidColorBrush(Colors.Blue);

Proprietatea Background este puțin mai complex decăt celelalte. Este important ca elemental XAML la care dorim să ne referim, în cod sau oriunde în XAML, să posede o valoare unică pentru x:Name. Atribuirea unei valori lui x:Name este ca și cum am crea o variabilă și i-am atribui instanța unui obiect.

3.2.3 Setarea proprietăților care nu sunt tipuri simple

În calsa Button, Width și Height sunt tipuri simple de date. WPF convertește valoarea string 100 la un double implicit. Totuși, multe proprietăți ale controalelor nu sunt tipuri de date simple. Unele proprietăți sunt obiecte care ele însuși au o mulțime de proprietăți. În exemplu de mai sus, proprietatea Background a butonului este de tipul SolidColorBrush. În XAML, putem pur și simplu să declarăm Blue și va merge. Există multe locuri în XAML unde tipuile frecvent utilizate, precum SolidColorBrush, pot fi reprezantate de o valoare string simplă, pe care WPF știe cum să o trateze. În cazul SolidColorBrush, putem scrie orice culoare care este prezentă în clasa System.Windows.Media.Colors, sau putem scrie o reprezentare hexagesimală a culorii similară cu cele utilizate în HTML sau CSS. Următoarele fragmente XAML sunt echivalente:

<Button Background="#FF0000FF" /> <Button Background="Blue" />

Totuși, în unele situații, această prescurtare nu este suficientă pentru a-i spune

WPF ceea ce dorim. În acele cazuri, putem folosi sintaxa elementelor proprietate.

Sintaxa elementelor proprietate este o sintaxă alternativă folosită pentru a atribui valori

de tipuri complexe. În locul setării proprității Background folosind un atribut, putem

folosi un element copil. Următorul fragment demostrează utilizarea acestei sintaxe

alternative pentru setarea fundalului la albastru:

<Button>

<Button.Background>

<SolidColorBrush Color="Blue" /> </Button.Background> </Button>

Elementul copil este referit ca un element proprietate. Elementele proprietate au forma <ClassName.PropertyName />. Prima parte este numele clasei, urmată de un punct, urmatp de numele proprietății. Conținutul elementului copil este valoarea pe care dorim să o setăm. Cînd utilizăm un element proprietate, trenuie să fim mai expliciți și să-i spunem WPF că dorim ca valoarea să fie o instanță a SolidColorBrush cu proprietatea Color setată la albastru. Se recomandă de autiliza prescurtarea ori de cite ori este posibil. Marcajul succinct este mai ușor de citit și face intenția XAML mai clară.

3.2.4 Proprietatea Content

Multe din controalele WPF pe care le întîlnim au o proprietate numită Content. Aceasta este una special. În listingul de mai jos, se setează conținutul unui buton la a valoare string, Click Me. Totuși, putem de asemenea seta proprietatea Content implicit, folosind un element copil. De exeplu, următoarele elemente XAML sunt echivalente:

<Button Content="Click Me" /> <Button>Click Me</Button>

Ambele butoane vor fi redate la fel în WPF. Ce este interesant, este faptul că Content este de fapt, de tipul object. Aceasta înseamnă că putem face conținutul unui buton mult mai mult decît un simplu string. De exemplu, se prea poate că vom dori să desenăm un cerc galben în interiorul butonului. Putem utilize următorul XAML:

<Button> <Ellipse Width="24"

</Button>

Height="24"

Fill="Yellow" />

Putem, de asemenea, să setăm propritatea Content explicit:

<Button> <Button.Content> <Ellipse Width="24"

Height="24"

Fill="Yellow" /> </Button.Content> </Button>

Totuși, făcînd asta, este mai mult de scris și nu facem nimic pentru a mări lizibilitatea sau mentenabilitatea codului. Mai mult ca atît, convenția de a seta implicit propritatea Content este aproape universal adoptată.

3.2.5 Extensii de Markup

Uneoeri, trebuie să specificăm valori în markup-ul nostru care sunt sau dificil de exprimat în XAML sau în afara domeniului procesorului XAML. XAML posedă o funcție numită markup extensions, și aceasta ne permite să tratăm aceste situații. De exemplu, să presupunem că avem o culoare specific pe care dorim să o utilizăm ca fundal pentru căteva butoane într-o aplicație WPF. Am putea seta proprietatea Background pentru fiecare buton pentru a folosi aceeași culoare, însă ar deveni laborios dacă vom avea nevoie vreodată să schimbăm acea culoare. Cu WPF, putem păstra culoarea cu o cheie în resursele unei aplicații. Acum puytem seta fundalul butoanelor în culoarea pe care am stocat-o în resurse. Daca dorim să schimbăm culoarea, trebuie să facem asta numai într-un singur loc. Acesta este un scenario plăcut, însă cum se poate de tratta aceasta în XAML. Vom folosi o extensie de marcaj.

În scenariul precedent, XAML-ul cu extensia de marcaj poate arăta astfel:

<Button Background="{StaticResource ResourceKey=myColor}" Content="Click Me" />

Extensiile de marcaj sunt identificate prin prezența acoladelor ({}). Primul cuvînt în markup extension îi spune WPF ce fel de extensie este. Numele extensiei este opțional urmat de un set de parametri numiți. În acest caz, extensia este pentru a primi o resursă partajată dintr-o bibliotecă de resurse. Numele extensiei este StaticResourse, iar noi furnizăm o valoare de myColor pentru parametrul ResourceKey. Multe extensii au un parametru implicit. Putem omite numele parametrului și semnul egal. De exemplu, am putea rescri fragmenul cu ResourceKey=:

<Button Background="{StaticResource myColor}" Content="Click Me" />

ResourceKey este parametrul implicit pentru StaticResource. În unele cazuri, vom avea mai mult de un parametru. Dacă va fi așa, tebuie să separăm perechile nume/valoare prin virgule. Modelul general este:

{ExtensionName Param1=Value1, Param2=Value2, Param3=Value3}

Cea mia frecventă greșeală în lucrul cu extensii markup este de a include ghilimele în jurul valorilor. Nu se permite să avem ghilimele între parantezele acolade. Aceasta face parser-ul confuz. Aceasta înseamnă , de asemenea, că valorile parametrilor nu pot conține spații albe. Multe extensii de markup sunt construite în WPF, iar noi putem chiar să scriem pe ale nostre (totuți, nu se obișnuiește de a face așa). Vom descrie extensii specifice în următorul capitol; totuși, Tabelul 2 oferă un rezumat foarte scurt a celor mai semnificative extensii.

Numele

Descrierea

Binding

Extensia folosită pentru legarea datelor.

StaticResource

Aceasta e foloosită pentri a primi datele din resursele unei aplicații. Nu se așteaptă ca resursele statice să se schimbe cît timp aplicația rulează.

DynamicResource

Similar cu StaticResource, cu excepția că datele în resursă se pot schimba în timpul execuției.

x:Null

Se utilizează pentru a specific o valoare null în XAML.

x:Type

Această extensie e folosită pentru a furniza un obiect System.Type.

X:Array

Aceasta permite de a defini un vector de obiecte în XAML.

Tabelul 2 Extensiile markup frecvente în WPF

IV. REALIZAREA MANUALULUI ELECTRONIC

Manualul electronic a fost realizat în 2 etape: mai întîi a fost important un proiect existent, de tip Class Library, cu numele WpfBookControls, care conține clasele BookPage, Book și alte structuri și enumerări adiționale, apoi a fost creat proiectul principal, cu numele WpfAppTezaDeLicenta, unde s-au utilizat controalele din primul proiect și a fost integrat conținutul disciplinei “Structuri de date și algoritmi” în aplicație.

4.1 Proiectul WpfBookControls

Proiectul WpfBookControls este un proiect de tip bibliotecă. Modul în care acesta a fost creat, permite de a fi ușor reutilizat în alte aplicații, sau de a fi extins, adăugîndu-i-se posibilități noi, și apoi utilizat. În acest paragraf se va descrie modul de implementare a acestuia (Vezi ANEXA 1).

4.1.1 Modulul cu tipuri de date auxiliare

Inițial, a fost creat fișierul UtilityItems.cs, care conține două enumerări, o clasă static și o structură, după cum urmează:

public enum CornerOrigin { TopLeft, TopRight, BottomLeft, BottomRight }; public enum PageStatus { None, Dragging, DraggingWithoutCapture, DropAnimation, TurnAnimation }

Semnificațiile acestora sunt evidente, datorită denumirilor sugestive. Urmează clasa LinearGradientHelper, care are umătoarea structură:

static class LinearGradientHelper

{

 

public static void ComputePoints(double controlWidth, double controlHeight, double x, double y, double r1, double r2, CornerOrigin fromCorner, out Point startPoint, out Point endPoint) { … }

public static void ComputePointsFromTop(double controlWidth, double controlHeight, double x, double y, double r1, double r2, CornerOrigin fromCorner, out Point startPoint, out Point endPoint) { … }

}

Aceasta se utlizează cînd se dorește calcularea coordonatelor paginilor atunci cînd acestea sunt răsfoite. Aceasta este necesară, deoarece paginile folosesc un gradient, care va trebui să-și schimbe coordonatele în dependență de poziția paginii. Mai jos avem structura PageParameters, care se utillizează pentru păstrarea parametrilor unei pagini. Aceasta conține 14 cîmpuri private, fiecare avînd proprietățile setter și getter corespunzătoare. Constructorul cu un parametru inițializează aceste date.

Struct PageParameters

{

private double _page0ShadowOpacity; private double _page1RotateAngle; private double _page1RotateCenterX; private double _page1RotateCenterY; private double _page1TranslateX; private double _page1TranslateY; private PathFigure _page1ClippingFigure; private PathFigure _page2ClippingFigure; private Point _page1ReflectionStartPoint; private Point _page1ReflectionEndPoint; private Point _page0ShadowStartPoint; private Point _page0ShadowEndPoint; public Point Page0ShadowEndPoint private Size _renderSize;

public PageParameters(Size renderSize)

{

_page0ShadowOpacity = 0; _page0ShadowEndPoint = new Point(); _page0ShadowStartPoint = new Point(); _page1ClippingFigure = new PathFigure(); _page1ReflectionEndPoint = new Point(); _page1ReflectionStartPoint = new Point(); _page1RotateAngle = 0; _page1RotateCenterX = 0; _page1RotateCenterY = 0; _page1TranslateX = 0; _page1TranslateY = 0; _page2ClippingFigure = new PathFigure(); _renderSize = renderSize;

}

}

4.1.2 Controlul BookPage

Controlul BookPage moștenește de la System.Windows.Controls.ContentControl, ceea ce înseamnă că acest control poate avea orice conținut – text, imagini, fotografii, video, animații, și are partea de design, vezi ANEXA 2, iar clasa definită în code-behind, este definită în două fișiere și are următoarea strucură:

Fișierul “BookPage.xaml.cs

namespace WpfBookControls

{

partial class BookPage : System.Windows.Controls.ContentControl

{

private const int animationDuration = 500;

private const double gripSize = 30;

internal CornerOrigin origin = CornerOrigin.BottomRight;

public PageStatus Status { … }

private Point CornerPoint { … }

public bool IsTopLeftCornerEnabled { … }

public bool IsTopRightCornerEnabled { … }

public bool IsBottomLeftCornerEnabled { … }

public bool IsBottomRightCornerEnabled { … }

public static readonly RoutedEvent PageTurnedEvent;

public static DependencyProperty CornerPointProperty; public static DependencyProperty IsTopLeftCornerEnabledProperty; public static DependencyProperty IsTopRightCornerEnabledProperty; public static DependencyProperty IsBottomLeftCornerEnabledProperty; public static DependencyProperty IsBottomRightCornerEnabledProperty;

private void ApplyParameters(PageParameters parameters) { … } void anim_Completed(object sender, EventArgs e) { … } void anim_CurrentTimeInvalidated(object sender, EventArgs e) { … } private void OnMouseDown(object sender, MouseButtonEventArgs args) { … } private void OnMouseUp(object sender, MouseButtonEventArgs args) { … } private void OnMouseMove(object sender, MouseEventArgs args) { … } private void OnMouseLeave(object sender, MouseEventArgs args) { … }

private static int ComputeAnimationDuration(UIElement source, Point p, CornerOrigin origin) { … } private static double ComputeProgressRatio(UIElement source, Point p, CornerOrigin origin) { … } private bool IsOnNextPage(Point p, UIElement source, CornerOrigin origin) { … } private void DropPage(int duration) { … } public void TurnPage() { … } private void TurnPage(int duration) { … } public void AutoTurnPage(CornerOrigin fromCorner, int duration) { … }

}

}

În Tabelul 3 de mai jos sunt descrise datele membre ale clasei de mai sus:

Denumirea

Descrierea

animationDuration

Constantă ce definește perioada de autorăsfoire a unei pagini (în milisecunde).

gripSize

Constantă ce definește lungimea laturii patratului invizibil din fiecare colț al paginii, deplasarea mouse-ului pe suprfața acestuia declanșînd un eveniment.

origin

Definește originea colțului de unde va fi trasă foaia la

 

răsfoire. Implicit, va fi Dreapta-Jos.

Status

Proprietate de tip PageStatus, care definește starea paginii. Initial va avea valoarea PageStatus.None.

CornerPoint

Proprietate de tip Point, care definește coordonatele punctului dintr-un oarecare colț al paginii.

IsTopLeftCornerEnabled

Proprietate de tip bool, care ne indică dacă colțul Stînga-Sus este activ. Sunt definite încă trei astfel de proprietăți pentru fiecare colț, cu numele respective.

PageTurnedEvent

Evenimentul static care se produce răsfoirea paginii.

CornerPointProperty

Proprietate dependență, care împreună cu alte patru astfel de proprietăți, precum și evenimentul precedent, se vor înregistra în constructorul static (dependency properties se declară întotdeauna statice, el permit ușor ca să se lege unele evenimente cu triggere, alte evenimente etc.)

Tabelul 3 Datele membre ale clasei BookPage

În Tabelul 4 “BookPage.xaml”:

de mai jos sunt descrise metodele clasei BookPage din fișierul

Denumirea

Descrierea

ApplyParameters

Aplică noii parametrii pentru pagina curentă.

anim_Completed

Se apelează atunci cînd pagina începe să fie răsfoită, sau este oprită, apelind funcția precedentă, apoi schimbînd starea cărții.

anim_CurrentTimeInvalidated

Similară cu cea precedent, însă apelează și altă funcție,

 

care

calculează

coordonatele

paginii,apoi

se

redesenează.

 

OnMouseDown

Se apelează atunci cînd mouse-ul are butonul click-

stînga apăsat.

 

OnMouseUp

Se apelează atunci cînd mouse-ul eliberează butonul

click-stînga.

 

OnMouseMove

Se apelează atunci cînd mouse-ul se mișcă în preajma

colțului paginii.

 

OnMouseLeave

Se apelează atunci cînd mouse-ul părăsește aria colțului

paginii.

ComputeAnimationDuration

Funcții auxiliare, ce se folosesc la calcule în timpul

ComputeProgressRatio

animației unei pagini.

 

DropPage

Se apelează cînd pagina se oprește

 

TurnPage

Această funcție are două supraîncărcări. Primul tip are

un parametru duration, care exprimă cît timp va dura

răsfoirea unei pagini. Al doilea – o apelează pe prima cu

valoarea variabilei animationDuration, care este de 500

milisecunde.

 

AutoTurnPage

Crează animație efectului de răsfoire a unei pagini.

 

Tabelul 4 Funcțiile clasei BookPage

În fișierul “BookPage.Compute.cs”, clasa BookPage mai conține trei metode:

una pentru resetarea paginii, alta pentru calcularea coordonatelor paginii și ultima pentru

a verifica niște parametri ai pagii.

4.1.3

Controlul Book

Ca orice alt control din WPF, acesta posedă partea de design (vezi ANEXA 3) și partea funcțională. Clasa Book moștenește de la ItemsControl, ceea ce înseamnă că poate conține o colecție de itemi. Aceasta este definită în fișierul “Book.xaml.cs”, care are următoarea structură:

Fișierul “Book.xaml.cs”

public partial class Book : ItemsControl

{

 

private PageStatus _status = PageStatus.None; private int _currentSheetIndex = 0;

internal object GetPage(int index) { … } private void OnLoaded(object sender, RoutedEventArgs args)

public void AnimateToNextPage(bool fromTop, int duration) { … } public void AnimateToPreviousPage(bool fromTop, int duration) { … }

public int GetItemsCount(){ … } private void RefreshSheetsContent(){ … } private void OnLeftMouseDown(object sender, MouseButtonEventArgs args) { … } private void OnRightMouseDown(object sender, MouseButtonEventArgs args) { … } private void OnLeftPageTurned(object sender, RoutedEventArgs args) { … } private void OnRightPageTurned(object sender, RoutedEventArgs args) { … }

public BookDisplayMode DisplayMode { … } public BookCurrentPage CurrentPage { … }

private void AnimateToLeftSheet(){ … } private void AnimateToRightSheet(){ … } public void MoveToNextPage(){ … } public void MoveToPreviousPage(){ … }

public enum BookDisplayMode { Normal, ZoomOnPage } public enum BookCurrentPage { LeftSheet, RightSheet }

 

}

}

În interiorul clasei, avem definite două enumerări: BookDisplayMode și BookCurrentPage. Semnificația lor este evidentă. Descrierea datelor membre ale clasei Book este reprezentată în Tabelul 5.

Denumirea

Descrierea

_status

Definește starea unei pagini. Inițial este Status.None.

_currentSheetIndex

Definește pagina indexul paginii curente. Inițial este zero.

Tabelul 5 Cîmpurile clasei Book

În Tabelul 6, se descriu funcțiile principale din clasa dată, împreună cu descrierea lor.

Denumirea

Descrierea

GetPage

Funcție internă ce returnează o pagină cu indexul dat ca parametru.

OnLoaded

Initializează controlul la încărcare.

AnimateToNextPage

Animează trecerea la următoarea pagină.

AnimateToPreviousPage

Animează trecerea la pagina precedentă.

GetItemsCount

Retunează numărul total de itemi incluși în control.

RefreshSheetsContent

Reactualizează conținutul paginilor.

OnLeftMouseDown

Funcția ce tratează evenimentul apăsării click-stînga.

OnRightMouseDown

Funcția ce tratează evenimentul apăsării click-dreapta.

OnLeftPageTurned

Funcția ce ce se apelează atunci cînd se dorește răsfouirea la stînga.

OnRightPageTurned

Funcția ce ce se apelează atunci cînd se dorește răsfouirea la dreapta.

DisplayMode

Proprietate ce returnează modul de afișare curent.

CurrentPage

Proprietate ce returnează pagina curentă.

AnimateToLeftSheet

Aceste patru funcții au corpul asemănător, fiecare putînd fi

AnimateToRightSheet

utilizată pentru tipuri diferite de animații – spre stînga,

MoveToNextPage

MoveToPreviousPage

respectiv, spre dreapta.

Tabelul 6 Funcțiile clasei Book

4.2 Proiectul WpfAppTezaDeLicenta

Acest proiect reprezintă programul principal, care se încarcă atunci cînd soluția

este rulată. El este compus din mai multe pagini XAML, care stochează informația

propriu-zisă. Informația este reprezentată prin imagini .JPG, toate fiind amplasate logic

în mape și submape, pentru o mai bună claritate și ușurință în dezvoltarea ulterioară

4.2.1 Clasa StartWindow

Aceasta este clasa care se încarcă atunci cînd este lansat programul. Ea este un

control WPF, compus din 2 părți partea de design (Vezi ANEXA 4), și partea

funcțională, care este descrisă în continuare.

În Visual Studio 2010, modul Design, controlul dat va arăta astfel:

Figura 3 Interfața aplicației văzută în Visual Studio 2010 Func ț ionalitatea clasei StartWindow este

Figura 3 Interfața aplicației văzută în Visual Studio 2010

Funcționalitatea clasei StartWindow este redată mai jos:

public partial class StartWindow : Window

{

public StartWindow()

{

InitializeComponent(); Width = 800; Height = 600; this.WindowStartupLocation = WindowStartupLocation.CenterScreen;

}

private void ButtonNext_Click(object sender, RoutedEventArgs e)

{

if (myBook.CurrentSheetIndex < myBook.GetItemsCount() / 2) myBook.CurrentSheetIndex++;

}

private void ButtonPrevious_Click(object sender, RoutedEventArgs e)

{

if (myBook.CurrentSheetIndex > 1) myBook.CurrentSheetIndex--;

}

protected override void OnKeyDown(KeyEventArgs e)

{

 

base.OnKeyDown(e);

try

{

 

if (e.Key == Key.Escape)

{

 

{

this.WindowState = WindowState.Minimized;

Environment.Exit(0);

}

 

}

else if (e.Key == Key.Left)

{

 

myBook.AnimateToPreviousPage(true, 500);

if (Int32.Parse(pageNumber.Text) > 1)

{

pageNumber.Text = (Int32.Parse(pageNumber.Text) - 2).ToString();

}

myBook.Focus();

 

}

else if (e.Key == Key.Right)

{

 

myBook.AnimateToNextPage(true, 500);

if (Int32.Parse(pageNumber.Text) < 431)

{

pageNumber.Text = (Int32.Parse(pageNumber.Text) + 2).ToString();

}

myBook.Focus();

 

}

else if (e.Key == Key.Enter)

{

 

if (this.WindowState == WindowState.Maximized)

{

this.WindowState = System.Windows.WindowState.Normal;

}

else

{

this.WindowState = WindowState.Maximized;

}

 

}

 

}

catch (Exception) {

}

}

private void ButtonMinimize_Click(object sender, RoutedEventArgs e)

{

this.WindowState = WindowState.Minimized;

}

private void ButtonMaximize_Click(object sender, RoutedEventArgs e)

{

 

if (this.WindowState == WindowState.Maximized)

{

this.WindowState = System.Windows.WindowState.Normal;

}

else

{

this.WindowState = WindowState.Maximized;

}

}

private void ButtonCloseApplication_Click(object sender, RoutedEventArgs e)

{

Environment.Exit(0);

}

private void ButtonCuprins_Click(object sender, RoutedEventArgs e)

{

myBook.CurrentSheetIndex = 2; pageNumber.Text = "5";

}

private void ButtonCauta_Click(object sender, RoutedEventArgs e)

{

SearchWindow.Show();

}

}

Deoarece metodele de mai sus au fost incluse împreună cu corpurile lor, vom descrie succint pe fiecare din ele. Constructorul implicit inițializează aplicați cu dimensiune de 800×600 ( pentru a putea rula pe diferite tipuri de calculatoare, inclusiv cele cu rezoluția minimă) și este centrată pe desktop. Funcțiile ButtonNext_Click și ButtonPrevious_Click realizează răsfoirea paginilor înainte, respective, înapoi.

În funcția protected override void OnKeyDown(KeyEventArgs e) se realizează tratarea evenimentelor apărute la tastarea unor butoane de la tastatură, cum ar fi Săgreată-Sus sau Enter. Funcțiile ButtonMinimize_Click, ButtonMaximize_Click și, respectiv, ButtonCloseApplication_Click, realizează funcționalitatea butoanelor standarte, prezente aproape în orice aplicație Wondows. De remarcat că aceste butoane reprezintă controale

custom, deoarece cele standard au fost scoase din cadrul aplicației, inclusiv a fost scoasă și bara standartă din partea de sus a aplicației. Funcția ButtonCuprins_Click deschide cartea la pagina de Cuprins, pentru a căuta manual tema dorită.

Funcția ButtonCauta_Click va deschide o mică fereastră, în care se va efectua căutarea automată a unei teme, sau termen dorit.

CONCLUZII

În cadrul tezei de licență au fost obținute următoarele rezultate:

Au fost analizate manualele elctronice și tipurile acestora.

Au fost stabilite funcțiile de bază ale unui manual electronic.

A fost descrisă succint tehnologia WPF și au fost evidențiate avantajele și dezavanatajele acesteia față de alte tehnologii.

Au fost analizate metodele de reprezentare a conținutului unui manual electronic și au fost stabilite avantajele și dezavantajele fiecăreia.

S-a elaborat proiectul unui manual electronic la disciplina “Structuri de date și algoritmi”.

A fost programat și depanat manualul electronic proiectat.

Manualul elctronic poate fi utilizat atît pentru pregătirea pentru examen la disciplina “Fundamentele programării în limbajul C”, cît și la disciplina “Structuri de date și algoritmi”

Manualul poate fi reutilizat, încărcat cu alt conținut, precum și extins prin adăugarea iunor funcționalități și efecte noi.

BIBLIOGRAFIE

1.

Pro C# 2010 and the .NET 4 Platform Fifth edition, Andrew Troelsen, Apress,

2010

2.

Sams Teach Yourself WPF in 24 Hours, Rob Eisenberg and Christopher Bennage, Sams, 2009

3.

Pro C# 2008, Christian Nagel, Bill Evjen, Jay Glynn, Morgan Skinner and Karli Watson, Wrox, 2008

4.

Visual C# 2010 Recipes: A Problem-Solution Approach, Allen Jones and Adam Freeman, Apress, 2010

5.

Pro WPF Programming, Chris Andrade, Shawn Livermore, Mike Meyers and Scott Van Vliet, Wrox, 2007

6.

7.

8.

9.

ANEXA 1

Structura proiectelor create în cadrul tezei de licență

ANEXA 1 Structura proiectelor create î n cadrul tezei de licen ță 56
ANEXA 1 Structura proiectelor create î n cadrul tezei de licen ță 56

ANEXA 2

Codul fișierului BookPage.xaml

<ContentControl x:Class="WpfBookControls.BookPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Loaded="OnLoaded" BorderBrush="Red" BorderThickness="1" MouseDoubleClick="OnMouseDoubleClick" MouseMove="OnMouseMove" MouseDown="OnMouseDown" MouseUp="OnMouseUp" MouseLeave="OnMouseLeave" > <Grid x:Name="mainGrid"> <!--Page 2 begin--> <ContentPresenter x:Name="page2" /> <!--Page 2 end--> <Canvas Opacity="1" x:Name="nextPageShadowCanvas" Visibility="Hidden"> <Canvas.Background> <LinearGradientBrush x:Name="nextPageShadow" StartPoint="0 0" EndPoint="0 0"> <GradientStop Color="Transparent" Offset="0" /> <GradientStop x:Name="nextPageShadowCanvasOffset1" Color="Black" Offset="0"

/>

<GradientStop x:Name="nextPageShadowCanvasOffset2" Color="Transparent"

Offset="1" />

<GradientStop Color="Transparent" Offset="1" /> </LinearGradientBrush> </Canvas.Background> </Canvas> <Grid> <Grid.Clip> <CombinedGeometry x:Name="clippingPage0" GeometryCombineMode="Exclude">

<CombinedGeometry.Geometry1>

<RectangleGeometry />

</CombinedGeometry.Geometry1>

<CombinedGeometry.Geometry2>

<PathGeometry> <PathFigure IsClosed="True" /> </PathGeometry>

</CombinedGeometry.Geometry2>

</CombinedGeometry> </Grid.Clip> <!--Page 0 begin--> <ContentPresenter x:Name="page0" /> <!--Page 0 end--> </Grid> <Canvas Opacity="1" x:Name="gridShadow" Visibility="Hidden"> <Canvas.Background> <LinearGradientBrush x:Name="pageShadow" StartPoint="0 0" EndPoint="0 0"> <GradientStop Color="Transparent" Offset="0" /> <GradientStop Color="Black" Offset="0" /> <GradientStop Color="Transparent" Offset="1" /> </LinearGradientBrush> </Canvas.Background> </Canvas> <Grid x:Name="rectangleVisible"> <Grid.RenderTransform>

<TransformGroup> <TranslateTransform x:Name="rectangleTranslate" /> <RotateTransform x:Name="rectangleRotate" /> </TransformGroup> </Grid.RenderTransform> <Grid.Clip> <PathGeometry x:Name="clippingFigure"> <PathFigure IsClosed="True" /> </PathGeometry> </Grid.Clip> <!--Page 1 begin--> <ContentPresenter x:Name="page1" /> <!--Page 1 end--> <Canvas Opacity="0.7" x:Name="canvasReflection" Visibility="Hidden"> <Canvas.Background> <LinearGradientBrush x:Name="pageReflection" StartPoint="0 0" EndPoint="0

0">

<GradientStop Color="Black" Offset="0" /> <GradientStop Color="White" Offset="0.35" /> <GradientStop Color="Transparent" Offset="1" /> </LinearGradientBrush> </Canvas.Background> </Canvas> </Grid> </Grid> </ContentControl>

ANEXA 3

Codul fișierului Book.xaml

<ItemsControl x:Class="WpfBookControls.Book"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:WpfBookControls" ClipToBounds="False" Loaded="OnLoaded" Width="500" Height="300"

>

<ItemsControl.Resources> <DataTemplate x:Key="defaultDataTemplate"> <Grid> <ContentControl Content="{Binding .}" /> </Grid> </DataTemplate> </ItemsControl.Resources> <ItemsControl.Template> <ControlTemplate TargetType="{x:Type local:Book}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="50*" /> <ColumnDefinition Width="50*" /> </Grid.ColumnDefinitions> <local:BookPage Grid.Column="0" Name="sheet0" IsTopRightCornerEnabled="false" IsBottomRightCornerEnabled="false" MouseDown="OnLeftMouseDown" PageTurned="OnLeftPageTurned" /> <local:BookPage Grid.Column="1" Name="sheet1" IsTopLeftCornerEnabled="false" IsBottomLeftCornerEnabled="false" MouseDown="OnRightMouseDown" PageTurned="OnRightPageTurned" />

</Grid> </ControlTemplate> </ItemsControl.Template> <ItemsControl.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scale" ScaleX="1" ScaleY="1" /> <RotateTransform Angle="0" /> <TranslateTransform x:Name="translate" X="0" Y="0" /> </TransformGroup> </ItemsControl.RenderTransform> </ItemsControl>

ANEXA 4

Codul fișierului StartWindow.xaml

<Window x:Class="WpfAppTezaDeLicenta.StartWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:controls="clr-namespace:WpfBookControls;assembly=WpfBookControls"

xmlns:local="clr-namespace:WpfAppTezaDeLicenta"

Title="StartUpWindow"

Height="Auto"

Width="Auto"

WindowStyle="None"

Background="Azure"

WindowStartupLocation="CenterScreen"

Icon="a.ico">

<Window.Resources> <Style x:Key="GelButton" TargetType="{x:Type Button}"> <Setter Property="Background" Value="Black" /> <Setter Property="Height" Value="40" /> <Setter Property="Foreground" Value="White" /> <Setter Property="Margin" Value="3" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid> <Rectangle Name="GelBackground"

RadiusX="9"

RadiusY="9"

Fill="{TemplateBinding Background}"

StrokeThickness="0.35">

<Rectangle.Stroke> <LinearGradientBrush StartPoint="0,0"

EndPoint="0,1">

<GradientStop Offset="0" Color="White" /> <GradientStop Offset="1" Color="#666666" /> </LinearGradientBrush> </Rectangle.Stroke> </Rectangle> <Rectangle Name="GelShine"

Margin="2,2,2,0"

VerticalAlignment="Top"

RadiusX="6"

RadiusY="6"

Stroke="Transparent"

Height="15px">

<Rectangle.Fill>

<LinearGradientBrush StartPoint="0,0"

EndPoint="0,1">

<GradientStop Offset="0" Color="#ccffffff" /> <GradientStop Offset="1" Color="Transparent" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <ContentPresenter Name="GelButtonContent" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}" />

</Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Rectangle.Fill" TargetName="GelBackground"> <Setter.Value> <RadialGradientBrush> <GradientStop Offset="0" Color="Lime" /> <GradientStop Offset="1" Color="DarkGreen" /> </RadialGradientBrush> </Setter.Value> </Setter> <Setter Property="Foreground" Value="Black" />

</Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Rectangle.Fill" TargetName="GelBackground"> <Setter.Value> <RadialGradientBrush> <GradientStop Offset="0" Color="#ffcc34" /> <GradientStop Offset="1" Color="#cc9900" /> </RadialGradientBrush> </Setter.Value> </Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>

<Style x:Key="RoundedGelButton" BasedOn="{StaticResource GelButton}" TargetType="Button"> <Setter Property="Width" Value="100" /> <Setter Property="Height" Value="100" /> <Setter Property="Grid.Row" Value="2" />

<Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid> <Ellipse Name="GelBackground"

StrokeThickness="0.5"

Fill="Black"> <Ellipse.Stroke> <LinearGradientBrush StartPoint="0,0"

EndPoint="0,1">

<GradientStop Offset="0" Color="#ff7e7e7e" /> <GradientStop Offset="1" Color="Black" /> </LinearGradientBrush> </Ellipse.Stroke> </Ellipse> <Ellipse Margin="15,5,15,50"> <Ellipse.Fill> <LinearGradientBrush StartPoint="0,0"

EndPoint="0,1">

<GradientStop Offset="0" Color="#aaffffff" /> <GradientStop Offset="1" Color="Transparent" /> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> <ContentPresenter Name="GelButtonContent" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}" />

</Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Rectangle.Fill" TargetName="GelBackground"> <Setter.Value> <RadialGradientBrush> <GradientStop Offset="0" Color="Lime" /> <GradientStop Offset="1" Color="DarkGreen" /> </RadialGradientBrush> </