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.

 Să 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.

2
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.

3
CUPRINS

SARCINA TEZEI………………………………………………………………2
ADNOTARE………………………………………………………………….…3
CUPRINS………………………………………………………………………..4
INTRODUCERE……………………………………………………………......6

I. MANUALE ELECTRONICE…………………………………………..8
1.1 Calculatorul – instrument didactic ..………………………....………..8
1.2 Tipuri de manuale electronice………………………………….……...9

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


2.1 Tipuri de date abstracte ...…………………………………….……….13
2.1.1 Caracteristici……………………………………………..…....…13
2.1.2 Avantaje………………………………………………....…….....14
2.1.3 Stiva……………………………………………………………...14

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


3.1 Caracteristicile 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
4
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
3.1.15 WPF în contrast cu Silverlight………………………...……….32
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


4.1 Proiectul WpfBookControls………………….…………...…………...41
4.1.1 Modulul cu tipuri de date auxiliare….………………………41
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

5
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
6
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.

7
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

8
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

9
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:

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
10
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.

11
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),
12
î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

13
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 (vî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.

14
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 cî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) {

15
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):


16
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];
}

17
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.
18
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.

Windows Presentation Foundation este concentrată pe transmiterea


mesajelor. Acest API simplifică enorm toate tipurile de comunicare
WCF
și transmitere a mesajelor în rețea. Cuprinde totul, de la servicii
web la P2P și multe altele.
O bibliotecă puternică pentru construirea aplicațiilor care permit
lucrul cu workflow (flux de lucru). Folosește un limbaj de marcare
WF 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.
Cel mai puțin renumită din cele patru biblioteci, CardSpace oferă
CardSpace 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
19
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.

20
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.

21
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)


22
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
23
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

24
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.

25
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
26
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

27
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.

Figura 2 Versiunile de .NET Framework

3.1.13 Caracteristici incluse în versiunile .NET Framework

Versiunea Versiunea Versiunea


Descrierea
.NET Framework CLR Visual Studio
Visual Studio Conține prima versiune a CLR și prima
1.0 1.0
.NET versiune a base class libraries.
Visual Studio Include update-uri pentru ASP.NET și
1.1 1.1
.NET 2003 ADO.NET. Această versiune a fost

28
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.
A introdus o nouă versiune a CLR cu
adaosuri la base class libraries, inclusiv
Visual Studio tipuri generice, colecții generice, și
2.0 2.0
.NET 2005 adaosuri semnificative la ASP.NET.
Această versiune este ulterior înnoită
cu SP1 și SP2.
Această versiune este în principal .NET
Visual Studio Framework 2.0 cu adăugarea WPF,
3.0 2.0
.NET 2005 WCF, WF și CardSpace. A fost ulterior
înnoită cu SP 1 și SP 2.
A adăugat noi caracteristici, așa ca site-
uri Web AJAX-enabled și LINQ. SP1 a
Visual Studio
3.5 2.0 adăugat .NET Framework Client
.NET 2008
Profile, Dynamic Data și un mic set de
înbunătățiri adiționale.
Include o nouă versiune de CLR, a base
class libraries extinse, și noi trăsături,
Visual Studio
4 4 precum Managed Extensibility
.NET 2010
Framework (MEF), dynamic language
runtime (DLR) și contracte de cod.

29
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
30
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).

31
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

32
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:
33
<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,

34
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#:
35
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>

36
<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"
37
Height="24"
Fill="Yellow" />
</Button>

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.

38
Î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.
39
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

40
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

41
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)


{

42
_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 { … }

43
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
44
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 de mai jos sunt descrise metodele clasei BookPage din fișierul
“BookPage.xaml”:

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,

45
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.

46
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.

47
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ă.


48
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:

49
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--;

50
}

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)


51
{
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

52
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.

53
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.

54
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. http://www.codeproject.com/KB/GDI-plus/TurnThePage.aspx

7. http://www.wpfbookcontrol.codeplex.com/

8. http://www.wpftutorial.net/

9. http://windowsclient.net

10. http://infoscience.3x.ro/c++.html

55
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>
57
<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>

58
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>

59
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>
60
<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" />
61
<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>
</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" />
62
</RadialGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground"
Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</Window.Resources>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>

<Button Name="ButtonOfficeStyle"
Height="20"
Width="20"
Style="{StaticResource RoundedGelButton}"
HorizontalAlignment="Left"
Content="D"
Margin="3,3,0,3"
Grid.Row="0"
Grid.Column="0">
</Button>

<DockPanel Height="Auto"
Width="Auto"
Grid.Row="0"
Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>

<Button Name="ButtonMinimize"
Grid.Column="0"
Height="20"
Width="Auto"
Style="{StaticResource GelButton}"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Content=" Min "
Click="ButtonMinimize_Click">
</Button>
<Button Name="ButtonMaximize"
Grid.Column="1"
Height="20"
63
Width="Auto"
Style="{StaticResource GelButton}"
VerticalAlignment="Top"
HorizontalAlignment="Center"
Content=" Max "
Click="ButtonMaximize_Click">
</Button>
<Button Name="ButtonCloseApplication"
Grid.Column="2"
Height="20"
Width="Auto"
Style="{StaticResource GelButton}"
VerticalAlignment="Top"
HorizontalAlignment="Center"
Content=" Close "
Click="ButtonCloseApplication_Click">
</Button>
</Grid>
</DockPanel>

<DockPanel Height="Auto"
Width="Auto"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2">
<DockPanel.Background>
<LinearGradientBrush StartPoint="0 0.4 "
EndPoint="1 0.6">
<GradientStop Offset="0"
Color="DarkGray" />
<GradientStop Offset="0.5"
Color="White" />
<GradientStop Offset="1"
Color="DarkGray" />
</LinearGradientBrush>
</DockPanel.Background>

<Viewbox Margin="5" Name="aaaa">


<Grid Width="Auto"
Height="Auto">

<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>

<controls:Book x:Name="myBook"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="15">

<controls:Book.ItemTemplate>
<DataTemplate>
<Border BorderThickness="4"
BorderBrush="Gray"
64
Background="#FFE5E1EB">
<ContentControl Content="{Binding .}" />
</Border>
</DataTemplate>
</controls:Book.ItemTemplate>

<local:FrontPage></local:FrontPage>
<local:BlankPage></local:BlankPage>
<local:BlankPage></local:BlankPage>
<local:Cuprins1></local:Cuprins1>
<local:Cuprins2></local:Cuprins2>

<local:Page1></local:Page1>
<local:Page2></local:Page2>
<local:Page3></local:Page3>
<local:Page4></local:Page4>
<local:Page5></local:Page5>
<local:Page6></local:Page6>

<local:Page425></local:Page425>
<local:Page426></local:Page426>
<local:Page427></local:Page427>
<local:Page428></local:Page428>
<local:Page429></local:Page429>
<local:Page430></local:Page430>
<local:Page431></local:Page431>

<local:BackPage></local:BackPage>

</controls:Book>

<Button x:Name="EmptyButtonAutoPrevious"
Grid.Column="1"
Content="&lt;"
HorizontalAlignment="Left"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Background="LightGray"
Opacity="0.5"
Height="50"
Click="ButtonAutoPrevious_Click" />

<Button x:Name="EmptyButtonAutoNext"
Grid.Column="2"
Content="&gt;"
HorizontalAlignment="Right"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Background="LightGray"
Opacity="0.5"
Height="50"
Click="ButtonAutoNext_Click" />
</Grid>
</Viewbox>
</DockPanel>

</Grid>
</Window>

65

S-ar putea să vă placă și