Aplicatii in Visual.net

203
Dezvoltare de aplicatii in Visual Studio .NET Presented by developerWorks, your source for great tutorials ibm.com/developerWorks Table of Contents If you're viewing this document online, you can click any of the topics below to link directly to that section. 1. Despre manual si despre autorul sau ............................... 2 2. Introducere in .NET Framework - I .................................. 3 3. Tipuri de date si membri- II ........................................... 12 4. Gestionarea interfetelor utilizator - III ............................... 35 5. Concepte POO in Visual Studio .NET - IV ......................... 61 6. Testarea si debugging-ul aplicatiilor - V ............................ 80 7. Accesarea bazelor de date. ADO.NET - VI ........................ 98 8. GDI+. Controale utilizator. Atribute - VII ............................ 122 9. Programare folosind fire de executie - VIII ......................... 140 10. .NET Framework Advanced - IX ................................... 142 11. Assemblies. Aplicatii - configurare, securizare, instalare, rulare - X .................................................................... 158 12. XML, Web Services - XI ............................................. 177 13. ASP.NET - XII ......................................................... 187 14. Appendix ............................................................... 202 15. Bibliografie, referinte ................................................. 203 Dezvoltare de aplicatii in Visual Studio .NET Page 1 of 203

Transcript of Aplicatii in Visual.net

Page 1: Aplicatii in Visual.net

Dezvoltare de aplicatii in Visual Studio.NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Table of ContentsIf you're viewing this document online, you can click any of the topics below to link directly to that section.

1. Despre manual si despre autorul sau............................... 22. Introducere in .NET Framework - I .................................. 33. Tipuri de date si membri- II ........................................... 124. Gestionarea interfetelor utilizator - III ............................... 355. Concepte POO in Visual Studio .NET - IV ......................... 616. Testarea si debugging-ul aplicatiilor - V ............................ 807. Accesarea bazelor de date. ADO.NET - VI ........................ 988. GDI+. Controale utilizator. Atribute - VII............................ 1229. Programare folosind fire de executie - VIII......................... 14010. .NET Framework Advanced - IX ................................... 14211. Assemblies. Aplicatii - configurare, securizare, instalare,rulare - X ....................................................................

158

12. XML, Web Services - XI ............................................. 17713. ASP.NET - XII ......................................................... 18714. Appendix ............................................................... 20215. Bibliografie, referinte ................................................. 203

Dezvoltare de aplicatii in Visual Studio .NET Page 1 of 203

Page 2: Aplicatii in Visual.net

Section 1. Despre manual si despre autorul sau

Despre manual...Manualul contine tematica cursului "Dezvoltare deaplicatii in Visual Studio .NET" si se adreseaza, inprimul rand, studentilor Facultatii de Informaticacare au optat sa urmeze acest curs. Cititorii acestuimanual trebuie sa posede cunostinte medii deprogramare orientata obiect si sa fie familiarizati cumedii de programare vizuala. In plus, o doza deambitie este suficienta pentru a garanta o bunaasimilare a cunostintelor de Visual Studio .NET si,in particular, de C# pe care autorul intentioneazasa le transmita.

Despre autor...

Gabriel NEGARA

• Preparator universitar, Facultatea de Informatica, IASI

• Lucrare de licenta, iunie 2002 - Ant Colony Optimisation

• Master, iunie 2003 - Tehnici de clasificare in Data Mining

• MCP 70-316 feb. 2004

• Pagina web: http://www.infoiasi.ro/~ngabi

• E-mail:[email protected]

• Telefon: 0232 201549

Gabriel NEGARA februarie-mai 2004, Iasi

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 2 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 3: Aplicatii in Visual.net

Section 2. Introducere in .NET Framework - I

1. NET Framework - privire de ansamblu

.NET Framework este o tehnologie care a reusit sa atraga simpatia lumii IT mondialeprin:

-usurinta in dezvoltare si utilizare (developing and deploying)

-disponibilitatea pe termen lung (high availability)

-stabilitatea (reliability)

-suportul pentru o gama larga de aplicatii (multi-target application support)

-rezultatul rapid (strength)

-modernitatea

-interoperabilitatea

• .NET Framework este o platforma de dezvoltare de aplicatii care implementeaza unmecanism eficient de alocare de memorie pentru stocarea datelor si instructiunilor,permitand executia unei aplicatii utilizator numai dupa verificarea unui set depermisiuni; daca sunt indeplinite conditiile de lansare in executie a aplicatiei, mediulde dezvoltare initiaza si gestioneaza executia aplicatiei, gestionand, de asemenea,mecanismul de realocare zonelor de memorie provenite de la resurse care nu maisunt utlizate de aplicatie. .NET Framework consta in doua mari componente:CommonLanguage Runtime si NET Framework Class Library.

• .NET Framework este baza dezvoltarii de programe.

CLR furnizeaza mare parte din serviciile de baza necesare executiei programelor.

Libraria de clase de baza BCL .NET expune un set de clase pre-implementate, carefaciliteaza dezvoltarea de programe.

Common Language Specification (CLS) defineste un set minim de standarde pecare toate limbajele care folosesc .NET Framework trebuie sa le suporte.

Common Type System(CTS) stabileste compatibilitatea de tipuri intre componenteimplementate in diverse limbaje.

• Unitatea de baza, elementara a unei aplicatii .NET este assembly-ul, care include unmanifest al assembly-ului. Acest manifest descrie assembly-ul si unul sau mai multemodule, iar modulele contin codul sursa al aplicatiei.

• Un executabil .NET este stocat ca un fisier IL (MSIL - Microsoft IntermediateLanguage). La incarcare, compilatorul transforma codul sursa in code managed(compilat si administrat de CLR), se verifica daca assembly-ul verifica conditiile desecuritate impuse de sistemul local. Daca se permite rularea, se creaza un fisier .exesau .dll numit PE - Executabil Portabil. Acesta este incarcat de motorul de executiecare extrage separat MSIL si Metadata. MSIL este JIT-compilat in cod masina(binar) si executat. Prezenta metadatei (data describing data, self describing data)face ca acest cod administrat sa poata sa se auto-descrie (definitii de tipuri,versiune, restrictii legate de securitate, etc). Aceasta extra-informatie asigura practico interoperabilitate fara compromisuri.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 3 of 203

Page 4: Aplicatii in Visual.net

CLR - interoperabilitate multi-limbaj

Integrare

compilatorul limbajului L in care se programeaza trebuie sa stie sa furnizeze codintermediar pentru masina virtuala .NET -CLR.

Exista, in prezent, cateva zeci de limbaje compatibile cu .NET (C#, C++, Visual Basic.NET, Jscript .NET, COBOL, Perl, etc).

Interoperabilitate

Modulele scrise in limbajul L pot fi utilizate in orice alt limbaj compatibil .NET. Spreexemplu, o clasa scrisa in L poate fi mostenita in C#, etc. In plus, in .NET, nu se maipune problema vulnerabilitatii legate de versiunea modulului scris in L (in care seregaseste signatura si implementarea clasei de mai sus). Introducerea metadateirezolva aceasta problema importanta.

Figura 1 - structura .NET Framework. Interoperabilitate

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 4 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 5: Aplicatii in Visual.net

Figura 2 - privire de ansamblu .NET Framework - aplicatii, tehnologii, protocoale

2. Libraria de clase de baza .NET (BCL)

Spatii de nume .NET reprezentative

Spatiu de nume Descriere

System Reprezinta spatiul de nume radacina pentru tipurilelow-level din .NET Framework si, de asemenea, pentrutipurile primitive de data, si este baza tuturor celorlalte spatiide nume din .NET BCL.

System.Collections Contine clase care reprezinta o varietate de tipuri container,cum ar fi ArrayList, SortedList, Queue si Stack. Contine, deasemenea, clase abstracte, cum ar fi CollectionBase, foarteutile pentru implementarea propriilor clase cu functionalitatede container.

System.ComponentModel Contine clase utile pentru implementarea comportamentelorcomponentelor si controalelor la run-time si design-time -convertori de tipuri si atribute, legare la surse de date(binding), componente care asigura managamentullicentelor.

System.Data Contine clase necesare accesarii si manipularii bazelor de

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 5 of 203

Page 6: Aplicatii in Visual.net

date, precum si spatii de nume aditionale utilizate pentruaccesul la date.

System.Data.Common Contine un set de clase distribuite pentru provideri de date.NET.

System.Data.OleDb Contine clase care pot efectua operatii cu provideri de datede tip managed, pentru acces OLE DB la surse de date.

System.Data.SQLClient Contine clase optimizate pentru interactiunea cu MicrosoftSQL Server.

System.Drawing Expune functionalitati GDI+, continand clase care faciliteazarandarea grafica.

System.IO inglobeaza tipuri pentru efectuarea operatiilor de I/O insistemul de fisiere.

System.Math Contine un set de functii matematice.

System.Reflection Furnizeaza suport pentru obtinerea de informatii sigenerarea dinamica de tipuri la runtime.

System.Security Tipuri cu ajutorul carora se pot crea si manipula permisiuni,aspectele legate de criptografie si securitatea accesariicodului constituie, de asemenea, subiecte strans legate deacest spatiu de nume.

System.Threading Contine clase care faciliteaza implementarea de aplicatii cufire de executie multiple.

System.Windows.Forms Contine tipuri implicate in crearea aplicatiilor Windowsstandard. Clasele care reprezinta forme si controale sunt,de asemenea, incluse aici.

Numele spatiilor de nume sunt auto-descriptive prin design. Aceasta modalitate deutilizare a numelor face ca .NET Framework sa fie usor de folosit si permiteutilizatorului o familiarizare rapida cu mediul de lucru.

Libraria de clase de baza .NET Framework este o librarie de cod care furnizeazafunctionalitati folositoare pentru construirea aplicatiilor. BCL este organizata in spatii denume, care contin tipuri si spatii de nume aditionale, legate prin functionalitate comuna.

Se poate folosi cuvantul rezervat using pentru a permite referentierea unor membri aiunui spatiu de nume fara a folosi un nume specificat prin calea comnpleta catremembrul respectiv. Daca se doreste folosirea unei librarii externe, trebuie creata maiintai o referinta catre aceasta.

Tipuri valoare si tipuri referinta

• Tipurile pot fi: tipuri valoare sau tipuri referinta. O variabila de tip valoare continetoate datele asociate cu tipul respectiv. O variabila de tip referinta contine un pointerla o instanta a unui obiect de tipul respectiv.

• Tipurile valoare predefinite sunt create la declarare si ramin vide pana in momentulin care li se asigneaza o valoare. Tipurile referinta trebuie instantiate dupa declararepentru a crea efectiv un obiect de acel tip. Declararea si instantierea pot fi combinate

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 6 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 7: Aplicatii in Visual.net

intr-un singur pas, fara nici o pierdere legata de performanta.

• Cand o variabila de tip valoare este asignata unei alte variabile de tip valoare, datelecontinute in prima variabila sunt copiate in cea de-a doua. Atunci cand o variabila detip referinta este asignata unei alte variabile de acelasi tip, numai referinta catreobiect este copiata, si ambele variabile vor face referire catre acelasi obiect.

3. Clase si structuri

Clase versus Structuri

La prima vedere, clasele si structurile par foarte asemanatoare. Ambele pot continemembri, cum ar fi campuri si metode, ambele necesita un constructor pentru a se creao noua instanta si, ca toate tipurile din .NET Framework, ambele sunt derivate dinObject. Diferenta dintre clase si structuri este accea ca structurile sunt tipuri valoare,iar clasele sunt tipuri referinta. La nivel de alocare, aceasta inseamna ca datele deinstantiere pentru clase sunt alocate pe heap, in timp ce pentru structuri acestea suntalocate pe stack. Acesul la stack a fost proiectat in asa fel incat sa fie facil si rapid, darstocarea unor date de dimensiuni mari pe stack pot conduce la diminuari aleperformantei aplicatiei.

in termeni practici, structurile reprezinta varianta optima pentru obiecte de dimensiunimici si pentru care se definesc putine instante, persistente pentru perioade relativ miciin memorie. Clasele sunt optim folosite pentru obiecte de dimensiuni mai mari si pentrucare de definesc un numar mai mare de instante, cu posibilitatea mentinerii lor inmemorie pentru perioade mari de timp.

Sinteza

• Tipurile definite de uzilizator includ clase si structuri. Ambele pot avea membri -campuri, proprietati, metode sau evenimente. Clasele sunt tipuri referinta iarstructurile sunt tipuri valoare.

• Cuvantul rezervat class este folosit in Visual C# pentru a defini clase. Structurile suntcreate utilizand cuvantul cheie struct. Atat clasele, cat si structurile pot contine tipuriimbricate.

• Tipurile definite de utilizator sunt instantiate in acceasi maniera ca tipurile predefite,exceptand faptul ca atat tipurile caloare cat si tipurile referinta trebuie sa foloseascacuvantul cheie new pentru instantiere.

4. Cum folosim metodele?

• Metodele executa manipulari ale datelor care imprima claselor si structurilor unanumit comportament. Metodele pot returna o valoare, dar acest lucru nu estenecesar. in Visual C#, daca o metoda nu returneaza o valoare, se specifica voiddrept tip returnat. Metodele sunt apelate prin plasarea numelui metodei in cod,specificandu-se eventualii parametrii necesari.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 7 of 203

Page 8: Aplicatii in Visual.net

• Metodele pot avea parametri, care reprezinta valori solicitate de metoda. Parametriisunt transmisi, implicit, prin valoare. Transmiterea parametrilor prin referinta se facein Visual C# folosind cuvantul rezervat ref. Visual C# permite specificareaparametrilor de iesire pentru o anumita metoda.

• Constructorul este prima metoda apelata la instantierea unui tip. Constructorulfurnizeaza o modalitate de a seta valori implicite ale datelor sau de a executa alteoperatii necesare, inainte ca obiectul sa fie disponibil pentru operatii ulterioare.Destructorii sunt apelati exact inainte ca un obiect sa fie distrus si pot fi folositi pentrua executa cod de clean-up, de dealocare de memorie. Pentru ca dealocareamemoriei alocate obiectelor este controlata de common language runtime,utilizatorul nu poate controla momentul apelarii destructorului.

••

5. Nivele de acces si domenii de vizibilitate (scope)

C# - Access Levels

Modificator de acces Efect asupra membrilor

public poate fi accesat de oriunde

private poate fi accesat doar de membrii din cadrul tipului care ildefineste

internal poate fi accesat de toate tipurile din cadrul assembly-uluiparinte, dar nu dinafara acestuia

protected poate fi accesat numai de membrii din cadrul tipului care ildefineste sau de tipuri care mostenesc acest tip

protected-internal poate fi accessed de toate tipurile din assembly sau detipuri mostenite din tipul care contine membrul in discutie;reprezinta reuniunea tipurilor de acces protected si internal

• Modificatorii de acces sunt folositi pentru a controla domeniul de vizibilitate amembrilor unui tip de date. Exista 5 modificatori de acces: public, internal,private,protected si protected internal. Fiecare dintre acestea determina un anumitnivel de acces.

• Daca pentru o metoda nu se specifica nici un modificator de acces, nivelul de accesasociat implicit este private pentru clasele si structurile din Visual C#. Daca nu estespecificat nici un modificator de acces pentru o variabila membru, acesta esteconsiderata private intr-o clasa si publicintr-o structura.

• Modificatorii de acces pot fi, de asemenea, folositi pentru a controla modul in careeste instantiat un tip. Nivelele de acces pentru tipuri sunt urmatoarele: tipurile publicpot fi instantiate de oriunde. Tipurile internal pot fi instantiate numai de membriiassembly-ului, tipurile private pot fi instantiate numai de ele insele sau dintr-un tipcare le contine.

• Daca nu se specifica un modificator de acces pentru o clasa sau structura, esteconsiderata public.

• Tipurile imbricate se supun acelorasi reguli ca si tipurile ne-imbricate dar, in practica,

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 8 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 9: Aplicatii in Visual.net

ele nu vor avea niciodata un nivel de acces mai mare decat cel al tipului parinte.

• Membrii de tip static apartin tipului si nu unei instante anume a tipului respectiv. Eipot fi accesati fara a crea o instanta a tipului si sunt accesati folosind numele tipului.

6. Garbage Collection

.NET Framework executa managementul automat al memoriei, ceea ce inseamna caatunci cand un obiect nu mai este folosit, .NET Framework elibereaza automatmemoria folosita de acel obiect. Acest proces se numeste garbage collection.

Sa consideram urmatorul exemplu:

void GarbageCollectionExample()

{

TipObiect obiect = new TipObiect();

}

La sfarsitul acestei proceduri, variabila obiect iese domeniul sau de vizibilitate, iarobiectul la care face referire nu mai este referentiat de nici o variabila din cadrulaplicatiei. Garbage collector-ul gestioneaza in background arborele de referinte siidentifica obiectele catre care nu se mai face referinta. Cand gaseste un astfel deobiect, cum ar fi TipObiect din exemplul anterior, il sterge si solicita eliberarea zonei dememorie ocpate de obiectul respectiv. Pentru ca garbage collector-ul ruleaza continuu,utilizatorul nu trebuie sa distruga explicit obiectele la care nu se mai face referire inprogram de la un anumit moment.

Garbage collector-ul reprezinta, de fapt, un fir de executie de prioritate scazuta, inconditii normale. El intervine in executia programului cand timpul procesor nu esteconsumat de sarcini mai importante. Totusi, atunci cand zonele de memorie libera seimputineaza semnificativ, firul de executie asociat garbage collector-ului creste inprioritate. Memoria utilizata de obiecte care nu mai sunt referentiate in program estesolicitata intr-o maniera mai insistenta, pana cand se elibereaza o zona suficienta dememoria, caz in care firul de executie al garbage collector-ului trece la o prioritatescazuta.

Aceasta abordare non-deterministica de eliberare a memoriei are ca scop maximizareaperformantei aplicatiei si furnizeaza un mediu de aplicatii mai putin predispus laactiunea bug-urilor (less bug-prone ). Exista, insa, un cost. Datorita mecanismului princare opereza garbage collector-ul, utilizatorul nu poate sti momentul in care un obiectva fi dealocat. Deci, nu exista control asupra momentului apelarii destructorului claseiVisual C# in cauza. Aceste metode ar trebui sa nu contina cod care se proiecteaza a fiexecutat la un anumit moment. in schimb, pot fi scrise clase care utlizeaza o cantitateimportanta de resurse si care contin o metoda Dispose() pentru eliberarea explicita aacestor resurse, atunci cand o instanta a acestei clase nu mai este necesara inprogram.

Referinte circulare

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 9 of 203

Page 10: Aplicatii in Visual.net

Procesul de garbage collection are in vedere, de asemenea, si referintele circulare, oforma foarte comuna de utilizare ineficienta a memoriei in medii de dezvoltareanterioare. Sa consideram urmatorul exemplu:

class Widget

{

public Widget ChildWidget;

public Widget Parent;

}

class aClass

{

Widget GrandParent;

void Demo()

{

Widget Parent;

Widget Child;

GrandParent = new Widget();

GrandParent.ChildWidget = new Widget();

Parent = GrandParent.ChildWidget;

Parent.ChildWidget = new Widget();

Child = Parent.ChildWidget;

Child.Parent = Parent;

GrandParent = null;

//acum, Parent si Child se autorefera - referintacirculara

}

}

Desi referintele circulare pot crea probeleme in ceea ce priveste detectarea zonelor dememorie ocupate inutil in alte platforme de dezvoltare, garbage collector-ul din .NETFramework este capabil sa detecteze si sa faca disponibile aceste zone. Deci, daca opereche de obiecte se autoreferentiaza, vor fi supuse procesului de garbage collection.

• .NET Framework gestioneaza procesul de eliberare automata a memoriei prinintermediul garbage collector-ului. Garbage collector-ul este un fir de executie deprioritate scazuta care ruleaza intotdeauna im background-ul aplicatiei. Candmemoria disponibila s-a diminuat, prioritatea garbage collector-ului creste pana candse vor elibera destule resurse.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 10 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 11: Aplicatii in Visual.net

• Pentru ca nu se poate stabili momentul in care un anumit obiect va fi eliminat degarbage collector, utilizatorul nu trebuie sa mizeze de codul scris in interioruldestructorilor. in schimb, pentru eliberarea resurselor, se poate folosi o metodaDispose() care va fi apelata explicit.

• Garbage collector-ul analizeaza in mod continuu arborele de referinte si eliminaobiectele la care nu se mai face referinta, precum si obiectele cu referinte circulare.

Detalii - MSDN Library, criteriu de cautare circular reference

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 11 of 203

Page 12: Aplicatii in Visual.net

Section 3. Tipuri de date si membri- II

1. Tipuri de date. Utilizare.

Microsoft .NET Framework furnizeaza un sistem foarte robust de tipuri primitive carepot fi folosite pentru stocarea si reprezentarea datelor din cadrul aplicatiei. Dateleprimitive reprezinta numere intregi, flotante, valori booleene, caractere si string-uri.Sistemul de tipuri de date .NET Framework este type-safe, adica conversiile impliciteintre diferitele tipuri de date au loc numai daca acest lucru nu conduce la pierderi dedate. Conversiile explicite pot fi executate in situatii cate pot provoca pierderi de date.Tipurile de date .NET contin functionalitati pentru a executa un set diversificat deconversii de tip si alte sarcini similare.

OBIECTIVE:

• intelegerea mecanismului conversiilor implicite si explicite dintre tipuri

• descrierea functionalitatilor oferite de tipurile .NET Framework

• prezentarea operatiilor cu string-uri, folosind metodele clasei String

.NET Framework pune la dispozitia utilizatorului un sistem extensibil de tipuri carepermit stocarea, manipularea si transmiterea valorilor intre diferitele entitati din cadrulaplicatiei. Limbajele .NET sunt puternic tipizate (strongly typed). Aceasta inseamnaca obiectele de un anumit tip nu pot fi schimbate cu obiecte de un alt tip. Apelul uneimetode va esua daca nu se specifica parametri avand tipurile corespunzatoarte.Conversiile implicite si explicite permit transformari asupra datelor atunci cand estenevoie. Acest lucru este posibil deoarece toate tipurile din .NET Framework suntderivate din Object, tipul de baza al tuturor claselr si structurilor.

Tipuri de date .NET

Tipuri valoare - subcategorii:

• tipuri intregi

• tipuri flotante

• tipul Boolean

• tipul Char

Tipuri referinta - frecvent folosite in aplicatii:

• String

• Object

Tipuri intregi

Tabelul urmator sintetizeaza aceste tipuri, prezentand tipurile din Visual C#corespunzatoare.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 12 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 13: Aplicatii in Visual.net

Tip Reprezentare C# Descriere Domeniu

System.Byte byte intreg fara semn pe 8 biti de la 0 la 255

System.Int16 short intreg cu semn pe 16 biti de la -32768 la32767

System.Int32 int intreg cu semn pe 32 biti de la -2 la 31 la 2la 31 - 1

System.Int64 long intreg cu semn pe 64 biti de la -2 la 63 la 2la 63 - 1

System.SByte sbyte intreg cu semn pe 8 biti de la -128 la 127

System.UInt16 ushort intreg fara semn pe 16 biti de la 0 la 65535

System.UInt32 uint intreg fara semn pe 32 biti de la 0 to 2 la 32-1

System.UInt64 ulong intreg fara semn pe 64 biti de la 0 to 2 la 64-1

Tabel 1 - Tipuri intregi

Se pot atribui valori tipurilor intregi folosind fie notatia zecimala, fie hexazecimala.Pentru a folosi notatia hexazecimala pentru un literal intreg, acesta trebuie prefixat cu0x in Visual C#. De exemplu: int nr_intreg;

nr_intreg = 0x36BA;

Tipuri flotante Exista trei astfel de tipuri care pot fi folosite pentru a reprezenta numerecu parte fractionara. Tabelul urmator sintetizeaza aceste tipuri:

Tip Reprezentare C# Descriere

System.Single float variabila flotanta pe 32 biti, precizie - 7 cifresemnificative

System.Double double pe 64 biti semnificativi, precizie 15-16

System.Decimal decimal pe 128 biti, precizie - 28 semnificativa

Tabel 2 - Tipuri flotante

Observatii:

• System.Single - util pentru calcule in virgula mobila care necesita un grad scazut deprecizie

• System.Double - pentru calcule cu un grad mai mare de precizie, operand cunumere dintr-un interval foarte vast

• System.Decimal - grad foarte mare de precizie, folosind insa numere dintr-un intervalmai restrans

Tipuri non-numerice

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 13 of 203

Page 14: Aplicatii in Visual.net

• System.Boolean

• System.Char

• System.String

• System.Object

System.Boolean

Tipul System.Boolean este folosit pentru a reprezenta o valoare care este fie true, fiefalse. In C#, o variabila booleana este desemnata prin intermediul tipului bool, cuvalorile posibile true si false.

System.Char

Tipul System.Char reprezinta un caracter Unicode pe 16 biti. In C#, o variabila de tipchar (tipul C# asociat) poate fi definita prin specificarea explicita a unui caracter intreapostroafe: char caracter;

caracter = 't';

sau atribuind valoarea numerica a codului Unicode al caracterului variabilei de tip char,folosind o valoare hexazecimala din 4 cifre, corespunzatoare: char caracter;

caracter = '\u01fe';

System.String

Tipul System.String este un tip referinta care reprezinta o succesiune de date de tipChar. Cu alte cuvinte, un string poate desemna un cuvant, un paragraf, un cod sauorice alta succesiune de caractere. Tipul C# asociat este desemnat de cuvantulrezervat string.

Exemplu de utilizare: string sir;

sir = "Acesta este un string.";

System.Object

Tipul Object este parintele tuturor tipurilor din .NET Framework. Orice tip, fie valoare,fie referinta, este derivat din System.Object. Tipul C# asociat - object. Unei variabileobject i se poate asocia orice valoare sau obiect: object obj;

obj = 233;

obj = new System.Collections.ArrayList();

!

Daca un obiect de un anumit tip este stocat intr-o variabila object, trebuie reconvertitexplicit la acel tip pentru a accesa intreaga sa functionalitate.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 14 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 15: Aplicatii in Visual.net

Tipuri de conversii

Datele pot convertite in doua feluri: implicit, caz in care conversia este executataautomat, si explicit - conversie executata de utilizator.

Conversii implicite

Sunt conversii care se executa atunci cand nu exista riscul pierderilor de date. Deexemplu: int un_short = 100;

long un_long;

un_long = un_short;

Daca un tip poate fi convertit implicit la un alt tip, atunci primul tip poate fi utilizatoriunde in program unde se solicita cel de-al doilea tip, fara a folosi o sintaxa speciala.De exemplu: // functia prelucare_long

// are un parametru de tip long

int x = 100; // conversie implicita de la int la long

// efectuata la apelul functiei

prelucare_long(I);

Tabelul urmator ilustreaza conversiile implicite permise in C#:

De la La

byte short, ushort, int, uint, long, ulong, float, double, decimal

short int, long, float, double, decimal

int long, float, double, decimal

long float, double, decimal

float double

char int, uint, long, ulong, float, double, decimal

sbyte short, int, long, float, double, decimal

ushort int, uint, long, ulong, float, double, decimal

uint long, ulong, float, double, decimal

ulong float, double, decimal

Conversii explicite

In cazul unei conversii in care tipurile nu pot fi convertite implicit, trebuie aplicata oconversie explicita. Aceasta conversie se mai numeste cast. In C#, conversiile explicitenecesita folosirea unei sintaxe speciale. Exemplu:

int un_int = 100;

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 15 of 203

Page 16: Aplicatii in Visual.net

short un_short;

un_short = (short)un_int;

! Conversiile explicite pot fi riscante. In exemplul anterior, conversia s-a efectuat faranici un fel de problema pentru ca atat o variabila int, cat si una de tip short poate retinevaloarea 100. Sa consideram acum urmatorul exemplu:

int un_alt_int = 80000;

short un_alt_short;

un_alt_short = (short)un_alt_int;

Codul acestui exemplu nu va furniza eroare de compilare sau la run-time. Totusi,examinand valoarea lui short, aceasta nu va fi cea dorita, deoarece valoarea maxima adomeniului tipului short este mai mica decat valoarea la care se incearca conversia.

! Deoarece conversiile explicite sunt adesea riscante, este indicata folosirea lor numaiin cazuri absolut necesare, implementand un sistem adecvat de tratare a conversiilornereusite si a tuturor exceptiilor care ar putea fi aruncate. (vezi cursul 5).

Functionalitati asociate tipurilor de date Toate tipurile de date au o functionalitateimplicita (built-in ). Acestea suporta urmatoarele patru metode:

• Equals - determina daca doua instante sunt egale

• GetHashCode - actioneaza ca o functie hash pentru un tip de date

• GetType - returneaza tipul obiectului pentru instanta curenta

• ToString - returneaza o descriere a obiectului, intr-un format accesibil utilizatorului

? Din cele prezentate mai sus, reiese faptul ca tipurile de date ocupa un relativ mic dememorie. Totusi, cum este posibil ca fiecare tip sa implementeze aceste metode?Raspunsul este dat in cele ce urmeaza.

Boxing Boxing reprezinta conversia implicita a tipurilor valoare la tipuri referinta. Toateclasele si tipurile sunt derivate din Object, fiecare din cele patru metode amintite fiindmembre ale clasei Object. Deoarece toate clasele sunt derivate din Object, fiecareclasa poate fi convertita implicit la acest tip. La apelul uneia dintre cele patru metode,Common Language Runtime creaza o referinta temporara variabila de tip valoaredeclarata de utilizator si se permite tratarea acesteia ca fiind de tip referinta.

Boxing explicit(manual) - prin atribuirea variabilei detip valoare unei variabile de tipObject. Exemplu:

short s = 10;

object O;

O = s;

Unboxing reprezinta conversia unei variabile boxed la un tip valoare. Se realizeazaprin conversia explicita a obiectului la tipul dorit. Se poate executa unboxing numaipentru obiectele care au fost supuse operatiei de boxing.

Metoda Parse

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 16 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 17: Aplicatii in Visual.net

• Parse - metoda statica, asociata tuturor tipurilor de date. Efectueaza conversiastring-ului primit ca parametru la tipul din care face parte. Daca string-ul nu are uncontinut specific(potrivit) tipului care apeleaza metoda, se va genera o eroare.

short s;

string input;

input = "321";

// s = 321

s = short.Parse(input);

Functii pentru operatii cu siruri de caractere

Metode de instanta pentru siruri de caractere

Metoda Descriere

String.Insert Insereaza un string specificat in instanta curenta

String.PadLeft,String.PadRight

Adauga caractere la stanga, respectiv la dreapta sirului

String.Remove Elimina un numar specificat de caractere din string, incepand de la uncaracter precizat

String.Replace Inlocuieste toate aparitiile unui caracter specificat din string cu un altcaracter

String.Insert Insereaza un string specificat in instanta curenta

String.Split Returneaza un array de substringuri, obtinut prin separareatoken-urilor din stringul initial, dupa un separator specificat

String.Substring Returneaza un substring al stringului initial

String.ToCharArray Returneaza caracterele compunente ale sirului, sub forma de array decaractere

String.ToLower,String.ToUpper

Transforma stringul, convertind caracterele la litere mici, respectivmari

String.TrimEnd,String.TrimStart, String.Trim

Elimina spatiile de la sfarsitul, inceputul stringului sau, respectiv toatespatiile din cadrul sirului

Metode statice cu siruri de caractere

Metoda Descriere

String.Compare compara doua stringuri

String.Concat returneaza un string obtinut prin concatenarea a doua sau mai multesiruri de caractere

String.Format returneaza stringul formatat

String.Join returneaza un string obtinut prin concatenarea unui array de stringuri,specificand un separator si inserandu-l intre componentele array-ului

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 17 of 203

Page 18: Aplicatii in Visual.net

Sinteza

• .NET Framework furnizeaza un sistem robust, puternic tipizat de tipuri de date.Principalele tipuri - intregi, flotante, boolean, caracter si string.

• Exista doua tipuri de conversii - implicite, executate automat de CLR, atunci cand nuexista riscul pierderii de date si explicite, efectuate explicit prin scriere de cod,programatorul trebuind sa analizeze ci atentie cazurile care ar putea conduce laerori.

• Boxing - macanismul care permite tratarea tipurilor valoare ca tipuri referinta.Unboxing - converteste un tip referinta asupra caruia s-a efectuat anterior boxingcatre un tip valoare.

• Tipurile .NET contin functionalitate built-in specifica tipului. Metoda Parse esteimplementata de toate tipurile valoare, fiind utila pentru conversia string-uriloe latipuri valoare. Clasa String contine un set de functii care faciliteaza manipulareastring-urilor.

2. Constante, enumerari, tablouri, colectii

Utilizatorul simte adesea necesitatea organizarii grupurilor de obiecte intr-un anumit tipde structura. De exemplu, anumite obiecte, de acelasi tip sau de tipuri diferite trebuieaccesate secvential si este necesara o sintaxa pentru gestionarea organizariiobiectelor. Tablourile (array) permit organizarea grupurilor de obiecte similare sireferirea lor printr-un index, adesea in defavoarea accesarii prin nume. Colectiile suntsimilare tablourilor, dar implementeaza o functionalitate mai complexa, fiind utilizate, inspecial, pentru organizarea grupurilor de obiecte de tipuri diferite. Constantele pot priminume familiare si contin valori utilizate frecvent in program. Enumerarile (enum) permitorganizarea unor multimi de constante, facilitand executia anumitor operatii din cadrulprogramului.

Constante si enumerari

Constantele permit asignarea unor nume familiare anumitor valori utilizate frecvent incod. Enumerarile sunt multimi definite de utilizatori continand constante asociate uneimultimi de nume. Folosirea constantelor si enumerarilor faciliteaza scrierea de cod,debugging-ul codului si reduc numarul erorilor de scriere.

Utilizarea constantelor

Se foloseste cuvantul rezervat const Exemplu:

public const int MAX = 25000;Constantele pot fi de orice tip intrinsec sau enumerativ, dar nu de un tip definit deutilizator sau array. Constantele au o valoare fixata care odata stabilita nu mai poate fischimbata sau redefinita. Dupa definire, o constanta poate fi folosita in cod, prinspecificarea numelui asociat. De exemplu:

public const int MAX = 25000;

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 18 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 19: Aplicatii in Visual.net

public int half_max()

{

return MAX/2;

}

Ca si variabilele, constantele pot avea orice nivel de acces. Pentru a defini o constantacare va putea fi accesata de toti utilizatorii aplicatiei sau componentei, trebuie declaratapublic. O constanta declarata private va putea fi accesata doar in cadrul domeniuluiclasei care o defineste. internal permite accesarea constantei din cadrul assembly-uluicare o contine, iar o constanta protected permite accesul la constanta si tipurilormostenite din clasa care contine constanta.

Enumerari

Enumerarile permit lucrul cu multimi de constante, prin asocierea acestora cu numefamiliare utilizatorului. Exemplu:

public enum LunileAnului

{

Ianuarie = 1,

Februarie = 2,

// si celelalte..., cu valorile uzuale

Decembrie = 12

}

Tipul asociat implicit elementelor enumerarilor int, dar poate fi setat la orice alt tipnumeric integral de date (byte, short, int si long). Modalitatea de definirea explicita atipului elementelor se poate observa in exemplul urmator:

public enum LunileAnului : short

// cod ...

NU este obligatorie asocierea de valori membrilor enumerarii. Implicit, membrii vorprimi valori implicite, secvential, pornind de zero. Exemplu:

public enum Cifre

{

zero, // egal cu zero

unu, // egal cu doi

doi // egal cu trei

}

Dupa definirea membrilor enumerarii, acestia pot fi folositi in cod. In C#, trebuieefectuata o conversie explicita a membrilor la tipul dorit pentru a putea accesa valoareareprezentata. De exemplu:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 19 of 203

Page 20: Aplicatii in Visual.net

// se utilizeaza enumerarea Cifre anterioara

MessageBox.Show(((int)Cifre.doi * 3).ToString());

// se afiseaza 6

! Pot fi scrise metode care primesc enumerari ca parametri; codul scris astfel este maiputin supus la erorile de scriere. Exemplu:

public void PlanLunar(LunileAnului luna)

//enumerarea definita mai sus

{

switch(luna)

{

case LunileAnului.Februarie:

// cod...

break;

case LunileAnului.Martie:

// cod...

break;

// alte case-uri...

}

}

Tablouri (array)

Reprezinta o modalitate de gestionare a unei multimi de elemente de tip valoare sau aunei multimi de obiecte. Folosind tablouri, se pot grupa o serie de variabile, la care sepoate face referire folosind un index. Se pot accesa toate sau o parte dintre variabile siexamina sau modifica fiecare dintre aceste variabile. Se pot defini, de asemenea,tablouri multidimensionale. In .NET Framework, tablourile contin functionalitatiintrinseci(buit-in) care faciliteazaa o serie de operatii.

Declararea si initializarea tablourilor

Declararea si initializarea se pot face in cadrul aceleasi instructiuni. Pentru declarare,se specifica tipul si numarul elementelor din tablou. Pentru toate tablourile din C#,indexul primului element este zero, celelalte avand indecsi calculati secvential, pornindde la zero.

Exemplu:

// tablou cu 20 de elemente de tip short

short[] array_shorts = new short[20];

Declararea si initializarea se pot efectua, desigur, si in pasi separati. Exemplu:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 20 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 21: Aplicatii in Visual.net

//declarare

short[] array_shorts;

// initializare

array_shorts = new short[20];

Un tablou poate fi redefinit, modificandu-i dimensiunea la run-time. Exemplu:

// declarare si initializare

int[] intregi = new int[20];

// reinitializare

intregi = new int[45];

In exemplul anterior, datele continute de tablou sunt pierdute la reinitializare. Nu existanici o modalitate de salvare a datelor la reinitializare (excluzand o varianta manuala).

La crearea unui tablou cu elemente de tip referinta, declararea si initializarea tablouluinu conduc la umplerea tabloului cu membri de tipul respectiv. De fapt, se creaza untablou de referinte null care pointeaza la acel tip. Pentru a completa tabloul cu membrii,trebuie asignata fiecare variabila la un obiect. De exemplu:

// se creaza un tablou de obiecte

TipObiect[] obiecte = new TipObiect[10];

// se asigneaza elementului obiecte[0] un nou obiect de tipTipObiect

obiecte[0] = new TipObiect();

// asigneaza elementului obiecte[1] un obiect existent

TipObiect un_obiect = new TipObiect();

obiecte[1] = un_obiect;

// se atribuie celorlalte elemente cate un nou obiect

for (int contor = 2; contor < 10; contor++)

{

obiecte[contor] = new TipObiect();

}

Tablouri multidimensionale

Tablourile prezentate pana acum sunt liniare, adica, tablouri cu o singura dimensiune.Exista in .NET Framework doua tipuri de tablouri multidimensionale: tablourirectangulare si tablouri jagged.

Tablouri rectangulare

Sunt tablouri in care fiecare membru al fiecarei dimensiuni este extins in fiecare alta

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 21 of 203

Page 22: Aplicatii in Visual.net

dimensiune folosind aceeasi lungime. De exemplu, un tablou bidimensional,rectangular, poate fi gandit ca un tabel tabel, continand linii si coloane, fiecare linieavand acelasi numar de coloane.

Exemplu:

// tablou de 4 pe 3

int[ , ] intregi = new int[4, 3];

// tablou bidimensional cu valori initiale specificate

int[ , ] intregi2 = {{1, 2, 3}, {4, 5, 6}};

// tablou tridimensional

int[ , , ] cubeArray = {{{2, 2}, {2, 4}}, {{5, 5}, {4, 4}}};

// tablou complex: 2 x 3 x 5 x 5 x 6

int[ , , , , ] tablou_complex = new int[2, 3, 5, 5, 6];

Tablouri jagged

Un astfel de tablou, bidimensional, poate fi conceput ca un tabel in care fiecare liniepoate avea un numar diferit de coloane. De exemplu, sa consideram un tabel in carefiecare linie reprezinta un grad universitar, iar coloanele contin numele profesorilor careau gradul respectiv. Liniile vor putea avea, deci, un numar diferit de elemente. Pentru agestiona o astfel de structura, se foloseste un tablou jagged, ca mai jos:

// tablou de 5 tablouri

string[][] grade = new string[5][];

// specificam numai prima dimensiune

// primul tablou are 4 membri

grade[0] = new string[] {"Popescu", "Negara", "Ionescu","Radulescu"};

//o alta varianta de declarare si initializare

// al doilea tablou are 3 elemente

grade[1] = new string[] {"Vidrescu", "Alexandrescu", "Macovei"};

// si asa mai departe...

grade[3] = new string[] {"Buburuzan", "Georgescu"};

...

Colectii

Colectiile contin functionalitati avansate pentru gestionarea grupurilor de obiecte. Ocolectie este o clasa specializata care organizeaza si permite manipularea unui grupde obiecte. La fel ca la tablouri, membrii unei colectii pot fi accesati prin index. In plus,colectiile pot fi redimensionate dinamic, existand posibilitatea adaugarii si eliminarii deelemente la run time.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 22 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 23: Aplicatii in Visual.net

Colectiile sunt utile pentru gestionarea grupurilor de elemente create dinamic la runtime. De exemplu, ne putem imagina o colectie in care un element contine informatiidespre un salariat al unei institutii. Creand o colectie de obiecte de tip Salariat, va fiposibila accesarea obiectelor, iterarea acestora, adaugarea de noi obiecte saueliminarea obiectelor care devin irelevante.

Clasa ArrayList

System.Collections.ArrayList - confera functionalitati specifice de colectie utile intr-oserie intreaga de situatii. Aceasta clasa permite adaugarea si eliminarea dinamica deelemente din lista. Elementele sunt accesate prin index Exemplu:

System.Collections.ArrayList lista = new

System.Collections.ArrayList();

Metoda Add

Dupa instantiere, pot fi adaugate elemente intr-un ArrayList utilizand metoda Add:

TipObiect obiect = new TipObiect();

lista.Add(obiect);

!

Orice lista de tip ArrayList este o colectie zero-based . Primul obiect introdus in lista areindexul zero, elementele adaugate ulterior primind indexul imediat urmator elementuluianterior.

In C#, indexatorii sunt folositi pentru accesarea elementelor colectiilor, utilizand osintaxa similara tablourilor. Exemplu:

object obj;

obj = lista[0];

!

Toate referintele dintr-o colectie sunt de tipul object. Se impune, deci, folosireaconversiilor explicite, pentru a obtine un element avand acelasi tip ca tipul elementuluidin lista, returnat de indexator:

TipObiect obj;

obj = (TipObiect)listaObiecte[1];

Metodele Remove si RemoveAt

• Remove - elimina obiectul a carui referinta este primita ca parametru din colectie

• RemoveAt - elimina din colectie elementul de la indexul a carui valoare este primitaca parametru

Exemplu:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 23 of 203

Page 24: Aplicatii in Visual.net

TipObiect obj = new TipObiect();

System.Collections.ArrayList lista = new

System.Collections.ArrayList();

// adauga obj la colectie

lista.Add(obj);

// elimina obiectul obj din colectie

lista.Remove(obj);

System.Collections.ArrayList lista = new

System.Collections.ArrayList();

// adauga 5 elemente la colectie

for (int i = 0; i < 5; i++)

{

TipObiect obj = new TipObiect();

lista.Add(obj);

}

// elimina elementul cu indexul 3

lista.RemoveAt(3);

!

Incercarea de eliminare a unui obiect care nu este continut in colectie va fi ignorata,fara a se genera eroare.

La eliminarea unor elemente din colection, are loc o reasignare a indecsilor pentru a seocupa spatiile disponibile. Deci, valorile indecsilor sunt dinamice si pot returna referintediferite la momente diferite ale executiei aplicatiei.

Proprietatea Count Returneaza numarul de elemente din colectie (cu 1 mai mult decatindexul maxim).

Alte tipuri de colectii

Clasa Descriere

BitArray tablou compact de biti

CollectionBase serveste drept clasa de baza pentru implementarea propriilorclase cu functionalitate de colectie

Hashtable colectie de perechi de tip cheie-valoare, organizate dupa codulhash al cheii

Queue gestioneaza un grup de obiecte dupa principiul first-in, first-out

SortedList contine un grup de obiecte care pot fi accesate dupa index saudupa valoare

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 24 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 25: Aplicatii in Visual.net

Stack gestioneaza un grup de obiecte dupa principiul last-in, first-out

Enumerarea (iterarea) membrilor unui tablou sau colectii

C# ofera o sintaxa specializata pentru parcurgerea membrilor unui tablou sau colectii.Utilizarea cuvantului rezervat foreach permite examinarea succesiva a fiecarui membrual unui tablou sau colectii. Exemplu:

int[] tab = new int[] {1,2,3,4};

foreach (int i in tab)

{

MessageBox.Show(i.ToString());

}

!

Pentru o utilizare corecta a acestei sintaxe, toti membrii colectiei trebuie sa aiba acelasitip ca al variabilei desemnate ca iterator (i pentru exemplul anterior). In caz contrat, vafi aruncata o exceptie de tipul InvalidCastException. Solutie:declararea variabileiiterator de tip object si utilizarea metodei GetType pentru a inspecta tipul obiectelor dincolectie. Exemplu:

// lista este un ArrayList care contine

// elemente de tip string si alte elemente de alte tipuri

foreach (object o in lista)

{

if (o.GetType() == typeof(string))

{

MessageBox.Show(o.ToString());

}

}

!

Referinta continuta de iterator este read-only . Deci, sintaxa foreach nu poate fi folositapentru a efectua modificari ale tabloului sau colectiei. Solutie: folosirea unei sintaxe detip for. Exemplu:

int[] tab = new int[] {1,2,3,4};

for (int i = 0; i <= 3; i++)

{

tab[i] ++; // modificare permisa

MessageBox.Show(tab[i].ToString());

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 25 of 203

Page 26: Aplicatii in Visual.net

}

Sinteza:

• Constante si enumerari (const si enum). Constantele pot avea orice tip. Enumerariletrebuie sa aiba un tip numeric integral.

• Tablourile pot fi unidimensionale sau multidimensionale. Tablourilemultidimensionale pot fi rectangulare sau jagged.

• Colectiile permit gestionarea grupurilor de obiecte, cu elemente de acelasi tip sau detipuri diferite System.Collections ofera un set de clase cu diverse functionalitatispecifice colectiilor.

• Sintaxa foreach permite iterarea membrilor unui tablou sau colectii, fara a puteamodifica membrii. Pentru a altera valorile membrilor unui tablou sau colectii, sepoate utiliza o sintaxa de tip for.

3.Proprietati

Proprietatile sunt membri ai claselor care acceseaza variabile sau obiecte membre.Prezinta similaritati atat fata de campuri cat si fata de metode. Valorile sunt setate siinspectate folosind acceasi sintaxa ca in cazul campurilor: de fapt aceste doua operatiisunt efectuate prin apelul unor metode specializate. Proprietatile pot contine cod carevalideaza valorile inainte de a le seta sau pot indeplini alte functionalitati impuse deaplicatie.

Implementarea proprietatilor

Proprietatile permit accesarea valorilor si obiectelor membre intr-o maniera mai robustain comparatie cu inspectarea obisnuita a campurilor. O proprietate este o metodaspecializata care se comporta ca un camp. Valorile proprietatilor sunt setate siinspectate in acelasi mod ca si campurile, fapt ilustrat in exemplul urmator:

// seteaza proprietatea Text a butonului btnExit la "Exit"

btnExit.Text = "Exit";

string sir;

// returneaza valoarea lui btnExit.Text si o asigneazastring-ului sir

sir = btnExit.Text;

Pana acum, o proprietate arata si se comporta exact ca un camp. Totusi, codul asociatunei proprietati este mai complex. Exista doua metode speciale asociate uneiproprietati, un getter si un setter care returneaza si, respectiv, seteaza valoareaproprietatii. Exemplu:

// proprietatea se numeste Xmax

// o variabila locala care stocheaza valoarea

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 26 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 27: Aplicatii in Visual.net

private short x;

// implementarea proprietatii

public short Xmax

{

get

{

// returneaza valoarea variabilei locale

return x;

}

set

{

// seteaza valoarea variabilei locale

x = value;

}

}

Cuvantul rezervat value este un cuvant special folosit in setter-ul unei proprietati sireprezinta intotdeauna valoarea la care se seteaza proprietatea. Proprietatile potexpune orice tip de obiecte, tablouri sau colectii. Valoarea sau obiectul este retinut, deobicei, intr-o variabila privata locala (x in exemplul anterior) si returnat atunci candproprietatea este accesata.

Exemplul anterior poate fi considerat trivial, proprietatea Xmax comportandu-se exactca un camp. Avantajul utilizarii proprietatilor consta in posibilitatea scrierii de codaditional in getter-ul si setter-ul proprietatii pentru a efectua calcule sau valida input-ul.Exemplu:

private short x;

public short Xmax

{

get

{

// returneaza valoarea variabilei locale

return x;

}

set

{

// valoarea nu trebuie sa depaseasca 500

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 27 of 203

Page 28: Aplicatii in Visual.net

if (value > 500)

MessageBox.Show(value.ToString() +

" coordonata x nu poate depasi valoarea 500!");

else

x = value;

}

}

De retinut:

Pentru a crea o proprietate:

• creati o variabila private care va retine valoarea sau obiectul returnat de proprietate

• scrieti cod pentru returnarea valorii proprietatii

• adaugati cod pentru validare sau efectuare de calcule in getter-ul si setter-ulproprietatii

Proprietati read-only si write-only

Uneori, programatorul trebuie sa implementeze a proprietate care returneaza o valoarecare nu mai poate fi modificata dupa ce clasa a fost initializata. Alteori, intr-un numarmai mic de situatii, se impune crearea unei proprietati a carei valori poate fi modificatadar nu poate fi citita. Aceste proprietati sunt numite read-only si, respectiv, write-only .

Proprietati read-only

Crearea unei proprietati read-only se realizeaza prin specificarea getter-ului si omitandsetter-ul proprietatii. Variabila private care retine valoarea proprietatii este declarata, incele mai multe cazuri, readonly (acest lucru nu este obligatoriu). Exemplu:

private readonly short s;

public short ShortNumber

{

get

{

return s;

}

}

!

Setarea variabilei care retine valoarea proprietatii trebuie efectuata in constructorulclasei sau la initializarea variabilei.

Proprietati write-only

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 28 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 29: Aplicatii in Visual.net

In anumite cazuri, pot fi implementate proprietati care pot fi scrise, dar nu citite, decatre utilizator. Exemplu: pozitionarea unei forme in functie de setari specificelocalizarii(culturii) aplicatiei (localizare - concept care va fi prezentat intr-un curs viitor) -forma este pozitionata la lansarea aplicatiei, nefiind necesara consultarea valoriiproprietatii respective.

O proprietate write-only se creaza similar unei proprietati obisnuite, omitandimplementarea getter-ului. Exemplu:

private short x;

public short XmaxForm

{

set

{

x = value;

}

}

Indexatori

Sunt proprietati specializate care permit accesarea obiectelor dintr-un grup. Numeleproprietatii este this, asociindu-se o variabila index. Exemplu:

// tablou care va stoca valorile retunate de indexator

private int[] tablou;

// sintaxa speciala care foloseste cuvantul rezervat this

public int this[int index] // indexatorul

{

get

{

return tablou[index];

}

set

{

tablou[index] = value;

}

}

Proprietati ale colectiilor

Expunerea colectiilor de obiecte ca proprietati permite controlarea accesului laobiectele componente si validarea operatiilor de atribuire. Modalitatile de implementare

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 29 of 203

Page 30: Aplicatii in Visual.net

a acestor proprietati depind de natura si functionalitatea colectiilor. O proprietate simplaeste cea care returneaza colectia ca un singur obiect (pentru siguranta, proprietateapoate fi definita read-only, utilizatorul putand modifica obiectele din colectie folosindmetodele colectiei). Exemplu:

private readonly System.Collections.ArrayList list_objects = new

System.Collections.ArrayList();

public System.Collections.ArrayList objects

{

get

{

return list_objects;

}

}

!

Aceasta abordare nu rezolva problema verificarii tipurilor obiectelor adaugate lacolectie (membrii colectiei sunt tratati ca obiecte).

Iata o abordare mai pertinenta:

private System.Collections.ArrayList list_objects = new

System.Collections.ArrayList();

public ItemType GetItem(int i)

{

return (ItemType)list_objects[i];

}

public void SetItem(int i, ItemType item)

{

list_objects[i] = item;

}

Acesta abordare rezolva problema tipizarii, insa rapeste utilizatorului posibilitateafolosirii sintaxei foreach pentru parcurgerea elementelor colectiei.

!

Pentru implementarea unor proprietati care implica functionalitati avansate se pot definicolectii derivate din System.Collections.CollectionBase.

Sinteza:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 30 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 31: Aplicatii in Visual.net

• proprietati - expun variabile sau obiecte membre, furnizand cod pentru validareavalorilor proprietatilor sau pentru efectuarea altor operatii; proprietatile read-only siwrite-only limiteaza abilitatea utilizatorului de a consulta sau modifica propriatatile.

• indexator - proprietate implicita a colectiilor

• proprietatile colectiilor expun grupuri de obiecte din colectie

4.Delegati.Evenimente

Evenimentele reprezinta o notificare determinata de o actiune survenita intr-o sectiunea a aplicatiei. La aparitia unui eveniment, altor parti ale aplicatiei li se oferaoportunitatea de a raspunde prin executis unor metode denumite event handler-e.

Delegati

Un delegat este, in principiu, un pointer type-safe la o functie care permitetransmiterea unei referinte catre inceputul unei metode si apelarea metodei fara afolosi un apel explicit al acesteia. La declararea unui delegat, se specifica signaturametodei apelate si tipul returnat

Exemplu:

public delegate int firstDelegate(double D);

// acest delegat poate invoca metode care returneaza un int

// si primesc un parametru double

// metoda care va fi invocata de delegat

public int ReturnInt(double D)

{

// implementare...

}

// declararea unei instante firstDelegate si

// invocarea metodei ReturnInt

public void invokeMethod()

{

firstDelegate aDelegate = new firstDelegate(ReturnInt);

}

Invocarea metodei pentru care s-a instantiat delegatul:

aDelegate(6780.87);

Declararea si folosirea unui delegat:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 31 of 203

Page 32: Aplicatii in Visual.net

• se declara delegatul, specificand o signatura identica cu cea a metodelor care vor fiinvocate

• se creaza o instanta a delegatului care pointeaza catre o metoda care are signaturaadecvata

• se apeleaza delegatul prin folosirea numelui sau, cu parametrii corespunzatori

Declararea si lansarea evenimentelor

Declaring and Raising Events Formele si controalele au evenimente membre implicite(built-in) care sunt apelate cand au loc anumite actiuni in program. De exemplu,evenimentul Click este lansat la executia unui clic asupra butonului.

In C#, pentru declararea unui eveniment, trebuie desemnat explicit tipul delegatuluicare va fi utilizat de eveniment:

public delegate void calculationDelegate(double d);

public event calculationDelegate CalculationComplete;

Odata declarat, evenimentul poate fi lansat in code atunci cand actiunile care vor finotificate de eveniment au loc. De exemplu, o componenta BankAccount lanseaza uneveniment Closing atunci cand se doreste inchiderea contului.

//Evenimentle in C# sunt lansate prin nume,

//ca in cazul unei metode

CalculationComplete(100000);

Tratarea evenimentelor

Dupa declarare, evenimentul trebuie asociat unuia sau mai multor event handlereinainte de a putea fi lansat raised. Un event handler este o metoda apelata prinintermediul unui delegat atunci cand un eveniment este lansat. Lansarea unuieveniment care nu are asociat nici un event handler provoaca aparitia unei erori.

Event Handlere

Un event handler C# poate returna o valoare care poate fi asignata unei variabile la felca in cazul unui apel de functie. Asocierea unei metode cu un eveniment se realizeazaprin crearea unei instante a unui delegat adecvat evenimentului care specifica, larandul sau, metoda pe care o invoca; se utilizeaza operatorul += pentru realizareaasocierii. Se pot crea, de aemenea, asocieri intre un evenimentt si o instanta a unuidelegat existent. De exemplu:

// metoda DisplayResults are signatura adecvata

// delegatului CalculationDelegate

// se creaza un nou delegat pentru a crea asocierea

Account.CalculationComplete += newcalculationDelegate(DisplayResults);

// asociere cu un delegat existent

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 32 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 33: Aplicatii in Visual.net

calculationDelegate calc = newcalculationDelegate(DisplayResults);

Account.CalculationComplete += calc;

Pentru evenimentele asociate controalelor si claselor .NET Framework exista delegatiimpliciti; acestia nu mai trebuie declarati ci doar instantiati. Exemplu: clasaSystem.EventHandler este clasa cea mai utilizata pentru instantierea delegatilor.

button1.Click += new

System.EventHandler(clickHandler);

Sinteza:

pentru a trata un eveniment in C#, se creaza o instanta a delegatului care va fi asociatevenimentului care va fi tratat si se foloseste operatorul += pentru a realiza asociereaeveniment - delegat.

Event-handlere care trateaza mai multe evenimente

// ClickHandler este o metoda cu signatura adecvata

// tratarii evenimentului clic pentru un buton

button1.Click += new System.EventHandler(ClickHandler);

button2.Click += new System.EventHandler(ClickHandler);

Evenimente cu handlere multiple

Un eveniment poate fi tratat de mai multe handlere,acestea apelandu-se in ordineaasocierii (operatorul +=), valoarea returnata de eveniment avand tipul returnat deultimul event handler asociat.

Eliminarea handlerelor la run-time

// se foloseste operatorul -=

Account.CalculationComplete -= new

calculationDelegate(DisplayResults);

Sinteza

• evenimentele sunt membri ai claselor utilizati pentru notificarea anumitor actiuni dinprogram. O instanta a unei clase poate lansa un eveniment membru pentru atransmite notificarea. Evenimentul poate fi trata de metode desemnate drept eventhandlere. Aceste metode sunt executate la lansarea evenimentului.

• delegatii implementeaza functionalitatea de la baza evenimentelor. Un delegat estepointer la o functie, puternic tipizat. Poate invoca o metoda fara apelul explicit alacesteia. Asocierile dintre evenimente si event handlere implica utilizarea explicita adelegatilor.

• Evenimentele sunt declarate ca membri ai clasei; pot fi apelati prin nume si potreturna o valoare.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 33 of 203

Page 34: Aplicatii in Visual.net

• Metodele care trateaza evenimentele se numesc event handlere. Un event handlerse creaza prin utilizarea operatorului += pentru a asocia un delegat evenimentului.

• Evenimentele pot avea mai multe event handlere asociat, si evenimente multiple potfi tratate de acceasi metoda. Event handlerele pot fi eliminate dinamic (folosindoperatorul -=).

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 34 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 35: Aplicatii in Visual.net

Section 4. Gestionarea interfetelor utilizator - III

1. Design-ul interfetelor utilizator - principii

• Descrierea importantei interfetei utilizator

• Rolul formelor, controalelor si a meniurilor in cadrul interfetelor

• Importanta compozitiei si culorilor interfetei utilizator

• Explicarea folosirii imaginilor, icon-urilor si a fonturilor in design-ul interactiv

Forme, controale, meniuri

• formele contin informatii si optiuni utile utilizatorilor

• fiecare forma este o clasa, pentru care se pot crea instante sau care poate fi folositadrept clasa de baza

• controalele fac informatiile accesibile utilizatorilor

• meniurile si tool box-urile furnizeaza o modalitate structurata de a expune comenziledisponibile utilizatorilor aplicatiei

Aspectul si functionalitatea aplicatiei

• simplitate

• pozitionarea controalelor

• consistenta: organizare, culori, forme, marime, tipuri, imagini, transparenta

• estetica

Sinteza:

• o interfata consistenta din punct de vedere vizual si logic este mult mai usor deinteles si folosit

• elementele de baza ale unei interfete sunt formele, controalele si meniurile

• o interfata reusita trebuie sa tina cont de cateva aspecte legate de look si feel

• sunt importante deciziile de design adresate direct utilizatorilor - semnificatiiculturale, consistenta, simplitate

2. Forme

Formele reprezinta unitatea fundamentala a unei interfete utilizator. Ele furnizeaza oplatforma pe care se plaseaza controalele si permit prezentarea aplicatiei intr-omaniera consistenta si atractiva. Formele afiseaza date si primesc input-ul utilizatorilor.De obicei, aplicatiile contin una sau mai multe forme, organizate astfel incat sa urmezelogica fireasca a aplicatiei.

• stabilirea rolului unei forme intr-o aplicatie

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 35 of 203

Page 36: Aplicatii in Visual.net

• adaugarea de forme la o aplicatie

• setarea formei de start si a locatiei de start

• setarea aspectului vizual al unei forme

• folosirea metodelor unei forme

• evenimente din cadrul metodelor

Adaugarea de forme la o aplicatie

La crearea unui proiect de tip Windows Forms, se creaza si se adauga la proiect oforma initiala, denumita Form1. Form1 nu reprezinta, efectiv, o instanta a unei forme, cimai degraba o clasa care contine codul asociat unei instante a formei. Designer-ul esteo reprezentare grafica a componentei(de obicei o forma) supuse design-ului, conferindposibilitatea adaugarii de controale, meniuri sau alte elemente vizuale formeirespective. Odata cu cresterea in dimensiuni a aplicatiei, se creaza noi forme sau altecomponente necesare bunei functionalitati a aplicatiei.

Adaugarea unei noi forme la un proiect:

1. Meniul Project, Add Windows Form. Se deschide astfel fereastra de dialog Add NewItem.

2. Se selecteaza Windows Form, apoi Open. Este adaugata o noua forma mediului delucru.

Adaugarea unei forme la o aplicatie la run time:

Se declara si se instantiaza o variabila reprezentand forma in aceeasi maniera ca incazul oricarei alte clase.

De exemplu:

// se presupune existenta unei forme de tip DialogForm

DialogForm forma1;

forma1 = new DialogForm();

Mostenirea vizuala

Mostenirea vizuala este un concept care se refera la crearea de noi forme, pornind dela forme existente, in ideea de a pastra caracteristicile vizuale si functionalitateaclaselor de baza. Aceasta tehnica permite crearea unei forme care incorporeaza totimembrii, controalele, meniurile si codul asociat unei forme existente, folosind aceastaforma ca baza pentru implementarea unei functionalitati aditionale. Pentru a crea relatiide mostenire se poate folosi fie Inheritance Picker-ul, fie varianta scrierii de cod.

Crearea unei forme derivate folosind Inheritance Picker-ul:

1. Meniul Projects, Add Inherited Form. Se deschide fereastra de dialog Add New Item.

2. In panoul din stanga se selecteaza Local Project Item, in dreapta, Inherited Form. Seintroduce un nume si se deschide Inheritance Picker-ul.

3. Acesta afiseaza formele existente in proiect, dintre acestea selectandu-se forma de

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 36 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 37: Aplicatii in Visual.net

baza care va fi asociata noii forme create.

! se poate alege drept clasa de baza si o forma dinafara proiectului, aceasta trebuie safie compilata intr-un fisier EXE sau DLL.

Crearea unei forme derivate folosind scrierea de cod:

1. Meniul Projects, Add Windows Form.

2. Se modifica, in codul asociat clasei create, declaratia clasei.

// FormaBaza este o clasa existenta,

// asociata unei forme din proiect

public class FormaDerivata : FormaBaza

{

// implementare

}

! Proiectul trebuie sa aiba acces la forma din care de deriveaza. Deci, el trebuie saincluda fie o referinta la assembly-ul care contine forma parinte (in acest exemplu,MainForm) sau forma trebuie sa fie inclusa in proiect.

Setarea formei de start

Daca o aplicatie de tip Windows Forms contine mai multe forme, trebuie sa sedesemneze o forma de start. Forma de start va fi prima forma incarcata la executiaaplicatiei.

public static void Main()

{

Application.Run(new myForm());

}

Setarea formei de start in Visual C# se face utilizand meniul Projects, optiuneaProperties, apoi la StartupObject se alege forma dorita.

Setarea pozitiei de start

Proprietatea StartPosition se poate utiliza pentru a determina pozitia pe ecran la carese va afisa prima data o forma. Aceasta poate fi setata la oricare dintre valorileenumerarii FormStartPosition.

Valori FormStartPosition

Valoare Efect

Manual Forma se deschide la pozitia determinata de proprietateaLocation.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 37 of 203

Page 38: Aplicatii in Visual.net

CenterScreen Forma se deschide centrat pe ecran.

WindowsDefaultLocation Forma se deschide la locatia implicita determinata desetarile Windows.

WindowsDefaultBounds Forma se deschide la pozitia Windows implicita, avandmarimea stabilita prin setari Windows implicite.

CenterParent Forma se deschide centrat, peste forma parinte.

Modificarea aspectului unei forme

Aspectul unei interfete este o parte importanta a unei aplicatii. Utilizarea proprietatiloratasate diferitelor obiecte permite utilizatorului modificarea aspectului formelor.

Modificarea proprietatilor:

- din fereastra Properties

- modificand codul, la run-time

// schimbarea culorii unei forme form1

form1.BackColor = System.Drawing.Color.Red;

Proprietatile BackColor, ForeColor si Text

• Text - stabileste titlul formei.

• BackColor si ForeColor - reprezinta culorile atasate unei forme.

ForeColor este culoarea textului in foreground.

BackColor reprezinta culoarea de background a formei.

Alte proprietati:

Valoare Efect

Font specifica fontul folosit in cadrul formei

Cursor specifica icon-ul care apare atunci cand sageatamouse-uluise afla deasupra formei

BackGroundImage permite setarea unei imagini de background

Opacity

- variaza gradul de transparenta al formei

- valori posibile: in intervalul [0, 1]. Valoarea 1 indica faptul ca forma este completopaca, iar valoarea 0 creaza o forma complet transparenta. Valorile intermediareimprima formei o transparenta partiala. Valoarea implicita este 1 (opacitate totala).

// o forma semi-transparenta

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 38 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 39: Aplicatii in Visual.net

MyForm.Opacity = .5;

! in fereastra Properties, Opacity este reprezentata ca o valoare procentuala.

Utilizarea metodelor specifice formelor

Orice forma incapsuleaza un set functional de baza mostenit din clasaSystem.Windows.Forms.Form. Printre acestea, se gasesc metodele responsabile demodul de afisare si de posibilitatile de accesare a formei in mediul de lucru. Cele maiimportante astfel de metode:

• Form.Show

• Form.ShowDialog

• Form.Activate

• Form.Hide

• Form.Close

Folosirea acestor metode implica existenta unei instante a formei in memorie. Pe langainstantele formelor create in cod, aplicatia creaza o instanta a formei de start-up inlansarii in executie a programului.

Show si ShowDialog

- Form.Show - face forma vizibila (se incarca in memorie o instanta a formei, seafiseaza forma pe ecran si primeste focus-ul aplicatiei). Proprietatea Visible este setatala true dupa apelul lui Form.Show. Pentru o forma incarcata in memorie dar care esteinvizibila (de exemplu, daca proprietatea Visible a fost setata la valoarea false), apelulForm.Show are acelasi efect ca setarea proprietatii Visible la valoarea true.

- Form.ShowDialog - in plus, afiseaza forma modal, adica forma trebuie inchisa inainteca orice alta forma sa poata primi focus-ul.

// DialogForm este o clasa asociata unei forme existente

DialogForm myForm = new DialogForm();

//afiseaza fereastra in mod uzual

myForm.Show();

//afizeaza fereastra modal

myForm.ShowDialog();

Activate

• pentru o forma vizibila, dar care nu a primit inca focus-ul, se poate utiliza metodaForm.Activate

• apelata in cadrul aplicatiei active, metoda Form.Activate aduce forma in prim-planulaplicatiei si ii transmite focus-ul

• apelarea metodei pentru o aplicatie inactiva in interfata utilizator, determina clipireatitlului aplicatiei din taskbar

• forma pentru care se apeleaza metoda Activate trebuie sa fie vizibila pentru a obtine

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 39 of 203

Page 40: Aplicatii in Visual.net

efectul scontat.

//apelarea metodei Activate

myForm.Activate();

Hide

• face forma invizibila. Desi forma persista in memorie, nu va mai fi vizibila pana laapelarea metodei Form.Show sau la setarea proprietatii Visible la valoarea true incod

• apelul metodei Hide seteaza proprietatea Visible la false

//apelarea metodei Hide

myForm.Hide();

Close

• Form.Close inchide forma si o elimina din memorie

• se inchid toate resursele continute de forma, fiind preluate de garbage collector

• apelul Form.Close anuleaza efectul unui apel ulterior Form.Show, pentru caresursele asociate formei nu mai sunt disponibile

• apelul Form.Close pentru forma de start-up determina inchidera aplicatiei

//apelarea metodei Close

myForm.Close();

Evenimente din cadrul formelor

Eveniment - o notificare survenita in urma unei actiuni din program. Aplicatia lanseazaevenimentul, iar o alta componenta a aplicatiei are oportunitatea de a trata evenimentulrespectiv. Fiecare dintre metodele prezentate anterior lanseaza unul sau mai multeevenimente; utilizatorul are oportunitatea de a trata prin cod aceste evenimente.Exemple: apelul metodei Form.Hide determina lansarea evenimentelor Deactivate siVisibleChanged. Un event handler este o metoda care se executa ca raspuns lalansarea unui eveniment.

Crearea unui event handler pentru o forma, un control sau o componenta

1. Design view - selectarea formei sau a controlului pentru care se va crea eventhandler-ul

2. Properties - butonul Events

3. din lista evenimentelor disponibile se selecteaza evenimentul dorit

4. se scrie codul pentru event handler

Argumentele event handler-elor

Exemplu:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 40 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 41: Aplicatii in Visual.net

private void Form1_Load(object sender, System.EventArgs e)

{

// codul metodei

}

Argumente:

- sender - obiect care contine o referinta catre obiectul care a lansat evenimentul

- e - instanta a clasei EventArgs; poate contine informatii suplimentare

! se poate obtine o referinta catre tipul care a cauzat lansarea evenimentului, in cazulin care se cunoaste acest tip, printr-o conversie explicita a argumentului sender la tipulrespectiv. De exemplu:

Form1 myForm;

myForm = (Form1)sender;

In multe cazuri, parametrul EventArgs nu contine informatii folositoare din punct devedere programatic. Exista insa situatii in care acest parametru furnizeaza informatiiutile.

Evenimente referitoare la durata de viata a unei forme

• Load

• Activated/Deactivate

• VisibleChanged

• Closing

• Closed

Load

Se lanseaza in momentul in care o forma este incarcata pentru prima oara in programla primul apel al metodelor Form.Show sau Form.ShowDialog.

Exemplu:

Form myForm = new Form();

myForm.Show();

// se lanseaza Load

myForm.Hide();

// forma este acum invizibila

myForm.Show();

// nu se mai lanseaza Load

myForm.Close();

// se inchide forma

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 41 of 203

Page 42: Aplicatii in Visual.net

myForm.Show();

// exceptie, forma nu mai este disponibila

!

evenimentul Load este lansat o singura data pe parcursul duratei de viata a uneiinstante a formei

Activated/Deactivate

Evenimentul Activated poate aparea in urmatoarele situatii (la primirea focus-ului):

- la apelul metodelor Form.Show, Form.ShowDialog, Form.Activate

- cand o forma este adusa in prim-planul aplicatiei

Deactivate apare ori de cite ori o forma pierde focus-ul:

- prin interactiunea utilizatorului cu interfata

- la apelul metodelor Form.Hide sau Form.Close (Form.Close lanseaza evenimentulnumai daca forma este activa)

! Activated si Deactivate sunt lansate numai cand focus-ul este modificat prinintermediul programului.

VisibleChanged

- lansat la schimbarea proprietatii visible a formei la apelul metodelor Form.Show,Form.ShowDialog, Form.Hide si Form.Close.

Closing - lansat in cazul in care forma este in curs de inchidere, dar nu este incainchisa complet

- prin apelul Form.Close sau prin apasarea butonului Close al formei

- signatura event handler-ului asociat evenimentului Closing include o instansa a claseiCancelEventArgs

//anularea inchiderii formei

private void Form1_Closing(object sender,

System.ComponentModel.CancelEventArgs e)

{

e.Cancel = true;

}

Closed

- se lanseaza dupa ce forma a fost inchisa prin apelul Form.Close sau prin inchidereamanuala a formei; apare dupa lansarea evenimentului Closing si dupa executia tuturorhandler-elor asociate acestuia

Sinteza:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 42 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 43: Aplicatii in Visual.net

Formele reprezinta elementul de baza al interfetei utilizator pentru un program de tipWindows Forms. Formele trebuie sa contina o interfata consistenta, completa siatractiva pentru utilizator.

Proprietati care controleaza aspectul unei forme:

• BackColor

• ForeColor

• Text

• Font

• Cursor

• BackGroundImage

• Opacity

Metode care controleaza durata de viata si modul de afisare a formelor:

• Form.Show

• Form.ShowDialog

• Form.Activate

• Form.Hide

• Form.Close

Fiecare dintre aceste metode provoaca schimbari de vizualizare si lanseaza diverseevenimente. Printre acestea:

• Load

• Activated/Deactivate

• VisibleChanged

• Closing

• Closed

Event handler-e: metode specializate de tratare a evenimentelor.

3. Controale si componente

Controalele reprezinta al doilea element al unei interfete vizuale, in ordinea importantei,dupa forme.

Functionalitate:

- o parte dintre controale, cum ar fi Button sau TextBox, sunt desemnate sa accepteinput-ul utilizatorului si sa execute operatii bazate pe interactiunea utilizatorului

- o alta parte constituie componente specializate, proiectate sa execute interactiunicomplexe cu alte parti ale aplicatiei.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 43 of 203

Page 44: Aplicatii in Visual.net

Asemanari si deosebiri intre controale si componente: ambele reprezinta unitati de codcare incapsuleaza functionalitati specifice; controalele au o reprezentare vizuala, intimp ce componentele nu.

Controale

Adaugarea unui control intr-o aplicatie Windows Forms

1. din Toolbox, se selecteaza controlul dorit.

2. se adauga controlul pe forma

3. eventual, se face o repozitionare a controlului.

Setarea proprietatilor unui (sau mai multor) control (controale) se realizeaza, cel maifrecvent, folosind fereastra Properties

Adaugarea de componente la o forma se face in acelasi mod, la fel si setareaproprietatilor. Diferenta principala fata de controale este aceea ca nu exista oreprezentare vizuala a componentelor, odata cu adaugarea lor la o forma.

Control Tab Order

Utilizatorii pot folosi tasta Tab pentru a transmite focus-ul de la un control la altul, intr-oanumita ordine - tab order. Aceasta ordine este specificata de proprietatea TabIndex.Pentru a stabili ordinea de primire a focus-ului, se seteaza proprietatea TabIndex afiecarui control la o anumita valoare. Focus-ul va fi transmis controalelor in ordineacrescatoare a valorilor proprietatii TabIndex. Visual Studio ofera a alta modalitate desetare a ordinii de primire a focus-ului. Din meniul View, se alege Tab Order. Indesigner, apare o casuta in interiorul fiecarui control care, prin clic ofera posibilitateasetarii unui numar. Ordinea de primire a focus-ului este ordinea data de valorilenumerelor respective.

!

Exista controale care nu pot primi focus-ul, deci nu au asociata proprietatea TabIndex.

Controale container

Sunt controale speciale care ofera posibilitatea gruparii mai multor butoane in interiorullor. Exemple de astfel de controale - Panel, GroupBox si TabControl. Pot fi folositepentru organizarea logica a grupurilor de controale pe o forma. De exemplu, se potgrupa un set de butoane radio intr-un control GroupBox.

!

- Un control container se comporta ca o gazda pentru alte controale, dar esteindependent de aceste controale. In contrast, exista controale utilizator care pot legacontroale multiple intr-o singura unitate interdependenta.

- Modificarea proprietatilor unui control container poate afecta proprietatile controalelorcontinute. De exemplu, daca proprietatea Enabled a unui GroupBox este setata lafalse, toate controalele continute devin disabled. La fel se intampla in cazulproprietatilor BackColor, ForeColor, Visible si Font. Acesta confera un aspect

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 44 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 45: Aplicatii in Visual.net

consistent interfetei utilizator.

GroupBox si Panel

Sunt doua controale container similare. Amandoua furnizeaza posibilitatea grupariilogice si fizice a controalelor. Pot fi proiectate ca subdiviziuni ale formei. Modificareaproprietatilor unui control Panel sau GroupBox afecteaza toate controalele continute.Acestea pot fi grupate sau repozitionate ca o singura unitate in momentul design-ului.La run-time, tot grupul poate fi dezactivat prin setarea proprietatii Enabled la false.

GroupBox - furnizeaza un titlu care va fi asociat intregului grup controale (modificandproprietatea Text).

Panel - un container cu scroll, nu contine o proprietate text. Setand proprietateaAutoScroll la true, se ataseaza bare de defilare panel-ului respectiv.

TabControl

- grupeaza controalele intr-o multime de tabele (similar diviziunilor dintr-o carte deadrese)

- un TabControl este un suport pentru un anumit numar de TabPages, care gazduiescalte controale

- exemplu de TabControl: pagini de proprietati pentru o aplicatie, fiecare tab continandproprietati referitoare la o componenta specifica aplicatiei.

Proprietatea TabPages reprezinta o colectie de controale TabPage, fiecare cu setulsau de proprietati. O pagina din TabPages este similara controlului de tip Panel.Adaugarea de TabPages se efectueaza prin utilizarea proprietatii TabPages.

Docking si Anchoring

Reprezinta proprietati ale controalelor care dicteaza comportamentul acestora in cadrulformei sau controlului parinte.

- Anchor permite definirea unei distante constante intre un control si una sau mai multemargini ale formei

- redimensionarea unei forme la run time implica pastrarea unei distante specifice fatade marginile indicate

- valori posibile : o enumerare care poate contine, separate prin virgule una sau maimulte dintre valorile Top, Left, Right, Bottom

- Dock permite atasarea controlului la una din marginile formei sau ocuparea completaa formei de catre control

- redimensionarea formei atrage dupa sine redimensionarea controlului

- setarea valorii se face prin folosirea micro-interfetei grafice puse la dispozitie infereastra Properties

Utilizarea colectiei Controls

Fiecare container, incluzand formele, expun o colectie a tuturor controalelor continute -controls collection. Colectia expune o proprietate Count care returneaza numarul de

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 45 of 203

Page 46: Aplicatii in Visual.net

elemente continute si o proprietate Item care returneaza un element specific. Exista, deasemene, metode care pot fi folosite pentru a adauga si elimina controale in cadrulcolectiei.

// se presupune existenta unei instante myForm

Control aControl;

aControl = myForm.Controls[3];

Label aLabel = new Label();

aLabel.Text = "Eticheta adaugata dinamic";

myForm.Controls.Add(aLabel);

myForm.Controls.Remove(Button1);

myForm.Controls.RemoveAt(3);

//sintaxa similara pentru adaugare si eliminare

//de controale intr-un

//Panel, GroupBox sau TabPage control

// myTabControl este o instanta a unui TabControl

Button aButton = new Button();

// se adauga un buton paginii cu indexul 1 in colectia

// TabPages din TabControl

myTabControl.TabPages[1].Controls.Add(aButton);

Adaugarea de noi controale in Toolbox

1. Se alege colectia din Toolbox la care se doreste adaugarea controlului.

2. Right-click in interiorul colectiei selectate - Customize Toolbox.

!

se pot adauga componente .NET sau componente COM existente

3. se poate selecta un control deja inregistrat in lista sau se foloseste Browse pentru alocaliza un control inca neinregistrat.

!

un control care se doreste adaugat trebuie recunoscut ca ActiveX Control, componentaCOM sau assembly .NET

Event Handlere pentru controale

Fiecare control poate lansa o varietate de evenimente care corespund interactiunii cuutilizatorul. Un exemplu este apasarea unui buton care determina lansarea unuieveniment, cautandu-se apoi eventualele handlere; handlerele gasite sunt lansate inexecutie. Fiecare control are un eveniment implicit asociat, care reprezinta evenimentullansat cel mai frecvent. De exemplu, evenimentul implicit pentru Button este Click, iar

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 46 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 47: Aplicatii in Visual.net

pentru Checkbox, CheckChanged.

Crearea unui event handler pentru evenimentul implicit al unui control:

1. In designer, se executa dublu clic pe control. Se deschide fereastra de cod asociataevent handler-ului.

2. Se scrie codul dorit pentru event handler.

Pentru a crea un event handler pentru un eveniment in general:

1. Design view - se selecteaza controlul.

2. Din fereastra Properties - se selecteaza Events. Se afiseaza lista evenimentelordisponibile pentru controlul respectiv.

3. Se alege evenimentul dorit, apoi se scrie codul.

4. Daca exista deja event handler-e implementate pentru controlul respectiv, se poatealege una din metodele existente, din drop-down-ul asociat evenimentului respectiv.

Interactiunea cu mouse-ul

Tabel - Evenimente determinate de interactiunea cu mouse-ul

Eveniment Descriere Tip EventArgs

MouseEnter mouse-ul intra in zona controlului System.EventArgs

MouseMove mouse-ul se misca pe suprafatacontrolului

System.MouseEventArgs

MouseHover mouse-ul se afla pe suprafatacontrolului

System.EventArgs

MouseDown mouse-ul se afla pe suprafatacontrolului si se apasa un buton

System.MouseEventArgs

MouseWheel miscarea rotitei de scroll a mouse-uluiatunci cand controlul are focus-ul

System.MouseEventArgs

MouseUp mouse-ul se afla pe suprafatacontrolului si se elibereaza un buton

System.MouseEventArgs

MouseLeave mouse-ul paraseste suprafatacontrolului

System.EventArgs

MouseEnter, MouseHover si MouseLeave semnaleaza faptul ca mouse-ul se afla inregiunea unui control, transmitand putine informatii event handler-elor. MouseMove,MouseDown, MouseWheel si MouseUp, din contra, pot fi folosite pentru a implementainteractiuni substantiale intre utilizator si interfata. Un obiect de tip MouseEventArgscontine informatii despre starea si locatia mouse-ului.

Tabel - proprietati MouseEventArgs

Proprietate Descriere

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 47 of 203

Page 48: Aplicatii in Visual.net

Button specifica daca s-a apasat un buton al mouse-ului

Clicks returneaza numarul de click-uri efectuate

Delta Returneaza numarul de actionari asupra rotitei mouse-ului;acesta poate fi pozitiv sau negativ - deplasare inainte sauinapoi; fiecare astfel de deplasare adauga sau scade 120din valoarea anterioara

x returneaza coordonta x a mouse-ului in momentul executieiunui click

y returneaza coordonta y a mouse-ului in momentul executieiunui click

Componente de tip Extender Provider

Furnizeaza proprietati aditionale controalelor.

Exemplu: ToolTipProvider. La adaugarea unei instante a unui ToolTipProvider pe oforma, fiecare control de pe forma capata o noua propritate - ToolTip on n, unde n estenumele ToolTipProvider-ului. La run-time, valoara acestei proprietati este afisata intr-ocasuta galbena atunci cand mouse-ul se afla deasupra controlului.

ToolTipProvider - specifica mesaje gen tips la run time

HelpProvider - specifica mesaje de help

ErrorProvider - specifica mesaje de eroare

Un ToolTipProvider detine metode denumite Getn si Setn, unde n este numeleproprietatii.

Exemple: GetToolTip si SetToolTip, care pot fi folosite dinamic in cod pentru a modificamesajele asociate controlului respectiv

(! la run time, aceste modificari nu pot fi facute prin intermediul controlului).

// preluarea ToolTip-ului asociat unui Button button1

string myToolTip;

myToolTip = toolTip1.GetToolTip(button1);

//setarea ToolTip-ului unui Button button1

toolTip1.SetToolTip(button1, "Click for help");

Sinteza

Ordinea de primire a focus-ului poate fi setata folosind proprietatea TabIndex sauselectand Tab Order din meniul View si executand click pe controale in ordinea dorita.

Controale container:

- Panel

- GroupBox

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 48 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 49: Aplicatii in Visual.net

- TabPage

Proprietatile Dock si Anchor implementeaza redimensionarea automata controalelor peo forma.

Colectia de controale asociate unei forme permite adaugarea dinamica de controale larun time.

Adaugarea de noi controale la un ToolBox se face prin selectarea din lista controalelorinregistrate in sistem a controlului dorit sau prin selectarea fisierului .dll sau .exeasociat, din file system.

Event handlere - metode care trateaza evenimentele

Componente de tip Extender Provider - furnizeaza informatii aditionale pentrucontroalele de pe o forma.

4. Meniuri

Meniurile faciliteaza accesul la sectiuni importante din cadrul aplicatiei.

OBIECTIVE:

* Explicarea importantei meniurilor in cadrul interfetelor

* Crearea unui meniu folosind componenta MainMenu

* Crearea unui meniu contextual folosind componenta ContextMenu

* Activarea si dezactivarea unui menu item

* Crearea de shortcut-uri pentru un menu item

* Crearea unui check mark sau a unui buton radio pentru un menu item

* Explicarea procedurii prin care un menu item poate deveni invizibil

* Adaugarea dinamica a unui menu item la un meniu

* Clonarea dinamica a unui meniu

Meniurile permit utilizatorilor sa acceseze comenzi si functii intr-o maniera familiara,usor de inteles. In momentul proiectarii meniurilor, trebuie avut in vedere parcursullogic al aplicatiei, elementele componente ale meniului trebuie grupate in concordantacu o anumita functionalitate.

Crearea meniurilor folosind Design View

Se foloseste componenta MainMenu. Aceasta contine si gestioneaza o colectie decontroale MenuItem care reprezinta elementele vizuale ale unui meniu la run time.

Componenta MainMenu

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 49 of 203

Page 50: Aplicatii in Visual.net

* Crearea de noi meniuri si bare de meniu

* Adaugarea de menu items la meniuri existente

* Modificarea proprietatilor meniurilor si a elementelor meniurilor prin intermediulferestrei Properties

* Crearea de event handlere

La adaugarea unei optiuni intr-un meniu, designer-ul creaza o instanta a unui obiectMenuItem. Fiecare obiect MenuItem are proprietatile si membrii sai care pot fimodificati in fereastra Properties. Doua proprietati importante: Text - contine textulafisat la run time si Name - numele asociat instantei MenuItem, prin care se va facereferire in cod.

Crearea de meniuri la design time - se adauga o componenta MainMenu la forma

- se adauga elemente la meniu, folosind interfata grafica

Separarea elementelor din meniu

Un astfel de separator reprezinta o linie orizontala care delimiteaza anumite elementeale meniului, folosta de obicei pentru a face o separarea logica a functionalitatilor dincadrul unui meniu. Se realizeaza prin tastatea caracterului - in spatiul rezervat numeluielementului de meniu respectiv. Separatorul va constitui un element de meniu.

Taste de acces si taste de shortcut

Sunt utile pentru facilitarea accesului la optiuni din meniuri folosind tastatura.

Taste de acces

Permit utilizatorilor accesarea unui meniu prin apasarea unei combinatii de tasteformate din Alt si o litera. Atunci cand meniul este deschis, se poate selecta o anumitacomanda folosind combinatia de taste Alt + litera de acces corecta. Exemplu : Alt + Fdeschide meniul File.

Pentru a atribui o tasta de acces unui menu item:

1. se selecteaza in designer elementul de meniu dorit

2. se tasteata un ampersand in fata literei care va desemna accesul la optiunearespectiva

Taste de shortcut

Permit accesul instant la comenzi de meniu, furnizand un shortcut pentru comenzifrecvente din meniu. Combinatia de taste asociata unei comenzi poate fi formatadintr-o singura tasta, cum ar fi Delete, F2 sau Insert, sau din mai multe, de exempluCtrl+B, Ctrl+F3 sau Alt+Shift+S. In cazul in care proprietatea ShowShortcut a unuielement de meniu este setata la true si daca exista o combinatie de taste asociata,aceasta va fi afisata in dreapta elementului de meniu in cauza.

Pentru a asigna un shortcut:

- se seteaza proprietatea Shortcut la combinatia de taste dorita

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 50 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 51: Aplicatii in Visual.net

Evenimente asociate elementelor meniurilor

Metodele care trateaza evenimentele lansate de elementele meniurilor se creeazasimilar altor controale.

- Cel mai frecvent folosit eveniment este Click

- Evenimentul Select este lansat la vizualizarea unui meniu prin click sau folosindtastele de acces. Poate fi utilizat pentru crearea unui help privitor la modul de utilizarea unei anumite comenzi.

- Evenimentul Popup este lansat inainte ca un element al meniului sa fie afisat. Oaplicatie utila poate fi activarea sau dezactivarea anumitor elemente de meniu la runtime.

Meniuri contextuale

Un meniu contextual este vizualizat la apasarea butonului dreapta al mouse-ului peforma sau controlul caruia ii este asociat. Se creaza folosind componentaContextMenu. Se editeaza similar componentei MainMenu. Meniurile contextualegestioneaza o colectie de controale de tip menu-item, permite folosirea tastelorshortcut, dar nu se pot defini taste de acces. Pentru a asocia un meniu contextual uneiforme sau unui control, se seteaza proprietatea ContextMenu a formei sau controluluirespectiv la numele meniului contextual dorit.

! un meniu contextual poate fi asociat mai multor controale, insa un singur meniucontextual poate fi asociat unui control.

Modificarea meniurilor la run time

In functie de anumite conditii indeplinite la run time:

- se pot dezactiva anumite comenzi din meniu

- se pot afisa cate un check mark sau un buton radio in dreptul unui menu item pentrua furniza informatii utilizatorului

- se pot ascunde anumite elemente de meniu atunci cand utilizarea lor este inadecvata

- se pot adauga elemente in meniuri la run time sau pot fi clonate sau concatenate cualte elemente de meniu

Activarea sau dezactivarea comenzilor din meniuri

Se utilizeaza proprietatea Enabled.

Exemplu:

menuItem1.Enabled = false;

Afisarea casutelor de selectare (check marks)

Se utilizeaza proprietatea Checked.

Exemplu:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 51 of 203

Page 52: Aplicatii in Visual.net

menuItem1.Checked = true;

menuItem1.Checked = false;

Afisarea butoanelor radio

Se utilizeaza proprietatea RadioCheck.

! butoanele radio sunt folosite frecvent pentru afisarea unor optiuni exclusive

Ascunderea elementelor meniurilor

Se utilizeaza proprietatea Visible.

menuItem1.Visible = false;

!

Submeniurile continute de menu item-ul care devine invizibil vor deveni, de asemenea,invizibile si, deci, innaccesibile.

Clonarea meniurilor

Se refera la copierea unor elemente de meniu la run time. Clonare imseamnatransmiterea tuturor informatiilor posibile obiectului caruia i se asigneaza obiectulrezultat in urma acestei operatii.

Exemplu: clonarea meniului Edit (si a submeniurilor asociate) dintr-un main menupentru a servi drept meniu contextual unui control.

// fileMenuItem este un menu item existent,

// myButton este un Button

// declararea si instantierea unui meniu contextual

ContextMenu myContextMenu = new ContextMenu();

// se cloneaza fileMenuItem si se adauga meniului contextual

myContextMenu.MenuItems.Add(fileMenuItem.CloneMenu());

// se asigneaza noul meniu contextual butonului myButton

myButton.ContextMenu = myContextMenu;

Concatenarea meniurilor la run time

Pot fi concatenate mai multe meniuri de tip MainMenu cu meniuri contextuale, meniuricu menu items sau mai multe menu items.

Exemplu:

fileMenuItem.MergeMenu(myContextMenu);

Adaugarea de elemente de meniu la run-time

Exista posibilitatea adaugarii de noi elemente de meniu pe durata executiei aplicatiei.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 52 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 53: Aplicatii in Visual.net

De exemplu, intr-un meniu, pot fi adaugate item-uri care sa afiseze caile spre cele mairecente fisiere deschise de aplicatie. Aceste noi elemente de meniu nu vor avea eventhandlere asociate, dar poate fi specificata o metoda de tratare a evenimentului Click,ca argument al constructurului noului item. Aceasta metoda trebuie sa fie void si saaiba aceeasi signatura ca celelalte event handlere. Exemplu:

public void ClickHandler (object sender, System.EventArgs e)

{

// implementare...

}

Adaugarea dinamica a elementelor de meniu

Exemplu:

// ClickHandler este o metoda cu signatura

// corespunzatoare unui event handler

MenuItem myItem;

myItem = new MenuItem("Item 1", new EventHandler(ClickHandler));

//se adauga item-ul creat la un alt menu item

fileMenuItem.MenuItems.Add(myItem);

Sinteza

* meniurile permit accesul facil la comenzi din carul aplicatiei prin intermediul uneiinterfete usor de folosit

* meniurile contextuale permit accesul la anumite comenzi in situatii contextuale

* meniurile se pot modifica la run time in functie de anumite situatii

5. Validarea input-ului utilizatorilor

In multe aplicatii, utilizatorul introduce informatii necesare aplicatiei folosind interfatautilizator. Validarea datelor verifica faptul ca informatiile introduse respecta anumitiparametri impusi de aplicatie, inainte de lansarea in executie a programului. Deexemplu, ar putea exista un camp in care utilizatorul introduce un cod ca parte a uneiadrese. Folosind validarea, se poate verifica daca s-a introdus un anumit numar decaractere, si toate acestea sunt cifre, inainte de a continua. Validarea input-uluiutilizatorilor reduce sansa aparitiei unei erori logice sau de executie si confera aplicatieiun caracter mult mai robust.

OBIECTIVE:

* Explicarea diferentei dintre validarea form-level si field-level

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 53 of 203

Page 54: Aplicatii in Visual.net

* Directionarea focus-ului folosind metode si evenimente asociate controalelor

* Implementarea validarii form-level

* Implementarea validarii field-level

Validarea de tip form-level verifica datele dupa ce utilizatorul a completat toatecampurile de pe o forma. Folosind validare form-level, toate campurile de pe o forma arputea fi validate atunci cand utilizatorul a apasat butonul OK. Pe de alta parte,validarea field-level verifica daca datele introduse in fiecare camp respecta conditiispecifice. De exemplu, daca un utilizator completeaza un camp asociat unui numar detelefon, validarea field-level poate verifica daca numarul este valid, inainte de a avansala urmatorul camp. Odata cu tastarea unui caracter, anumite evenimente asociatecontrolului respectiv pot verifica daca s-au introdus numai cifre.

Validare field-level

Proprietati ale clasei TextBox

Controlul TextBox este controlul cel mai frecvent folosit pentru input-ul utilizatorilor. Oserie de proprietati ale acestui tip de control restrictioneaza valorile introduse lamultimea de valori acceptabile. Cele mai importante proprietati de acest fel sunt:

* MaxLength - limiteaza numarul de caractere care pot fi introduse

* PasswordChar - ascunde input-ul la run time

* ReadOnly - true sau false (permite sau nu editarea)

* MultiLine - true sau false (permite sau nun introducerea datelor pe mai multe linii)

Validare field-level - utilizarea evenimentelor

Controalele care pot primi input de la tastatura lanseaza urmatoarele evenimentespecifice:

* KeyDown

* KeyPress

* KeyUp

KeyDown si KeyUp

Evenimentele KeyDown si KeyUp survin la apasarea si, respectiv, eliberarea uneitaste. Controlul care detine focus-ul lanseaza evenimentul. La lansarea acestorevenimente, informatiile legate de tasta sau combinatia de taste care au fost apasatesau eliberate pot fi preluate folosind o instanta a clasei KeyEventArgs. Un eventhandler asociat evenimentelor KeyDown si KeyUp trebuie sa includa un parametru detip KeyEventArgs in signatura sa.

Proprietati KeyEventArgs

Proprietate Descriere

Alt specifica daca s-a apasat sau nu tasta Alt

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 54 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 55: Aplicatii in Visual.net

Control specifica daca s-a apasat sau nu tasta Ctrl

Handled returneaza o valoare indicand daca evenimentul a fost tratat

KeyCode returneaza un enum care specifica tasta apasata

KeyData intoarce informatii despre tasta care a fost apasata,verificand si daca s-a apasat Alt, Ctrl sau Shift

KeyValue returneaza o reprezentare sub forma de intreg a proprietatiiKeyData

Modifiers returneaza flag-uri care indica ce combinatie a tastelor Alt,Ctrl sau Shift s-a folosit

Shift specifica daca s-a apasat tasta Shift

Evenimentele KeyUp si KeyDown sunt cel mai frecvent utilizate pentru a determinadaca s-a apasat Alt, Ctrl sau Shift, prin intermediul proprietatilor instanteiKeyEventArgs transmisa ca parametru handler-ului. Proprietatile KeyEventArgs Alt,Control si Shift returneaza o valoare booleana care indica daca aceste taste suntapasate - true daca tasta corespunzatoare este apasata si false daca a fost eliberata.

Exemplu: se verifica daca tasta Alt este apasata

private void textBox1_KeyUp(object sender,

System.Windows.Forms.KeyEventArgs e)

{

if (e.Alt == true)

MessageBox.Show("Tasta ALT este inca apasata");

}

Proprietatea KeyEventArgs.KeyCode se poate utiliza pentru a examina tasta care alansat evenimentul. Returneaza o valoare Key care reprezinta tasta care a fost apasata(evenimentul KeyDown) sau eliberata (evenimentul KeyUp).

Exemplu:

afisarea intr-un MessageBox a reprezentarii sub forma de string a tastei care a fostapasate.

private void textBox1_KeyDown(object sender,

System.Windows.Forms.KeyEventArgs e)

{

MessageBox.Show(e.KeyCode.ToString());

}

KeyPress

Atunci cand utilizatorul apasa o tasta care are o valoare ASCII asociata, se lanseazaevenimentul KeyPress. Printre tastele care au o valoare ASCII asociata sunt incluse

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 55 of 203

Page 56: Aplicatii in Visual.net

caracterele alfabetice si numerice (a-z, A-Z, 0-9), precum si anumite taste speciale,cum ar fi Enter and Backspace. Daca o tasta sau o combinatie de taste nu genereazao valoare ASCII, apasarea lor nu va determina aparitia evenimentului KeyPress.Exemple de astfel de taste includ Ctrl, Alt si tastele functionale. La aparitia acestuieveniment, se trasmite handler-ului ca parametru o instanta a claseiKeyPressEventArgs. Aceasta instanta contine informatii despre tasta apasata care potfi folosite pentu validarea input-ului. Proprietatea KeyPressEventArgs.KeyChar continecaracterul ASCII reprezentat de combinatia de taste care a lansat evenimentul.KeyPressEventArgs.Handled este proprietatea care indica daca evenimentul a fosttratat.

Validarea caracterelor

Tipul Char contine mai multe metode statice utile pentru validarea caracterelorfurnizate de evenimentul KeyPress. Cele mai importante astfel de metode:

* Char.IsDigit

* Char.IsLetter

* Char.IsLetterOrDigit

* Char.IsPunctuation

* Char.IsLower

* Char.IsUpper

Exemplu:

utilizarea metodei Char.IsDigit pentru a testa daca s-a apasat o tasta numerica:

private void textBox1_KeyPress (object sender,

System.Windows.Forms.KeyPressEventArgs e)

{

if (Char.IsDigit(e.KeyChar) == true)

MessageBox.Show("Ai apasat o tasta numerica");

}

Tratarea focus-ului

Focus-ul reprezinta abilitatea unui obiect de a primi input prin intermediul mouse-uluisau tastaturii. Un singur control poate detine focus-ului la un moment dat. Acesta seafla pe forma activa a aplicatiei. Fiecare control implementeaza metoda Focus careseteaza focus-ul controlului care a apelat-o. Returneaza o valoare booleana careindica daca setarea focus-ului s-a executat cu succes sau nu. Proprietatea CanFocusreturneaza true in cazul in care controlul poate primi focus-ul si false in caz contrar.

if (textBox1.CanFocus == true)

textBox1.Focus();

Evenimentele referitoare la primirea sau pierderea focus-ului au loc in urmatoarea

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 56 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 57: Aplicatii in Visual.net

ordine:

1. Enter

2. GotFocus

3. Leave

4. Validating

5. Validated

6. LostFocus

Enter si Leave - controlul primeste si, respectiv, pierde focusul.

GotFocus si LostFocus - controlul obtine pentru prima oara focus-ul, respectiv,controlulpierde focus-ul.

Validating si Validated - cele mai utile evenimente pentru validarea field-level.

Validating si Validated

Validating - are loc inainte ca un control sa piarda focus-ul. ProprietateaCausesValidation a controlului care va primi focus-ul si a celui care trebuie validattrebuie setata la true pentru ca evenimentul sa poata fi lansat. Exemple de cazuri deutilizare: un event handler care testeaza daca input-ul respecta un anumit format,imposibilitatea parasirii unui control pana la introducerea unor informatii de un anumittip.

Validated - este lansat dupa ce controlul a fost validat cu succes. Poate fi folosit pentrua executa operatii bazate pe input-ul validat.

Exemplu:

event handler pentru evenimentul Validating

private void textBox1_Validating(object sender,

System.ComponentModel.CancelEventArgs e)

{

// verifica valoarea introdusa in textBox1

if (textBox1.Text == "")

// se reda focus-ul controlului

e.Cancel = true;

}

Validare form-level

Reprezinta procesul validarii simultane (in acelasi moment al executiei aplicatiei) atuturor campurilor de pe o forma. O procedura centralizatoare implementeaza validareaform-level si este apelata, de obicei, in momentul in care utilizatorul doreste sa treacala un nou pas al aplicatiei.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 57 of 203

Page 58: Aplicatii in Visual.net

Exemplu:

la apasarea unui buton, se verifica toate toate controalele de tip TextBox au fostcompletate si se transmite focus-ul primului TextBox care nu indeplineste aceastaconditie, in cazul in care exista un asemenea TextBox.

private void btnValidate_Click(object sender,

System.EventArgs e)

{

// parcurgerea iterativa a tuturor controalelor de pe forma

foreach (System.Windows.Forms.Control aControl in this.Controls)

{

// se verifica daca este un TextBox si

// daca contine stringul vid

if (aControl is System.Windows.Forms.TextBox)

{

if (aControl.Text == "")

// se transmite focus-ul primului control care

// indeplineste conditia de mai sus

aControl.Focus();

return;

}

}

}

Keyboard Handler pentru validare form-level

Reprezinta o tehnica mai sofisticata de validare form-level. Un keyboard handlercentralizat permite gestionarea input-ului din toate campurile de pe o forma. Sefolosesc evenimentele KeyPress, KeyDown si KeyUp.

! pentru ca o forma sa lanseze aceste evenimente, proprietatea KeyPreview formeitrebuie setata la valoarea true. In acest caz, forma lanseaza evenimente legate deapasarea tastelor inaintea controlului care detine focus-ul. Pentru a preveni executiaevent handler-ului asociat evenimentului KeyPress al unui control, se seteazaproprietatea KeyPressEventArgs.Handled la true:

private void Form1_KeyPress(object sender,

System.Windows.Forms.KeyPressEventArgs e)

{

//evita pasarea evenimentului event handler-ului

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 58 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 59: Aplicatii in Visual.net

//asociat controlului care detine focus-ul

e.Handled = true;

}

Feedback

La introducerea unui input invalid, utilizatorul trebuie alertat si trebuie sa i se ofereoportunitatea de a corecta eroarea.

Modalitati de atentionare:

- pentru erori simplu de intuit, este suficienta o notificare auditiva

- schimbarea proprietatilor BackColor sau ForeColor ale controlului la care a surveniteroarea

- utilizarea metodei MessageBox.Show, in diferite formate

Exemplu:

MessageBox.Show("Valoare invalida pentru acest control!");

Componenta ErrorProvider

Permite setarea unui mesaj de eroare pentru fiecare control de pe forma de fiecaredata cand se introduce un input invalid. Se afiseaza un icon de eroare in dreptulcontrolului, iar textul mesajului de eroare este afisat ca Tool Tip atunci cand mouse-uleste pozitionat deasupra controlului afectat.

Afisarea unui mesaj de eroare

Se utilizeaza metoda SetError a componentei ErrorProvider.

Exemplu:

// nameTextBox este o instanta a clasei TextBox,

// myErrorProvider este un ErrorProvider

myErrorProvider.SetError(nameTextBox,

"numele nu poate fi vid!");

Setarea mesajului de eroare la design-time se poate efectua prin setarea proprietatiiError on x asociata controlului, unde x este numele ErrorProvider-ului.

Alte proprietati ale componentei ErrorProvider:

- Icon - specifica icon-ul vizualizat in dreptul controlului

- BlinkStyle - determina daca icon-ul va clipi in momentul aparitiei unei erori

- BlinkRate - stabileste cat de repede va clipi icon-ul

Exemplu:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 59 of 203

Page 60: Aplicatii in Visual.net

private void passTextBox_Validating(object sender,

System.ComponentModel.CancelEventArgs e)

{

// validarea input-ului

if (passTextBox.Text == "")

// setarea mesajului de eroare

myErrorProvider.SetError(passTextBox, "Parola nu poate fivida!");

else

// nu se afiseaza nici un mesaj de eroare

myErrorProvider.SetError(pswordTextBox, "");

}

Sinteza

* Validare form-level vs. field-level

* Proprietati ale controlului TextBox control care restrictioneaza input-ul utilizatorului:

- MaxLength

- PasswordChar

- ReadOnly

- MultiLine

* Evenimente lansate de intercatiunea utilizatorului cu tastatura:

- KeyDown

- KeyUp

- KeyPress

* Metode statice ale clasei Char utile in validarea input-ului:

- Char.IsDigit

- Char.IsLetter

- Char.IsLetterOrDigit

- Char.IsPunctuation

- Char.IsLower

- Char.IsUpper

* Validating - principalul eveniment folosit pentru validare

* ErrorProvider - componenta utila pentru setarea mesajelor de eroare

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 60 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 61: Aplicatii in Visual.net

Section 5. Concepte POO in Visual Studio .NET - IV

1. Concepte generale POO

Programarea in .NET Framework este realizata cu ajutorul obiectelor. Obiectele suntconstructii programatice care reprezinta pachete de date cu functionalitate unitara.Obiectele furnizeaza mediului de dezvoltare de aplicatii o functionalitate specifica, faraa se detalia comportamentul intern al obiectului. Obiectele sunt create pe baza unuisablon, denumit clasa. Libraria de clase .NET furnizeaza un set de clase de la care sepot crea obiecte in cadrul aplicatiilor. Exista, desigur, posibilitatea crearii propriilor clasein Microsoft Visual Studio.

Obiecte, membri, abstractizare

Un obiect este o constructie programatica care reprezinta o anumita entitate in cadrulaplicatiei. In lumea reala, obiectele sunt computere, case, masini etc. Fiecare dintreaceste elemente au o anumita functionalitate si sunt caracterizate de o serie deproprietati specifice. Intr-o aplicatie, un obiect poate fi o forma, un control, o conexiunela o baza de date, si asa mai departe. Fiecare obiect reprezinta o unitate functionala,continand toate datele si functionalitatea necesare pentru a isi indeplini sarcinile incadrul aplicatiei. Abilitatea obiectelor programatice de a reprezenta obiecte din lumeareala este numita abstractizare.

Clasele - sabloane pentru obiecte

Clasele reprezinta tipuri referinta definite de utilizator. Clasele ar putea fi privite ca oamprenta pe care toate obiectele de acest tip o poarta: ele definesc toti membrii unuiobiect, comportamentul acestuia si seteaza valorile initiale ale datelor membre, dupacaz. La instantierea unei clase, se creaza o instanta a clasei respective in memorie.Aceasta instanta este denumita obiect. O clasa se instantiaza utilizand cuvantulrezervat new, dupa cum urmeaza:

// se declara o variabila de tip TipObiect

TipObiect un_obiect;

// instantiere si asignare

un_obiect = new TipObiect();

La instantierea unei clase, se creaza in memorie o copie a datelor care formeazainstanta si acestea sunt asignate, unitar, variabilei referinta. Instantele individuale aleunei clase sunt independente intre ele si reprezinta constructii programatice separate.In principiu, nu exista o limita a numarului de copii (instante) ale unei aceleasi clase laun moment dat. Prin analogie cu lumea reala, daca un computer reprezinta un obiect,atunci datele tehnice de fabricatie ar putea reprezenta sablonul (clasa), pornind de lacare se pot fabrica un numar practic nelimitat de computere. O modificare adusa unuiastfel de obiect nu afecteaza in vreun fel celelalte obiecte.

Obiecte si membri

Obiectele sunt compuse din membri. Membrii pot fi: proprietati, campuri, metode si

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 61 of 203

Page 62: Aplicatii in Visual.net

evenimente, reprezentand datele si functionalitatea care compun obiectul. Campurile siproprietatile reprezinta datele membre ale unui obiect. Metodele reprezinta actiuni carepot fi executate de obiect, iar evenimentele sunt notificari pe care un obiect le poatetrimite sau primi la (de la) alte obiecte in urma unor actiuni din cadrul aplicatiei.

Pentru a continua exemplul din lumea reala legat de un obiect de tip Computer, putemconsidera ca un obiect Computer are campuri si proprietati, cum ar fi Frecventa, Firma,Tip etc. Acestea sunt date care descriu starea obiectului. Un astfel de obiect poateavea mai multe metode, cum ar fi Restart, StandBy sau Shutdown. Aceste metodedetermina comportamentului obiectului, reprezentand actiuni care pot fi executate.Evenimentele reprezinta notificari. De exemplu, un Computer poate primi un evenimentExtraHeating din partea procesorului sau un eveniment StartShutDown atunci cand seapasa butonul de shutdown.

Modelarea obiectelor

Obiectele simple pot contine numai cateva proprietati, metode si, eventual, unul saudoua evenimente. Obiectele mai complexe pot necesita un numar mare de proprietatisi metode si pot, chiar, ingloba alte obiecte. Obiectele pot contine si expune alteobiecte ca membri. De exemplu, un control TextBox are o proprietate Font care constaintr-un obiect de tip Font. Similar, orice instanta a clasei Form contine si gestioneaza ocolectie Controls care include toate controalele de pe forma. Modelul unui obiectdefineste ierarhia obiectelor care formeaza structura obiectului modelat.

Modelul unui obiect este o organizare ierarhica a obiectelor subordonate continute deun obiect parinte.

Incapsulare

Incapsularea este conceptul prin care implementarea unui obiect este independenta deinterfata sa. Cu alte cuvinte, o aplicatie interactioneaza cu un obiect prin intermediulinterfetei sale, care consta in metodele si proprietatile sale publice. Cat timp aceastainterfata ramane neschimbata, applicatia poate continua interactiunea cu respectivacomponenta, chiar daca implementarea interfetei a fost complet rescrisa de la oversiune la alta.

Obiectele ar trebui sa interactioneze cu alte obiecte prin intermediul metodelor siproprietatilor publice. Deci, obiectele trebuie sa contina toate datele necesare, precumsi functionalitatea completa necesara manipularii acestor date. Datele interne ale unuiobiect nu trebuie expuse in interfata; deci, campurile nu trebuie declarate public.

Polimorfism

Polimorfismul reprezinta abilitatea unor clase diferite de a efectua implementari diferiteale aceleeasi interfete publice. Cu alte cuvinte, polimorfismul permite metodelor siproprietatilor unui obiect sa fie apelate fara a se tine cont de o implementare particularaa acelor membri. De exemplu, un obiect User poate interactiona cu un obiect Computerprin intermediul interfetei publice a obiectului Computer. Daca un alt obiect, cum ar fiServerStation, expune aceeasi interfata publica, obiectul User poate interactiona cuambele obiecte, fara a fi importanta implementarea specifica a interfetei. Exista douatipuri importante de polimorfism: polimorfism bazat pe interfete si polimorfism bazat pemostenire.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 62 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 63: Aplicatii in Visual.net

Polimorfism bazat pe interfete

O interfata este o structura comportamentala a unei clase. In principal, o interfatadefineste membrii pe care o clasa ar trebui sa-i implementeze, dar nu specifica detaliireferitoare la aceasta implementare. Un obiect poate implementa mai multe interfetediferite, si mai multe clase diferite pot implementa aceeasi interfata. Toate obiectelecare implementeaza aceeasi interfata sunt capabile sa interactioneza cu alte obiecteprin intermediul acestei interfete. De exemplu, un obiect WorkStation poate implementao interfata ICalculation, care specifica metodele BeginCalculation, ContinueCalculationsi StopCalculation. Alte clase, cum ar fi Pda sau Laptop pot implementa aceeasiinterfata, fiind, deci, capabile sa interactioneza cu un obiect User. Obiectul de tip Usernu stie cu care dintre implementarile interfetei interactioneaza; el foloseste pur sisimplu interfata.

Polimorfism bazat pe mostenire

Mostenirea permite incorporarea functionalitatii unor clase definite anterior intr-o nouaclasa si implementarea unor alti membri. Despre o clasa care mosteneste o alta clasaspunem ca este derivata din acea clasa, sau mosteneste clasa respectiva. O clasapoate fi derivata direct dintr-o singura clasa, numita clasa de baza. Clasa derivata areaceeasi membri ca si clasa de baza, adaugandu-se eventuali membri aditionali. Inplus, implementarea membrilor de baza poate fi modificata in noua clasasupraincarcand implementarea clasei de baza. Clasele derivate retin toatecaracteristicile clasei de baza si pot interactiona cu alte obiecte in aceeasi maniera cuobiectele de tipul clasei de baza.

Sinteza

Abstractizarea este reprezentarea obiectelor din lumea reala prin constructiiprogramatice. Obiectele programatice pot reprezenta obiecte din lumea reala prinimplementari ale membrilor lor.

Clasele sunt sabloane pentru obiecte. La crearea unui obiect, se creaza o copie aclasei in memorie, fiind initializate valorile variabilelor membre. O clasa se poatecomporta ca un numar, teoretic nelimitat, de obiecte distincte.

Incapsularea este un principiu al programarii orientate obiect. Un obiect ar trebui sacontina toate datele de care are nevoie si tot codul necesar manipularii acestor date.Datele specifice unui obiect nu trebuie sa fie disponibile altor obiecte. Numaiproprietatile si metodele ar trebui expuse in interfata.

Polimorfismul reprezinta abilitatea unor obiecte diferite de a expune implementaridiferite ale aceleasi interfete publice.

Polimorfism bazat pe interfete

O interfata defineste trasaturile comportamentale ale unei clase. Ea specifica caredintre membri trebuie implementati, dar nu specifica detalii legate de implementareaacestora. Un obiect poate implementa mai multe interfete diferite, si mai multe obiectediferite pot implementa aceeasi interfata.

Polimorfism bazat pe mostenire

Obiectele pot mosteni functionalitati de la alte obiecte. O clasa derivata retine toata

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 63 of 203

Page 64: Aplicatii in Visual.net

implementarea clasei de baza, iar instantele claselor derivate pot fi tratate ca instanteale clasei de baza. Clasele derivate pot implementa functionalitati aditionale.

2. Overloading

Supraincarcarea (overloading) permite crearea mai multor membri ai unei clase avandacelasi nume. Fiecare astfel de membru trebuie sa aiba o signatura diferita.Supraincarcarea este cel mai frecvent folosita pentru metode, dar C# permite sisupraincarcarea operatorilor.

Sa consideram situatia crearii unei metode care poate avea diversi parametri. Saconsideram urmatorul exemplu:

public void Afisare(int valoare)

{

// Implementare...

}

Sa presupunem ca utilizatorul doreste modificarea numarului si/sau tipurilorparametrilor. Solutia acestei probleme este data de supraincarcare. Acesta implicadefinirea mai multor functii cu acelasi nume. Metodele supraincarcate trebuie sa aibaacelasi nume, dar acest lucru nu se respecta pentru tipul returnat sau pentrumodificatorii de acces asociati. La apelul unei metode supraincarcate, commonlanguage runtime examineaza tipurile argumentelor transmise la apelul metodei. Secauta apoi o potrivire a listei argumentelor printre signaturile metodei supraincarcate sise face apelul corespunzator. Daca nu se gaseste o astfel de potrivire, se genereaza oeroare.

Metodele sunt membrii cel mai frecvent folositi pentru supraincarcare. C# permitesupraincarcarea operatorilor, oferind astfel functionalitati ale operatorilor pentru tipuriledefinite de utilizator.

Supraincarcarea metodelor

Se poate crea o metoda supraincarcate similar crearii unei metode oarecare: prindeclararea unei metode cu un nume, un nivel de acces, returnand un anumit tip sispecificand o lista de argumente. O metoda supraincarcata trebuie sa aiba acelasinume ca si o alta metoda existent, dar trebuie sa aiba o signatura diferita. Nivelul deacces si tipul returnat pot fi identice sau diferite.

Exemplu:

// metoda supraincarcata

public void Afisare(int i)

{

MessageBox.Show(i.ToString());

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 64 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 65: Aplicatii in Visual.net

}

// metoda cu acelasi nume, dar signatura diferita

public void afisare(string s)

{

MessageBox.Show(s);

}

Supraincarcarea operatorilor in C#

In aplicatii care utilizeaza tipuri definite de utilizator, se impune frecvent necesitateadefinirii unui set de operatii aritmetice, logice sau a unor operatori de comparare careutilizeaza aceste tipuri de date. Exemplu:

public struct PrezenteLab

{

int nrPrez;

int nrPrezExtra;

}

Acesta structura poate fi utilizata pentru a gestiona evidenta situatiei prezentelor la unlaborator de informatica. Pentru o utilizare facila si eficienta, apare necesitateasupraincarcarii operatorilor.

Sintaxa generala a supraincarcarii unui operator este urmatoarea:

public static tip operator op (argument1[, argument2])

{

//implementare...

}

Componenta tip din cadrul sintaxei reprezinta tipul returnat de operator. argument1,argument2 etc. reprezinta argumentele asociate operatorului. Pentru un operator unar,vom avea un singur argument, si trebuie sa aiba acelasi tip ca tipul returnat. Pentru unoperator binar, vom avea doua argumente, dintre care cel putin unul trebuie sa aibaacelasi tip ca tipul retunat. op reprezinta insusi operatorul, de exemplu +, -, >, !=, si asamai departe. Un operator supraincarcat trebuie sa fie public, pentru a putea fi accesat.Un operator supraincarcat trebuie sa fie, de asemenea, static. Definitia unui operatorsupraincarcat trebuie sa apara in cadrul definitiei tipului asupra caruia i se aplicaoperatorul. Sintaxa supraincarcarii operatorilor este similara pentru structuri si clase.Exemplu: supraincarcarea operatorului + pentru structura definita anterior.

public struct PrezenteLab

{

int nrPrez;

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 65 of 203

Page 66: Aplicatii in Visual.net

int nrPrezExtra;

// supraincarcarea operatorului +

public static PrezenteLab operator + (PrezenteLab a,

PrezenteLab b)

{

PrezenteLab rezultat = new PrezenteLab();

rezultat.nrPrez = a.nrPrez + b.nrPrez;

rezultat.nrPrezExtra = a.nrPrezExtra + b.nrPrezExtra;

return rezultat;

}

}

Utilizarea operatorului supraincarcat in cod:

// Saptamana2, Saptamana3 sunt instante

// ale structurii PrezenteLab

PrezenteLab total = new PrezenteLab();

total = Saptamana2 + Saptamana3;

Pornind de la ideea generala de supraincarcare, putem defini mai multe signaturipentru a suprincarca un acelasi operator. Exemplu:

public struct PrezenteLab

{

int nrPrez;

int nrPrezExtra;

// operatorul + supraincarcat anterior

public static PrezenteLab operator + (PrezenteLab a,

PrezenteLab b)

{

PrezenteLab rezultat = new PrezenteLab();

rezultat.nrPrez = a.nrPrez + b.nrPrez;

rezultat.nrPrezExtra = a.nrPrezExtra + b.nrPrezExtra;

return rezultat;

}

// supraincarcare aditionala (o alta signatura,

// o alta functionalitate)

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 66 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 67: Aplicatii in Visual.net

public static PrezenteLab operator + (PrezenteLab a, int b)

{

PrezenteLab rezultat = new PrezenteLab();

rezultat.nrPrez = a.nrPrez + b;

return rezultat;

}

}

Sinteza

- Supraincarcarea permite crearea de metode multiple avand acelasi nume, insa cuimplementari diferite. Metodele supraincarcate trebuie sa difere prin signatura dar potreturna acelasi tip de date sau pot avea aceeasi modificatori de acces asociati.Declararea unei metode supraincarcate este similara definirii oricarei alte metode.

- C# permite supraincarcarea operatorilor. Operatori supraincarcati trebuie sa fie publicisi statici. Pentru a declara un operator supraincarcat se utlizeaza cuvantul rezervatoperator.

3. Polimorfism

Polimorfism bazat pe interfete

Interfetele permit definirea comportamentelor obiectelor. Clase diferite pot implementaaceeasi interfata si pot, deci, interactiona cu alte obiecte intr-o maniera polimorfica.

O interfata actioneaza ca un sablon. Orice obiect care implementeaza o anumitainterfata garanteaza implementarea membrilor definiti in acea interfata. Daca un obiectnecesita interactiune cu o interfata specifica, orice obiect care implementeaza interfatapoate raspunde acestei interactiuni.

O interfata defineste numai membrii care vor deveni disponibili prin implementarea unuiobiect. Definitia unei interfete nu implica aspecte legate de implementarea membrilor,specificandu-se, in schimb, lista parametrilor si tipul returnat. Sarcina implementariiunei interfete revine, in totalitate, clasei care utilizeaza interfata.

Ca urmare, este posibila, pentru obiecte diferite, scrierea de implementari total diferiteale acelorasi membri. Sa consideram, de exemplu, o interfata IForma, care defineste ometoda CalculArie. O clasa Cerc care implementeaza aceasta interfata va calcula ariaintr-un mod diferit fata de o clasa Patrat care implementeaza aceeasi interfata.

Definirea interfetelor

Interfetele se definesc folosind cuvantul rezervat interface. De exemplu:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 67 of 203

Page 68: Aplicatii in Visual.net

public interface ICalculate

{

...

}

Acesta declaratie defineste interfata ICalculate, dar nu defineste nici un membru.Metodele membre trebuie definite specificand signatura, dar fara modificatori de acces.Modificatorul de acces asociat interfetei determina modificatorul de acces al fiecaruimembru al interfetei. Deci, in cadrul unei interfete publice, toti membrii vor fi publici.Exemplul urmator demonstreaza cum se pot adauga metode unei interfete:

public interface ICalculate

{

bool CheckInput(int input);

void StartCalculation();

int GetResult();

}

O interfata poate contine definitii de proprietati. Definitia unei proprietati trebuie saincluda getter-i, setter-i, sau ambele, precum si specificarea tipului returnat deproprietate. Exemplu:

public interface ICalculate

{

// alti membri...

string CalcType

{

get;

// eventual, urmeaza set...

}

}

!

In cadrul interfetelor nu se pot defini campuri! Aceasta restrictie blocheaza accesulclaselor care interactioneaza cu interfata la datele interne ale unui obiect.

Interfetele pot defini evenimente. Evenimentele definite in cadrul interfetelor reprezintaevenimente lansate de obiecte care implementeaza interfata. Desi orice clasa careimplementeaza o interfata trebuie sa furnizeze o implementare pentru toateevenimentele membre, obiectele care interactioneaza prin intermediul acestei interfetenu sunt obligate sa trateze evenimentele lansate. In C#, trebuie desemnat explicit tipuldelegatului asociat evenimentului. Exemplu de definire a unui eveniment membru al

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 68 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 69: Aplicatii in Visual.net

unei interfete:

public interface ICalculate

{

// alti membri...

event System.EventHandler OutOfMemory;

}

Definirea unei interfete

Se declara interfata folosind cuvantul rezervat interface. In cadrul definitiei interfetei, sedefinesc signaturile metodelor, proprietatilor si evenimentelor membre ale interetei.

Polimorfism bazat pe interfete

Orice obiect care implementeaza o anumita interfata poate interactiona cu un alt obiectcare solicita acea interfata. Sa consideram, drept exemplu, urmatoarea metoda:

public void CalculateSomething(ICalculate ic)

{

// implementare...

}

Aceasta metoda necesita o implementare a interfetei ICalculate. Orice obiect careimplementeaza aceasta interfata poate fi transmis ca parametru acestei metode.Obiectul va fi implicit convertit la interfata corespunzatoare. Cand un obiectinteractioneaza prin intermediul interfetei sale, numai membrii interfetei sunt accesibili.

Se poate executa, de asemenea, o conversie explicita a obiectelor careimplementeaza interfete specifice. Exemplu - conversia unui obiect WorkStation lainterfata ICalculate (obiectul ws trebuie sa implementeze ICalculate):

WorkStation ws = new WorkStation();

ICalculate calculateTool;

// converteste ws la interfata ICalculate

calculateTool = (ICalculate)ws;

Implementarea interfetelor

In C#, se utilizeaza caracterul : pentru a specifica o clasa sau o structura careimplementeaza o anumita interfata. Urmatorul exemplu indica faptul ca o clasaimplemeneaza o anumita interfata:

public class WorkStation : ICalculate

{

// cod aditional...

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 69 of 203

Page 70: Aplicatii in Visual.net

}

Clasele pot implementa mai multe interfete. Exemplu:

public class WorkStation : ICalculate, IMovieViewer,IInternetExplorer

{

// cod aditional....

}

Atunci cand o clasa sau o structura implementeaza o interfata, trebuie scriseimplementari separate pentru fiecare membru al interfetei. Daca se implementeaza maimulte interfete, trebuie furnizate implementari pentru fiecare membru al fiecareiinterfete.

Implementarea membrilor interfetelor in C#

In C#, implementarea unui membru al interfetei in cadrul clasei sau structurii serealizarea prin definirea unui membru care are acelasi nume cu membrul definit incadrul interfetei. Acest membru trebuie sa aiba acelasi modificator de acces ca incadrul interfetei. Exemplu:

public interface ICalculate

{

void BeginCalculation(int input);

}

public class WorkStation : ICalculate

{

public void BeginCalculation(int i)

{

// implementare...

}

}

In cazul unei astfel de implementari a membrilor unei interfete, ei sunt disponibili atatinterfetei, cat si clasei insesi. Deci, acesti membri pot fi accesati daca obiectul esteconvertit la propria sa clasa sau la interfata implementata.

Este, de asemenea, posibila implementarea explicita a interfetei si blocarea accesuluila membrii sai pentru clasa care implementeaza interfata. Un membru astfelimplementat poate fi accesat numai cand obiectul parinte este convertit la interfata pecare o implementeaza (si care contine membrul respectiv). Implementarea explicita aunui membru al unei interfete se realizeaza prin specificarea completa a numeluiinterfetei si a membrului. Exemplu:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 70 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 71: Aplicatii in Visual.net

public class WorkStation : ICalculate

{

void ICalculate.Begin Calculation(int input)

{

// implementare...

}

}

!

Membrul definit explicit din exemplul anterior nu are modificator de acces asociat.Deoarece s-a efectuat o implementare explicita a unui membru al interfetei, acesta vaavea acelasi nivel de acces ca si membrul definit de interfata.

Sinteza

O interfata descrie comportamentul obiectelor. Ele definesc membrii care vor fiaccesibili prin intermediul interfetei, si parametrii si tipul returnat de acesti membri.Orice obiect care implementeaza o interfata poate interactiona cu orice obiect caresolicita interfata respectiva. Atat clasele, cat si structurile pot implementa una sau maimulte interfete.

Implementarea membrilor unei interfete este realizata de clasele sau structurile careimplementeaza interfata.

In C#, pentru a specifica faptul ca o clasa sau structura implementeaza o interfata, seutilizeaza : (doua puncte). Daca o clasa sau structura implementeaza o interfata,aceasta trebuie sa implementeze fiecare membru definit in cadrul interfetei.

In C#, exista doua modalitati de a implementa membrii unei interfete:

- implementand un membru cu acelasi nume, signatura, si nivel de access ca simembrul definit in interfata. Acest membru va fi disponibil atat clasei care ilimplementeaza, cat si interfetei.

- implementand explicit membrul interfetei, utilizand calificarea completa a numeluimembrului. Un membru implementat in aceasta maniera va fi disponibil numai interfeteidin care face parte.

Polimorfism bazat pe mostenire

Mostenirea (derivarea) permite declararea unei noi clase care retine toti membrii sifunctionalitatea unei clase definite anterior. Aceast mecanism permite crearea de clasecare implementeaza functionalitati comune, de baza si apoi scrierea de subclasespecializate care introduc functiuni diferite, dar strans legate de cele ale clasei de baza.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 71 of 203

Page 72: Aplicatii in Visual.net

Mostenirea

Mostenirea permite crearea mai multor clase distincte, dar care au in comun o anumitafunctionalitate. Clasele specializate, denumite clase derivate, mostenesc o clasacomuna, numita clasa de baza. Clasa de baza incapsuleaza functionalitatea comunacare va fi prezenta in fiecare clasa derivata, in timp ce clasele derivate implementeazafunctionalitati specifice. De exemplu, sa consideram o clasa Laptop. Aceasta clasaimplementeza toata functionalitatea specifica unei clase Computer. In plus ea poateimplementa diverse metode specifice, cu ar fi StandByMode, apelata, de exemplu, lainchiderea capacului laptop-ului.

Comportamente polimorfice in clasele derivate

Clasele derivate sunt, in general, intr-o relatie de tipul is-a fata de clasa de baza. Deexemplu, un Laptop este un (is-a ) Computer, iar un Computer este un Dispositif. Oriceinstanta a unei clase derivate se poate comporta polimorfic ca o instanta a clasei debaza. Deci, daca o metoda necesita un parametru de tip Computer, i se poate furnizain schimb un obiect Laptop. Orice clasa derivata poate fi convertita implicit la clasa sade baza. In momentul conversiei catre clasa de baza, fiecare membru implementat declasa derivata va deveni inaccesibil; numai membrii clasei de baza vor fi disponibili.

Crearea claselor derivate

Se utilizeaza : (doua puncte). Exemplu:

public class Laptop : Computer

{

// implementare...

}

Clasele pot mosteni o singura clasa de baza, dar pot implementa una sau mai multeinterfete. Daca o clasa implementeaza mai multe interfete, odata cu derivarea dintr-oclasa de baza, numele interfetelor trebuie enumerate dupa : (doua puncte), despartiteprin virgula. De exemplu:

public class Laptop : Computer,

ICalculate, IFileManager

{

// implementare...

}

Odata ce o clasa derivata a fost declarata, se pot implementa membrii aditionali pentrua adauga functionalitati specifice clasei.

Crearea de clase care nu pot fi derivate

Uneori, este necesara definirea unor clase care nu vor putea fi mostenite. De exemplu,o clasa specializata care va fi utilizata pentru scrierea unor componente si nu va fi utilaaltor programatori, se defineste in asa fel incat sa nu poate fi mostenita. In C#, pentru arealiza acest lucru, se utilizeaza cuvantul rezervat sealed:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 72 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 73: Aplicatii in Visual.net

public sealed class ClassNotInheritable

{

// implementare...

}

Membri mosteniti

La crearea unei clase derivate, noua clasa poseda toata functionalitatea implementatain clasa de baza. Pe langa adaugarea de noi membri, se poate modifica siimplementarea membrilor mosteniti, pentru anumite scopuri. Suprascrierea (overriding)membrilor din clasa de baza se realizeaza printr-o noua implementare a unui membruexistent, implementat in clasa de baza. C# permite ascunderea membrilor clasei debaza, prin implementarea unui nou membru, in clasa derivata, cu acelasi nume sisignatura, dar avand diverse alte caracteristici.

Suprascrierea membrilor din clasa de baza

La derivarea dintr-o clasa de baza, se poate furniza o implementare diferita pentrumembrii clasei de baza prin suprascrierea lor folosind o noua implementare in clasaderivata a unui membru cu acelasi nume. De exemplu, o clasa Computer are o metodaHibernate. Daca derivam o clasa Laptop din clasa Computer, se poate furniza oimplementare diferita pentru metoda Hibernate.

!

Pot fi suprascrise numai proprietatile si metodele din cadrul unei clase de baza.Variabilele si evenimentele membre nu pot fi suprascrise.

Pentru a declara o noua implementare a unui membru dintr-o clasa intr-o clasaderivata, se utilizeaza cuvantul rezervat override. Noua implementare trebuie sa aiba osignatura si tip returnat identice cu cele ale membrului suprascris, si trebuie sa aibaasociat acelasi nivel de acces. De exemplu:

// Calculate este o metoda a clasei Computer

public class Laptop : Computer

{

public override void Calculate(int input)

{

// implementare....

}

}

La suprascrierea unui membru, noul membru va fi apelat in locul membrului din clasade baza. Aceasta afirmatie este dependenta de contextul in care este apelat unmembru. De exemplu, daca o instanta a unei clase derivate este convertita la clasa sade baza si este apelata o metoda membra suprascrisa, se va executa nouaimplementare, desi variabila este de tipul clasei de baza. Tipul obiectului, si nuvariabila, determina care membru va fi apelat.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 73 of 203

Page 74: Aplicatii in Visual.net

Pentru a suprascrie un membru al unei clase de baza, acesta trebuie declarat virtual.Membrii non-virtuali sunt nu pot fi suprascrisi. Exemplu de declarare a unei metodevirtuale:

public virtual void OverridableMethod()

{

// implementare...

}

Ascunderea membrilor clasei de baza

Un membru al clasei de baza poate fi ascuns prin inlocuirea sa cu o implementarecomplet noua. Mecanismul este cunoscut sub numele de ascundere (hiding). Laascunderea unui membru, se inlocuieste implementarea din clasa de baza cu o nouaimplementare. Noua implementare trebuie sa aiba aceeasi signatura ca a membruluiascuns si trebuie sa fie asociata unui membru de acelasi tip, dar poate avea nivel deacces, tip returnat diferite, si o implementare complet diferita. Orice metoda care areacelasi nume ca o metoda existenta, dar o signatura diferita, este tratata ca osupraincarcare a metodei initiale si nu se va realiza ascunderea. Pentru a ascunde unmembru al unei clase de baza se defineste un membru in clasa de baza avand aceeasisignatura si folosind cuvantul rezervat new:

// clasa de baza

public class ClasaDeBaza

{

public string metoda(int i)

{

// implementare...

}

}

// clasa derivata

public class ClasaDerivata : ClasaDeBaza

{

// ascunderea metodei din clasa de baza

// signatura identica, insa nivel de acces diferit,

// tip returnat diferit

internal new int metoda(int i)

{

// implementare...

}

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 74 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 75: Aplicatii in Visual.net

}

Mentinerea compatibilitatii cu membrii ascunsi

La ascunderea unui membru al unei clase, se ascunde implementarea din clasa debaza si se creaza o noua implementare care nu trebuie sa aiba caracteristicileimplementarii membrului din clasa de baza. Acest aspect poate conduce la implicatiinedorite in ceea ce priveste interoperarea cu alte obiecte. Daca un obiect apeleazametoda din exemplul anterior, in ideea de a obtine un String, la returnarea unui int, decatre metoda care ascunde metoda initiala, se poate genera o eroare. Ascundereamembrilor trebuie facuta deci cu atentie.

Desi ascunsa, implementarea membrilor din clasa de baza poate fi accesibila subanumite circumstante. Aceasta depinde de clasa, si nu de tipul obiectului, ca in cazulmembrilor suprascrisi. De exemplu, sa consideram urmatorul fragment de cod:

// folosim clasele din exemplul anterior

ClasaDerivata X = new ClasaDerivata();

ClasaDeBaza Y;

// X si Y refera acelasi obiect, dar

// variabilele au tipuri diferite

Y = X;

// se apeleaza noul membru

X.metoda(23);

// se apeleaza metoda originala

Y.metoda(23);

Deci, tipul variabilei determina daca se va apela membrul din clasa derivata saumembrul original (ascuns). Ca urmare, se poate modifica implementarea unui membrufara a se distruge abilitatea unei clase de a se comporta polimorfic.

Accesarea membrilor clasei de baza

La suprascrierea sau ascunderea unor membri, poate aparea necesitatea accesariiimplementarii acestor astfel de membri din clasa de baza. Pentru aceasta, se utilizeazacuvantul rezervat base. Se face astfel o referinta la implementarea clasei de baza si sepermite invocarea membrilor implementati in clasa de baza. Exemplu:

// apelul unei metode din clasa de baza

// dintr-o metoda care suprascrie metoda respectiva

public override string metoda(int i)

{

base.metoda(i);

// implementare...

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 75 of 203

Page 76: Aplicatii in Visual.net

}

Membri protected

• membri public - accesibili din orice sectiune a aplicatiei, incluzand clase externe

• membri internal - accesibili membrilor assembly-ului local, dar nu si apelantilorexterni

• membri private - disponibili numai in interiorul clasei

• membri protected si protected internal - discutati in cele ce urmeaza

Un membru definit protected are aceeasi vizibilitate fata de apelantii externi ca simembrii private. Diferenta consta in faptul ca membrii protected pot fi accesati dinclasele derivate. Exemplu:

// o metoda private si o metoda protected

// in clasa de baza

public class BaseClass

{

// o metoda private nu poate fi apelata

// din clase derivate

private void private_method()

{

// implementare....

}

// un membru protected poate fi

// apelat din clase derivate

protected void protected_method()

{

// implementare...

}

}

// clasa derivata

public class InheritedClass : BaseClass

{

public void Demo()

{

// apel legal, metoda protected

this.protected_method();

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 76 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 77: Aplicatii in Visual.net

// apel nepermis, metoda private

this.private_method();

}

}

Membri protected internal

Acest modificator de acces este reuniunea modificatorilor de acces protected siinternal. Deci, un membru protected internal poate fi accesat de clasele din assemblysau de clasele care mostenesc clasa care contine membrul, desigur, pe langaposibilitatea accesarii membrului din interiorul clasei care il contine.

Clase si membri abstracti

La crearea de componente, poate surveni situatia crearii unei clase de baza carefurnizeaza o functionalitate invarianta dar lasa in seama claselor derivateimplementarea anumitor membri. Acest aspect este surprins cu ajutorul claselorabstracte, clase care trebuie mostenite.

Clasele abstracte sunt similare interfetelor, dar au multe caracteristici in comun cuclasele. O clasa abstracta nu poate fi instantiata; trebuie mai intai mostenita. Claseleabstracte pot furniza sau nu implementari ale unei clase. Precum interfetele, potspecifica membri care tebuie implementati in clasele derivate. Spre deosebire deinterfete, o clasa poate mosteni numai o clasa abstracta. Similar claselor uzuale,clasele abstracte pot implementa complet anumiti membri, dar pot specifica membricare trebuie implementati in clasele derivate.

Crearea claselor abstracte

O clasa se defineste ca fiind abstracta prin utilizarea cuvantului rezervat abstract. Deexemplu:

public abstract class AbstractClass

{

// implementare...

}

Membri abstracti

O clasa abstracta poate implementa orice membru. Membrii unei clase virtuale pot fideclarati virtual, caz in care clasele derivate pot crea implementari proprii alemembrilor, sau pot fi declarati non-virtual, avand deci o implementare fixa, comuna inclasele derivate.

Un membru abstract este similar unui membru al unei interfete. Se specifica numaitipul, nivelul de acces, parametrii si tipul returnat. Implementarea este sarcina claseiderivate.

Membrii abstracti se declara in clase abstracte. Declararea unui membru abstract intr-oclasa non-abstracta conduce la eroare.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 77 of 203

Page 78: Aplicatii in Visual.net

public abstract class Computer

{

public abstract void Calculate(int);

public abstract int GetResult();

public abstract string Info

{

get;

set;

}

}

!

In C#, trebuie specificati un getter si/sau un setter pentru o proprietate abstracta. Dacasunt specificate ambele, atunci trebuie implementate impreuna in clasa derivata.

Mostenirea unei clase abstracte

Clasa derivata dintr-o clasa abstracta trebuie sa implementeze fiecare membruabstract definit in clasa abstracta de baza. Implementarea se realizeaza prinmacanismul suprascrierii, la fel ca in cazul claselor uzuale. Exemplu (bazat peexemplul anterior):

public class MyComp : Computer

{

public override void Calculate(int input)

{

// implementare...

}

public override int GetResult()

{

// implementare...

}

public override string Info

{

get

{

// implementare obligatorie a

// getter-ului si a setter-ului

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 78 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 79: Aplicatii in Visual.net

}

set

{

// implementarea setter-ului

}

}

}

!

Se pot crea noi clase abstracte prin derivarea din alte clase abstracte. In acest caz,clasa abstracta derivata nu trebuie sa implementeze membrii abstracti definiti in clasade baza (acest lucru este, insa, permis).

Sinteza - cuvinte cheie

• mostenire (derivare)

• supraincarcare (overriding)

• ascundere (hiding)

• base

• protected, protected internal

• virtual

• abstract

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 79 of 203

Page 80: Aplicatii in Visual.net

Section 6. Testarea si debugging-ul aplicatiilor - V

1. Unelte de debugging

Erorile de programare sunt inevitabile. Chiar si programatorii cu experienta mare indomeniu comit frecvent erori (bug-uri) la scrierea de cod. Debugging-ul este procesullocalizarii si corectarii erorilor.

Tipuri de erori

Exista trei tipuri de erori care pot surveni pe durata de viata a unei aplicatii. Erorile desintaxa sunt determinate de scrierea de cod care nu poate fi inteles de catrecompilator. Erorile de tip run-time sunt erorile care au loc atunci cand se efectueaza ooperatie imposibil de tratat in context. Erorile logice sunt erorile care rezulta atuncicand programul se compileaza si se executa corect, dar returneaza un rezultatneasteptat.

Erori de sintaxa

O eroare de sintaxa are loc atunci cand compilatorul nu poate compila codul scris. Deexemplu, o eroare de sintaxa apare atunci cand cuvintele cheie sunt scrise incorect,cand lipsesc semne de punctuatie sau cand entitatile din program nu sunt binestructurate.

Exemplu:

public void EroareDeSintaxa() {

System.Windows.Forms.MessageBoxShow("Care este eroarea?");

Mai intai, lipsa unui punct intre MessageBox si Show creaza o comanda care nu poatefi inteleasa de compilator. Apoi, constructia prin care se specifica sfarsitul functieilipseste (acolada inchisa). Ambele erori vor crea o conditie pe care compilatorul nu opoate interpreta.

Erorile de sintaxa pot fi usor identificate odata cu scrierea codului (colorarea adecvataa portiunilor de cod). Erorile detectate vor aparea, de asemenea, in fereastra Task List,odata cu prima compilare efectuata.

Executand dublu clic pe o eroare din fereastra Task List, cursorul se va pozitiona pelinia de cod care a generat eroare. Frecvent, aceasta actiune furnizeaza suficienteinformatii pentru a corecta eroarea. Pentru mai multe informatii se tasteaza F1 pe codulde eroare selectat.

Erori la executie (run-time)

Erorile la executie apar in momentul in care aplicatia incearca sa efectueaze o operatienepermisa in context. Aceasta include operatii imposibil de tratat, cum ar fi impartireala zero, si operatii nepermise, ca in cazul exceptiilor legate de securitate. La aparitiaunei astfel de erori, se arunca o exceptie care descrie eroarea. Exceptiile sunt clase

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 80 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 81: Aplicatii in Visual.net

speciale care sunt utilizate pentru a comunica starile de eroare ale diferitelor sectiuniale aplicatiei. Se poate scrie cod care sa trateze exceptiile, astfel incat acestea sa nustopeze executia aplicatiei.

Erori logice

Erorile logice apar atunci cand aplicatia este compilata si executata corect, dar nu seobtin rezultatele scontate. Acestea pot fi considerate eroriele cel mai dificil de tratat,pentru ca, adesea, nu exista informatii aditionale care sa indice sursa erorii. Erorilogice pot surveni, de exemplu, din plasarea inadecvata a punctului zecimal. Deexemplu:

public float CalculNota(int punctajLab, int punctajExamen)

{

float nota;

nota = punctajLab * 0.3 + punctajExamen * 0.07;

return nota;

}

Modul break

Modul break permite intreruperea executiei programului si executia codului linie culinie. In mod break, se pot utiliza uneltele de debugging pentru a examina valorilevariabilelor si proprietatile aplicatiei. In Visual Studio .NET, se intra in mod Break subuna din urmatoarele circumstante:

• s-a selectat Step Into, Step Over sau Step Out din meniul Debug sau din toolbar.

• executia programului avanseaza la o linie care contine un breakpoint activ.

• se intalneste un Stop

• se arunca o exceptie netratata

Elementele meniului Debug

Optiune Descriere

Windows Deschide un submenu de ferestre de debugging.

Start/Continue F5 Se ruleaza aplicatia in mod Debug. Daca aplicatia este inmod Break, se continua executia programului.

Break AllCtrl+Alt+Break

Se intrerupe executia programului si se intra in mod Breakla linia curenta din program. Se poate folosi Continue pentrua continua executia.

Stop DebuggingShift+F5

Se opreste modul Debug si se intra in mod Design.

Detach All Se stopeaza toate procesele in care era implicatdebugger-ul. Acesta este inchis, insa nu se intrerupeexecutia programului.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 81 of 203

Page 82: Aplicatii in Visual.net

RestartCtrl+Shift+F5

Se finalizeaza si se restarteaza executia aplicatiei.

Apply CodeChanges

Optiune specifica programarii C/C++.

Processes Vizualizeaza fereastra Processes.

ExceptionsCtrl+Alt+E

Vizualizeaza fereastra Exceptions.

Step Into F11 Se executa urmatoarea linie de cod. Daca aceasta contineapelul unei metode, Step Into se opreste la inceputul aceleimetode.

Step Over F10 Se executa urmatoarea linie de cod. Daca aceasta contineapelul unei metode, Step Over executa metoda si seopreste la linia urmatoare a metodei curente.

Step OutShift+F11

Executa liniile ramase din metoda curenta si se opreste laurmatoarea linie executabila de cod din metoda apelanta.

QuickWatchCtrl+Alt+Q

Afiseaza fereastra QuickWatch.

New BreakpointCtrl+B

Afiseaza fereastra New Breakpoint.

Clear AllBreakpointsCtrl+Shift+F9

Elimina toate breakpoint-urile din aplicatie.

Disable AllBreakpoints

Dezactiveaza toate breakpoint-urile, fara a le eliminaefectiv.

Mai mult, anumite functii de debugging pot fi accesate prin clic dreapta pe un elementdin fereastra de cod si alegand o functie meniul pop-up respectiv. Tabelul urmatorsintetizeaza o parte din aceste functii.

Tabel: functii de debugging accesibile din meniuri pop-up accesibile din cadrul ferestreide cod.

Optiune Descriere

Insert Breakpoint Insereaza un breakpoint la linia selectata.

New Breakpoint Afiseaza fereastra New Breakpoint. Acest element esteidentic cu optiunea cu acelasi nume din meniul Debug.

Add Watch Adauga expresia specificata in fereastra Watch.

QuickWatch Afiseza fereastra QuickWatch. Identica cu optiunea cuacelasi nume din meniul Debug.

Show NextStatement

Indica urmatorul bloc de program care se va executa.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 82 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 83: Aplicatii in Visual.net

Run To Cursor Deplaseaza executia programului la linia selectata.

Set NextStatement

Desemneaza linia selectata drept urmatoarea linie de codcare se va executa. Aceasta trebuie sa fie in cadrulprocedurii curente.

Examinarea valorilor variabilelor

Valorile variabilelor din program pot fi examinate in mod Break mentinand mouse-ulpozitionat deasupra variabilei, in fereastra de cod. Valoarea curenta a variabilei va fiafisata intr-o casuta de tip pop-up. Aceasta tehnica furnizeaza o modalitate facila sirapida de a determina valoarea curenta a unei variabile. Pentru mai multe informatiireferitoare la starea unei variabile, se pot folosi ferestrele Watch, Autos sau Locals.

Breakpoints

Se pot desemna linii de cod sau conditii care vor determina aplicatia sa isi opreascaexecutia in debugger. Aceste entitati se numesc breakpoints. Se pot utiliza breakpointspentru a seta linii de cod sau conditii care vor opri executia program. Exista 4 tipuri debreakpoints:

Setarea unui breakpoint de tip funtie:

- prin clic stanga pe bara gri din stanga ferestrei de editare de cod, in dreptul linieidorite

- prin clic dreapta pe linia dorita si selectand Insert Breakpoint din fereastra pop-up

- meniul Debug - New Breakpoint

Fereastra Breakpoints permite gestionarea multimii de breakpoints din program intr-osingura fereastra.

Breakpoints - proprietati, conditii

Proprietatile unui breakpoint se pot vizualiza prin intermediul ferestrei Breakpoints - clicdreapta, Properties. Fereastra Properties a oricarui breakpoint are trei taburi asociate:Function, File si Address, fiecare dintre acestea fiind asociind breakpoint-ul la tipulrespectiv. Deci, chiar daca un breakpoint este asociat in fereastra de cod la un anumittip, el se exprima in fereastra Properties prin toate cele trei tipuri.

In plus, fereastra Breakpoint Properties contine doua butoane: butonul Conditions sibutonul Hit Count. Primul va vizualiza o fereastra care permite specificarea uneiexpresii care va activa breakpoint-ul numai daca expresia este evaluata la true saudaca expresia se modifica. Expresia poate fi orice expresie booleana care poate fievaluata la o valoare booleana. De exemplu, conditia poate fi setata la expresiabool_var == true, breakpoint-ul devenind activ numai daca variabila bool_var arevaloarea true.

O alta metoda este desemnarea unei variabile sau expresii care, atunci cand semodifica, va determina oprirea executiei programului. Expresia specificata trebuie safie o expresie valida.

Butonul Hit Count determina vizualizarea ferestrei Breakpoint Hit, in care se poate seta

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 83 of 203

Page 84: Aplicatii in Visual.net

ca breakpoint-ul sa intrerupa executia aplicatiei dupa ce a fost intalnit de un anumitnumar de ori, sau de un multiplu a unui numar predeterminat de ori sau de un numarde ori mai mare sau egal cu un numar predeterminat. De exemplu, daca se seteazaconditia hit count la un multiplu de 10, executia programului se va opri la fiecare azecea intalnire a breakpoint-ului.

!

Breakpoint-ul trebuie sa fie activ pentru a putea fi numarat.

Debugging Windows Sunt unelte de monitorizare a executiei programului. Unele,precum fereastra Output sau fereastra Command, sunt disponibile in mod Design.Altele, cum ar fi fereastra Locals, sunt vizibile numai pe durata debugging-ului.

• Fereastra Output

- vizualizeaza output-ul generat in urma compilarii si executiei aplicatiei. Output-ulinclude notificari legate de incarcarea assembly-urilor, precum si output generat deconstructii Debug si Trace.

• Ferestrele Locals, Autos si Watch

Permit monitorizarea starii variabilelor din program pe durata debugging-uluiaplicatiei. Mai mult, aceste ferestre permit editarea valorilor variabilelor. Sunt utilepentru testarea modului in care anumite proceduri raspund la diverse input-uri.

• Fereastra Locals

Cand programul ruleaza in mod Debug, fereastra Locals permite monitorizareavalorilor tuturor variabilelor din procedura curenta. Fereastra este structurata pe treicoloane: Name, Value si Type. Tipurile mai complexe sunt vizualizate intr-un treecare poate fi expandat pentru a vizualiza valorile membrilor. Pe parcursul executieiprogramului, continutul ferestrei se mosdifica, in functie de procedura curenta. Sepot modifica valorile tipurilor primitive prin editarea valorii variabilelor. Tipurilecomplexe, precum clase sau structuri nu pot fi modificate, incercarea de a atribuiunui obiect continutul unui alt obiect neputandu-se realiza.

• Fereastra Autos

Este o forma abreviata a ferestrei Locals, vizualizand numai variabilele din liniacurenta si din cea anterioara, in acelasi format si cu posibilitatea de editare avalorilor variabilelor.

• Fereastra Watch

Permite studierea evolutiei valorilor unor variabile specificate. Se poate efectua oevaluare rapida a unei variabile utilizand dialogul QuickWatch.

• Immediate Mode in fereastra Command

Este utilizat pentru executia procedurilor, evaluarea expresiilor sau modificareavalorilor variabilelor pe durata debugging-ului. Vizualizarea ferestrei: Meniul Debug -Windows - Immediate.

Afisarea valorii obtinute prin evaluarea unei expresii: folosind semnul intrebarii (?).Exemplu:

? X*Y (o astfel de linie nu se termina prin punct si virgula).

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 84 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 85: Aplicatii in Visual.net

? Label2.Text - afiseaza valoarea curenta a proprietatii Text a variabilei Label2.

• Alte ferestre

Tabelul urmator sintetizeaza alte ferestre disponibile din meniul Debug.

Tabel: alte ferestre disponibile din meniul Debug

Optiune Descriere

RunningDocuments

Lista documentelor incarcate in cadrul procesului careruleaza.

This Afiseaza datele membre ale obiectului asociat metodeicurente.

Call Stack Afiseaza numele functiilor din stiva de apeluri, tipulparametrilor si valorile parametrilor.

Threads Permite examinarea si controlul firelor de executie dinprogram.

Modules Listeaza modulele (fisiere DLL sau EXE) utilizate inprogram.

Memory Afiseaza valorile stocate in memorie. Utila pentruvizualizarea bufferelor si stringurilor de mari dimensiuni, saua altor date care nu pot afisate corespunzator in ferestreLocals, Autos sau Watch.

Disassembly Afiseaza cod assembly corespunzator instructiunilor createde catre compilator.

Registers Vizualizeaza continutul registrilor.

Sinteza

- tipuri de erori: de sintaxa, la executie si logice

- modul break - ferestre din meniul Debug

2. Clasele Debug si Trace

Clasele Debug si Trace permit generarea si afisarea (de obicei sub forma de log-uri) demesaje informative legate de anumite conditii specifice aplicatiei, fara a fi necesaraintreruperea executiei aplicatiei. Pentru aplicatii simple, frecvent utilizate, nu suntnecesare unelte de debuging complexe, mijloacele prezentate anterior fiind suficiente.Aplicatiile complexe ridica, insa, probleme. La aparitia unei erori logice, examinareavariabilelor din aplicatie, urmarind liniile programului, conduce rar la identificarea sirezolvarea erorii. Clasa Debug furnizeaza o modalitate de a crea si salva sub forma delog-uri mesaje informative despre conditiile din program, pe masura ce aplicatia seexecuta. Clasa Trace permite crearea unor instrumente de diagnostic care pun ladispozitie mesaje informative chiar dupa ce aplicatia a fost compilata.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 85 of 203

Page 86: Aplicatii in Visual.net

Cum functioneaza tracing-ul? Clasele Trace si Debug fac parte din spatiul de numeSystem.Diagnostics care contine metode statice care permit testarea anumitor conditiila run time si salvarea rezultatelor sub forma de log-uri. Output-ul generat de acestemetode este afisat in fereastra Output si poate fi vizualizat pe durata debugging-ului.Output-ul este transmis, de asemenea, colectiei Listeners. Aceasta colectie contine ungrup de clase care pot primi output de la clasele Trace si Debug. Trace si Debugpartajeaza aceeasi colectie Listeners si toti asculatatorii din colectie primesc input de laTrace si Debug. Exista mai multe tipuri de Listeners, incluzand ascultatori care scriu infisiere text si Trace Listeners care scriu in loguri de evenimente. Dupa executiaprogramului, se pot examina aceste fisiere pentru identificarea erorilor din aplicatie.Tracing-ul este, de asemenea, util in optimizarea programelor.

Clasele Trace si Debug sunt aproape identice. Clasa Debug este folosita, in principal infaza de dezvoltare, in timp ce Trace poate fi utilizata pentru testare si optimizare dupace o aplicatie a fost compilata si s-a generat o versiune release a aplicatiei.

Scrierea output-ului furnizat de clasele Trace si Debug

Metodele care realizeaza acest lucru sunt:

• Write - scrie text in colectia Listeners, neconditionat.

• WriteLine - similar, adaugand un enter la textul scris.

• WriteIf - se scrie text daca conditia booleana specificata are valoarea true.

• WriteLineIf - similar cu WriteLine, adaugandu-se un enter.

• Assert - se scrie un mesaj de asertiune catre colectia Listeners daca expresiabooleana specificata are valoarea false. Se afiseaza, de asemenea, un messagebox.

• Fail - creaza o asertiune care este considerata falsa, fara a se testa vreo conditie.Se scrie in colectia Listeners mesajul specificat de asertiune si se afiseaza, deasemenea, un message box.

Exemplu de apelare a acestor metode:

// metodele sunt statice,

nu este necesara declararea unor instante

Trace.Write("Mesaj Trace 1");

Trace.WriteLine("Mesaj Trace 2");

// se scrie text daca expresia este true

Debug.WriteIf(x==2, "x are valoarea 2");

Debug.WriteLineIf(x==3, "x este egal cu 3");

// se scrie output si se afiseaza un message box

// daca valoarea conditiei este false

Trace.Assert(x==5, "x nu este egal cu 5!");

// se scrie output si se afiseaza un message box, neconditionat

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 86 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 87: Aplicatii in Visual.net

Debug.Fail("Discul D nu mai este valid!");

Se poate modifica nivelul de indentare asociat mesajelor Trace atunci cand sunttransmise colectiei Listeners apeland metodele Indent si Unindent si setandproprietatile IndentSize si IndentLevel. Aceste metode si proprietati sunt utile pentrucrearea crearea si vizualizarea ierarhica a mesajelor de eroare. ProprietateaIndentSize seteaza si returneaza numarul de spatii pentru o indentare, iar IndentLevelseteaza si returneaza numarul de indentari aplicate. Metoda Indent incrementeazaIndentLevel cu o unitate, iar Unindent decrementeaza.

Exemplu:

// incrementare IndentLevel

Trace.Indent();

Colectia Listeners

Output-ul generat de clasele Trace si Debug este directionat catre colectia Listeners.Colectia Listeners organizeaza si expune clase capabile sa primeasca output-ulfurnizat de Trace. Fiecare membru al colectieiListeners primeste output de la claseleTrace si Output. Tratarea output-ului depinde de tipul ascultatorului. Colectia Listenerseste initializata cu un membru, o instanta a clasei DefaultTraceListener. Acestascultator este creat automat si va primi output-ul claselor Trace si Debug, chiar dacanu se ataseaza un alt ascultator. Output-ul primit de instanta DefaultTraceListener estedirectionat catre debugger. DefaultTraceListener-ul este responsabil de vizualizareaoutput-ului in fereastra Output. Daca se doreste salvarea mesajelor, in afara deafisarea lor in fereastra Output, trebuie adaugat cel putin un ascultator in plus. Clasespecializate pentru scrierea de log-uri: EventLogTraceListener siTextWriterTraceListener. Ambele clase sunt derivate din clasa abstracta TraceListener.

Crearea de log-uri sub forma de text

Clasa TextWriterTraceListener scrie output-ul primit ca text, fie catre un obiect de tipStream, fie catre un obiect TextWriter. De exemplu, Console.Out este un TextWriter.Deci, se poate crea un TextWriterTraceListener care isi afiseaza intreg output-ul laconsola. Stream si TextWriter scriu in fisiere text.

Mecanismul crearii de fisiere log este urmatorul:

- se creaza un fisier care va contine output-ul

- se creaza o instance a clasei TextWriterTraceListener, specificandu-se fisierulanterior creat

- se adauga instanta TextWriterTraceListener la colectia Listeners

Exemplu:

// se deschide fisierul log.txt

// (daca acesta nu exista, se creaza)

System.IO.FileStream firstLog = new

System.IO.FileStream("C:\\log.txt",

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 87 of 203

Page 88: Aplicatii in Visual.net

System.IO.FileMode.OpenOrCreate); // se creaza un TraceListenercare specifica

// firstLog drept fisier tinta

TextWriterTraceListener firstListener = new

TextWriterTraceListener(firstLog);

// se adauga firstListener la colectia Listeners

Trace.Listeners.Add(firstListener);

!

Daca fisierul specificat in constructorul clasei FileStream exista, deschiderea fisieruluifolosind IO.FileMode.OpenOrCreate va avea ca efect suprascrierea continutuluiexistent. Utilizand IO.FileMode.Append, noile informatii se vor adauga la sfarsitulfisierului. O alta supraincarcare a constructorului TextWriterTraceListener permitesimpla specificare a fisierului in care se va scrie. Folosind acest constructor, fisierul textva fi creat, daca nu exista sau, in caz contrar, noile informatii se vor adauga la sfarsit.Exemplu:

TextWriterTraceListener secondListener = new

TextWriterTraceListener("C:\\log.txt");

La executia codului oricaruia dintre aceste doua exemple, tot output-ul claselor Trace siDebug este scris in ascultatorul asociat. Pentru ca acest output sa fie scris efectiv infisier, trebuie apelata metods Flush a clasei Trace:

Trace.Flush();O alta posibilitate este setarea proprietatii Trace.AutoFlush la true, ca in exemplulurmator. Aceasta tehnica determina golirea bufferului dupa fiecare scriere:

Trace.AutoFlush = true;

Salvarea output-ului clasei Trace intr-un EventLog

EventLogTraceListener este clasa care permite salvarea output-ului clasei Traceintr-un obiect EventLog. Mecanismul este in mare parte similar scrierii intr-un fisier text.Se creaza un nou EventLog sau se specifica un log existent, se creaza un nouEventLogTraceListener si se adauga la colectia Listeners. Output-ul este salvat inEventLog ca obiecte EventLogEntry. Crearea unui nou event log si setarea numeluisub care va fi vizualizat:

EventLog firstLog = new EventLog("Debug Log");Se seteaza proprietatea Source pentru EventLog. Daca proprietatea Source nu estesetata, se va genera o eroare.

firstLog.Source = "Trace Output";In continuare, se creaza o instanta EventLogTraceWriter care specifica noul log catarget pentru output-ul Trace.

EventLogTraceListener logListener = new

EventLogTraceListenerfirstLog);

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 88 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 89: Aplicatii in Visual.net

Daca este necesar, se poate seta proprietatea Trace.AutoFlush la valoarea true, sause poate apela Trace.Flush dupa fiecare scriere.

Comutatoare Trace (Trace Switches)

De obicei, la debugging, se doreste primirea intregului output provenit din constructiicare utilizeaza Trace si Debug. Totusi, dupa ce o aplicatie a fost compilata si lansata,este de dorit activarea tracing-ului numai in anumite cazuri. Comutatoarele Trace suntcomutatoare configurabile utilizate pentru a vizualiza constructii Trace. Acestea pot ficonfigurate prin intermediul aplicatiei prin modificarea fisierului de configurare alaplicatiei dupa ce aceasta a fost compilata si distribuita.

Exista in .NET Framework doua tipuri de comutatoare Trace. Instantele claseiBooleanSwitch returneaza o valoare booleana. Deci, acestea sunt caracterizate prindoua stari: on sau off. Clasa TraceSwitch permite utilizatorilor sa seteze nivelulreprezentat de comutator, care poate fi o valoare intre 1 si 5, depinzand de tipul deoutput pe care utilizatorul doreste sa il primeasca.

Ambele comutatoare necesita doi parametri in constructor: un NumeDeVizualizare,care reprezinta numele comutatorului in cadrul interfetei utilizator si o Descriere, carecontine o scurta descriere a comutatorului. De exemplu:

BooleanSwitch firstBooleanSwitch = new BooleanSwitch("Switch1",

"Controls Data Tracing");

TraceSwitch firstTraceSwitch = new TraceSwitch("Switch2",

"Controls Forms Tracing");

Clasa TraceSwitch contine cinci setari care reprezinta diverse nivele de eroare. Acestesetari sunt expuse prin intermediul proprietatii TraceSwitch.Level. Proprietatea poate fisetata la una din cele cinci valori ale enumeratorului TraceLevel:

• TraceLevel.Off. Desemneaza un TraceSwitch inactiv. Valoare 0.

• TraceLevel.Error. Asociat cu mesaje de eroare scurte. Valoare 1.

• TraceLevel.Warning. Pentru mesaje de eroare si warning-uri. Valoare 2.

• TraceLevel.Info. Pentru mesaje de eroare, warning-uri si mesaje informative scurte.Valoare 3.

• TraceLevel.Verbose. Reprezinta mesaje de eroare, warning-uri si descrieri detaliateale executiei programului. Valoare asociata 4.

Mai mult, clasa TraceSwitch expune patru proprietati booleene read-only carereprezenta nivelele Trace:

• TraceSwitch.TraceError

• TraceSwitch.TraceWarning

• TraceSwitch.TraceInfo

• TraceSwitch.TraceVerbose

Aceste proprietati corespund nivelurilor Trace cu aceleasi nume. La setarea proprietatii

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 89 of 203

Page 90: Aplicatii in Visual.net

TraceSwitch.Level, are loc o setare automata a acestor patru proprietati la un nivelcorespunzator. De exemplu, daca TraceSwitch.Level este setat la TraceLevel.Info,TraceSwitch.TraceInfo va returna true. De asemenea, TraceSwitch.TraceError siTraceSwitch.TraceWarning vor returna true. Atunci cand in nivel este specificat, toatenivelurile inferioare vor returna true.

Exemplu:

// se presupune declararea anterioara

// a unui obiect BooleanSwitch,

// firstBooleanSwitch, si a unui obiect

// TraceSwitch, firstTraceSwitch

Trace.WriteIf(firstBooleanSwitch.Enabled == true, "Eroare");

Trace.WriteLineIf(firstTraceSwitch.TraceInfo == true,

"Incompatibilitate de tipuri");

Dupa cum se poate observa, utilizatorul trebuie sa creeze propriile conexiuni intreinstructiunile care folosesc metodele clasei Trace si valorile comutatorilor. Daca sefolosesc metodele Trace.Write si Trace.WriteLine, valorile comutatorilorvor fi ignorate.

Configurarea comutatoarelor

Comutatoarele Trace pot fi activate sau dezactivate dupa ce aplicatia a fost compilatasi distribuita. Configurarea manuala se poate realiza prin intermediul fisierului deconfigurare a aplicatiei (.config), un fisier XML care contine informatii despre aplicatie.Fisierul .config trebuie plasat in acelasi director cu executabilul aplicatiei si trebuie saaiba acelasi nume: nume_aplicatie.exe.config. Nu toate aplicatiile au un fisier .configfile, deci pentru a folosi comutatoare Trace, este necesara crearea unui fisier .config. Inmomentul in care aplicatia executa cod care creaza un comutator Trace, se verificafisierul .config pentru a extrage eventualele informatii in legatura ce acel comutator.Fisierul este examinat cate o data pentru fiecare comutator. Orice modificare dinfisierul de configurare legata de un anumit comutator necesita oprirea si apoirestartarea aplicatiei (fara o noua compilare!).

La crearea unui comutator, unul dintre parametrii este NumeleDeVizualizare. Acestaeste numele folosit pentru a configura comutatorul Trace in fisierul .config. La editareafisierului .config, trebuie specificat nu numai numele comutatorului, ci si valoarea lacare este setat. Valoarea trebuie sa fie intreaga. Pentru instante BooleanSwitch, zeroreprezinta off, iar o valoare nenula reprezinta on. Pentru obiecte TraceSwitch, valorilezero, unu, doi, trei si patru corespund, respectiv, cu TraceLevel.Off, TraceLevel.Error,TraceLevel.Warning, TraceLevel.Info si TraceLevel.Verbose. Orice valoare mai maredecat 4 este tratata ca TraceLevel.Verbose.

Daca aplicatia nu are un fisier .config, acesta se poate crea, de exemplu, folosindmeniul Project, optiunea Add New Item. Fisierul trebuie sa aiba numele app.config,unde app este numele aplicatiei. Se editeaza in cadrul fisierului tagul de inceput, xml, sitagul configuration.

Intre tagurile configuration, se declara comutatoarele si se seteaza valorile acestora.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 90 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 91: Aplicatii in Visual.net

Exemplu:

<system.diagnostics>

<switches>

<add name="firstBooleanSwitch" value="0" />

<add name="firstTraceSwitch" value="3" />

</switches>

</system.diagnostics>

In acest exemplu, firstBooleanSwitch este setat pe off, iar firstTraceSwitch este setat laTraceLevel.Info. Se modifica apoi valorile comutatoarelor, in functie de output-ul pecare dorim sa il vizualizam. Se pot adauga, eventual, comentarii adecvate, pentru aexplica configurarile efectuate prin intermediul fisierului XML.

<system.diagnostics>

<switches>

<!-- pentru a primi mesaje Trace, setati valoarea la un intregnenul... -->

<add name="firstBooleanSwitch" value="0" />

<!-- setati valoarea la 1,2,3 sau 4 pentru, respectiv, mesajeminimale, normale, detaliate sau complete -->

<add name="firstTraceSwitch" value="3" />

</switches>

</system.diagnostics>

Sinteza

- clasele Debug si Trace classes allow you to display and log messages

- colectia Trace.Listeners:

* DefaultTraceListener

* TextWriterTraceListener

* EventLogTraceListener

- comutatoare Trace: BooleanSwitch, TraceSwitch

- fisierul de configurare al aplicatiei

3. Exceptii

Chiar si dupa testarea si debugging-ul complet al aplicatiei, pot inca aparea erori la

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 91 of 203

Page 92: Aplicatii in Visual.net

run-time. De exemplu, o aplicatie care salveaza date pe un floppy disk va genera oeroare daca se incearca salvarea pe un disc care nu este disponibil. Chiar daca codulaplicatiei functioneaza, eroarea poate aparea. C# confera posibilitatea tratariiexceptiilor, adica scrierea de cod care sa permita continuarea executiei programului inastfel de situatii.

Cum se trateaza exceptiile?

Atunci cand o aplicatie intalneste o eroare la run-time, se arunca o exceptie. Exceptiilesunt instante ale unor clase specializate care mostenesc clasa de bazaSystem.Exception. Clasele folosite pentru tratarea exceptiilor includ aspecte carefaciliteaza diagnosticarea si managementul erorilor, cum ar fi:

- proprietatea Message - contin o descriere a erorii, precum si alte informatii relevantedespre aceasta

- proprietatea StackTrace - ofera posibilitatea localizarii fragmentului de cod care agenerat eroarea

Utilizatorul poate crea propriile exceptii, derivand din clasaSystem.ApplicationException. La intalnirea unei erori la run-time, se creaza o instantaa exceptiei corespunzatoare erorii si este transmisa de la metoda care a generateroarea catre metoda apelanta, prin intermediul stivei de apeluri. Daca, la nivelulmetodei apelante, se intalneste o structura de tratare a exceptiei, aceasta este tratata.In caz contrar, exceptia este pasata urmatoarei metode apelante s.a.m.d. Daca nu seintalneste nici o astfel de structura, se efectueaza o tratare implicita a exceptiei.Aceasta are ca efect afisarea unui message box care vizualizeaza informatii legate detipul exceptiei si alte informatii aditionale si apoi aplicatia se termina, fara a mai aveaposibilitatea salvarii datelor sau tratarii erorii.

Utilizand structuri de tratare a exceptiilor, se pot defini modalitati de tratare a erorilorsau, cel putin, de salvare a datelor inainte de inchiderea aplicatiei.

Crearea unui exception handler

Structurile de tratare a exceptiilor sunt implementate pentru metode specifice. Deci,fiecare metoda poate avea propriul exception handler, specific metodei respective siexceptiilor pe care le poate arunca. Metodele care pot arunca exceptii, cum ar fimetodele care implica acces la fisiere, trebuie sa implementeze structuri de tratare aexceptiilor. Acestea utilizeaza structuri de forma Try...Catch...Finally. Urmatorii trei pasisunt specifici crearii unei structuri de tratare a exceptiilor:

- se scrie codul care se va asocia handler-ului intr-un bloc try

- se adauga unul sau mai multe blocuri catch pentru tratarea posibilelor exceptii

- se adauga intr-un bloc finally cod care se va executa neconditionat (chiar daca searunca sau nu exceptia)

Exemplu:

try

{

// cod care poate arunca exceptii

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 92 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 93: Aplicatii in Visual.net

}

// urmeaza blocuri catch sau finally

Un bloc try poate fi urmat de unul sau mai multe blocuri catch. Un bloc catch continecod care va fi executat atunci cand exceptia va fi aruncata. Blocurile catch pot figenerice sau specifice exceptiei. Exemplu: un bloc catch generic.

// bloc try... catch

{

// se executa la aruncarea oricarei exceptii

}

Se poate obtine o referinta a exceptiei care a fost aruncata. Acest lucru permiteaccesarea in cadrul rutinei de tratare a exceptiei a informatiei continute de exceptie. Sepot crea astfel blocuri catch multiple, specifice exceptiilor respective.

Exemplu:

// bloc try...

catch (System.NullReferenceException e)

{

// se prinde o exceptie NullReferenceException

}

catch (System.Exception e)

{

// acest bloc va prinde toate celelalte exceptii

}

Blocurile finally contin cod care trebuie executat independent de faptul ca o exceptie afost aruncata sau nu. Exemplu:

public void Parsare(string sir)

{

try

{

double x;

x = Double.Parse(sir);

}

catch (System.ArgumentNullException e)

{

// cod pentru cazul in care s-a

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 93 of 203

Page 94: Aplicatii in Visual.net

// aruncat o exceptie de acest tip

}

catch (System.Exception e)

{

// cod pentru tratarea celorlalte exceptii

}

finally

{

// cod care se va executa neconditionat

}

}

Se va executa tot timpul un singur bloc catch. Se executa apoi blocul finally. Executiaaplicatiei se continua cu urmatoarea linie de cod de dupa linia care a apelat rutina cecontine erori.

!

Deoarece se executa un singur bloc catch, acestea trebuie scrise de la cel mai specificla cel mai putin specific bloc. Uneori, se doreste tratarea exceptiilor in cadrul rutineicare a apelat rutina ce contine blocul try (cu un nivel mai sus). Chiar si in acest caz,poate aparea necesitatea scrierii de cod care se va executa indiferent de aruncareasau nu a exceptiei. Pentru aceasta, se omite blocul catch si se utilizeaza o structuratry...finally. Exemplu:

try

{

// codul metodei...

}

finally

{

// cod de clean-up

}

Aruncarea exceptiilor

Se disting doua situatii specifice:

- eroare care poate fi patial tratata local: se trateaza partial eroarea, apoi aceasta estetransmisa stivei de apeluri

- eroare care nu poate fi tratata local: se arunca o exceptie .NET sau o exceptiespecifica

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 94 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 95: Aplicatii in Visual.net

Rearuncarea exceptiiilor

Uneori, structura de tratare a exceptiilor, initial proiectata, nu este capabila sa tratezetotal o anumita exceptie. In acest caz, se utilizeaza cuvantul rezervat throw, in cadrulblocului catch, pentru rearuncarea exceptiei, adica transmiterea acesteia catre functiaapelanta. Exemplu:

try

{

// cod...

}

catch (System.NullReferenceException e)

{

// cod care testeaza posibilitatea tratarii exceptiei

// daca aceasta nu va putea fi tratata complet, va fi rearuncata

throw e;

}In cazul unui catch generic, se utilizeaza cuvantul rezervat throw, fara a mai specifica oreferinta catre o anumita exceptie:

// bloc catch

catch

{

throw;

}

La rearuncare, se poate crea o noua exceptie care contine mesaje informative,incluzand caracteristicile exceptiei initiale (in cazul in care dorim furnizarea deinformatii suplimentare catre nivelul superior al aplicatiei, caruia i se transmite exceptiaprin throw) Exemplu:

// bloc catch

catch (NullReferenceException e)

{

throw new NullReferenceException(

"Obiectul X este neinitializat", e);

}

Exceptii definite de utilizator (custom)

Un al doilea scenariu in care se poate arunca o noua exceptie este dezvoltarea de

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 95 of 203

Page 96: Aplicatii in Visual.net

componente. In cazul unei conditii care nu poate fi rezolvate, este indicata aruncareaunei exceptii definite de utilizator in cadrul aplicatiei client.

!

Aruncarea exceptiilor nu trebuie sa devina o obisnuinta, ci trebuie efectuata numai inconditii exceptionale din program.

Exceptiile de tip custom se creaza prin derivarea din clasaSystem.ApplicationException. Aceasta incapsuleaza intreaga functionalitate necesaraunei exceptii, incluzand proprietatile Message, StackTrace si InnerException. Exemplu:

public class CustomException: System.ApplicationException

{

KindOfObject an_object;

public KindOfObject ErrorObject // proprietate

{

get

{

return an_object; // read-only

}

}

// constructor - parametri de tip KindOfObject si string

public CustomException(KindOfObject o, string a) : base(s)

// se apeleaza constructorul din clasa de baza

{

// se seteaza proprietatea

an_object = o;

}

}

Dupa crearea unei clase exceptie, se poate arunca o noua instanta a acestei clase:Exemplu:

KindOfObject a = new KindOfObject();

// cod care corupe obiectul a omis...

throw new CustomException(a, "Obiectul a a fost corupt!");

Sinteza

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 96 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 97: Aplicatii in Visual.net

- exceptii

- tratarea exceptiilor: try, catch, finally

- rearuncarea exceptiilor

- clasa System.ApplicationException

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 97 of 203

Page 98: Aplicatii in Visual.net

Section 7. Accesarea bazelor de date. ADO.NET - VI

1. Privire de ansamblu

O mare parte dintre aplicatii necesita un anumit tip de acces la baze de date. Aplicatiiledesktop trebuie sa integreze modele care sa interactioneze cu baze de date centrale,colectii de date in format XML sau baze de date locale. Tehnologia ADO.NET de accesla baze de date permite accesul facil si eficient la colectiile de date, prin eficientizareautilizarii resurselor.

Acces la baze de date fara conexiune

Tehnologiile anterioare functionau pe baza accesului la baze de date prin stabilireaunei conexiuni permanente pe durata efectuarii operatiilor specifice. Intr-un astfel demodel, aplicatia creaza o conexiune la baza de date si aceasta este activa pana lasfarsitul aplicatiei, sau cel putin pe durata interogarii bazei de date.

Dezavantaje ale conexiunilor permanente la baze de date:

-conexiunile deschise la bazele de date sunt costisitoare din punct de vedere alresurselor

-aplicatiile sunt dificil de scalat; o aplicatie care functioneaza foarte bine cu 5 clientipoate avea performante foarte scazute pentru 50 de conexiuni deschise simultan

-utilizarea unui numar mare de conexiuni poate conduce la epuizarea licentelordisponibile pentru baza de date

ADO.NET vine in intampinarea acestor probleme implementand un model de accesarea bazelor de date fara conexiune permanenta. In cadrul acestui model, conexiunilesunt initializate si mentinute active doar pe durata efectiva a executiei operatiilor cubaza de date. De exemplu, daca o aplicatie solicita anumite date dintr-o baza,conexiunea este deschisa doar pe durata incarcarii datelor in aplicatie, apoiconexiunea este inchisa. Similar, in cazul altor operatii.

Arhitectura ADO.NET

Accesul la date in ADO.NET implica doua entitati:

-un DataSet, care stocheaza datele pe masina locala

-un Data Provider, un set de componente care mediaza interactiunea dintre program sibaza de date

DataSet

Un DataSet este o reprezentare non-conexiune, in-memory , a unei multimi de date.Poate fi gandit ca o copie locala a sectiunilor bazei de date utile aplicatiei. Datele pot fiincarcate intr-un DataSet din orice sursa valida, cum ar fi un server SQL, o baza dedate Microsoft Access sau un fisier XML. DataSet-ul persista in memorie, iar datelecontinute pot fi modificate, manipulate, independent de baza se date. La momentuloportun, DataSet-ul poate actiona ca un sablon pentru modificarea bazei de date

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 98 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 99: Aplicatii in Visual.net

centrale.

Un obiect DataSet contine o colectie de zero sau mai multe obiecte DataTable, fiecaredintre acestea fiind o reprezentare in-memory a unei tabele. Structura unui obiectDataTable este definita de colectia DataColumns, care enumereaza coloanele dintr-otabela si de colectia Constraint care enumereaza legaturile, constrangerile din tabela.Aceste doua colectii definesc schema tabelei. Un obiect DataTable contine, deasemenea, o colectie DataRows, care contine datele corespunzatoare din DataSet.

Un DataSet contine o colectie DataRelations care permite crearea asocierilor intreliniile unei tabele si liniile altei tabele. Colectia DataRelations enumereaza un set deobiecte DataRelation care definesc relatiile intre tabelele din DataSet.

Data Provider

Legatura cu baza de date este creata si mentinuta de un data provider. Acesta esteformat dintr-un set de componente interconectate care coopereaza pentru a furnizadate intr-o maniera eficienta, performanta.

Exista patru tipuri de furnizori de date in .NET Framework:

- SQL Server .NET Data Provider

- OleDb .NET Data Provider

- ODBC Data Provider

- Oracle Data Provider

Fiecare dintre acesti furnizori contin versiuni ale urmatoarelor clase generice:

- Connection - realizeaza conexiunea la baza de date

- Command - executa o comanda asupra unei surse de date: comenzi non-query(INSERT, UPDATE sau DELETE) sau comanda SELECT, returnand un DataReader

- DataReader - desemneaza o multime de inregistrari (recordset) bazata pe conexiune,de tip forward-only , read-only

- DataAdapter - populeaza un DataSet sau DataTable non-conexiune si executamodificari

Mecanismul accesarii bazelor de date in ADO.NET este urmatorul:

- un obiect Connection stabileste o conexiune intre aplicatie si baza de date. Aceastaconexiune poate fi accesata direct de un obiect Command sau de un obiectDataAdapter. Obiectul Command executa o comanda asupra bazei de date. Daca sereturneaza valori multiple, se utilizeaza un obiect DataReader care va contine datelereturnate. Aceste date pot fi procesate direct de de aplicatie. Alternativ, se poate utilizaun DataAdapter pentru a popula un obiect DataSet. Modificarile asupra bazei de datese pot efectua prin intermediul unui obiect Command sau unui obiect DataAdapter.

Connection

Reprezinta conexiunea curenta la baza de date.

Tipuri de conexiuni:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 99 of 203

Page 100: Aplicatii in Visual.net

- SqlConnection - pentru conectarea la SQL Server 7 sau versiuni ulterioare

- OleDbConnection - conexiuni la diverse tipuri de baze de date

- ODBCConnection

- OracleConnection

Un obiect Connection contine toate informatiile necesare deschiderii unui canal decomunicatie cu baza de date in cadrul proprietatii ConnectionString. Sunt incorporate,de asemenea, metode pentru facilitarea tranzactiiilor.

Command

Este reprezentat de doua clase: SqlCommand si OleDbCommand Utilizat pentru aefectua apeluri de proceduri stocate sau de comenzi SQL asupra bazei de date saupentru a returna tabele. Metode:

- ExecuteNonQuery - executa comenzi care nu returneaza inregistrari - INSERT,UPDATE, DELETE

- ExecuteScalar - returneaza o singura valoare dintr-o interogare

- ExecuteReader - returneaza o multime rezultat, sub forma unui obiect DataReader

DataReader

- contine un recordset bazat pe conexiune, forward-only, read-only

- obiectele DataReader nu pot fi instantiate direct, sunt returnate ca rezultat al metodeiExecuteReader a unui obiect Command (SqlCommand - SqlDataReader etc)

- o singura linie din recordset este in memorie la un moment dat, deci se foloseste unminim de resurse, dar este necesara mentinerea activa a unui obiect Connection pedurata de viata a obiectului DataReader

DataAdapter

DataAdapter este clasa din nucleul tehnologiei ADO.NET, bazata pe mecanismulnon-conexiune.

- faciliteaza comunicarea intre baza de date si DataSet

- populeaza obiectele DataTable sau DataSet ori de cate ori se apeleaza metoda Fill

- metoda Update inregistreaza modificarile, efectuate local, in baza de date

Proprietati:

- SelectCommand - contine textul sau obiectul asociat comenzii care se va efectua laapelul metodei Fill

- InsertCommand - contine textul sau obiectul asociat comenzii prin care se insereazao linie in tabela

- DeleteCommand - similar, pentru stergerea unei linii din tabela

- UpdateCommand - similar, pentru modificarea valorilor din baza de date

La apelul metodei Update, se copie modificarile din DataSet in baza de date,

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 100 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 101: Aplicatii in Visual.net

executandu-se una din comenzile reprezentate de InsertCommand, DeleteCommandsau UpdateCommand.

2. Comenzi SQL

Structured Query Language (SQL) - limbajul universal al bazelor de date relationale.SQL poate fi utilizat pentru a prelua si filtra inregistrari din baza de date, pentru aadauga inregistrari, pentru a sterge inregistrari din baza de date si pentru a modificavalorile unei inregistrari existente.

Exista 4 constructii de baza:

- SELECT - pentru selectarea anumitor inregistrari din baza de date

- UPDATE - pentru modificarea unor inregistrari in baza de date

- INSERT - pentru inserarea unei noi linii intr-o tabela

- DELETE - pentru eliminarea unei inregistrari

SELECT

Sintaxa:

SELECT lista_campuri

FROM lista_tabele

WHERE (Optional) filtre

ORDER BY (Optional) criteriu_de_ordonare

Sintaxa minimala:

SELECT campuri FROM tabele

Exemplu:

SELECT StudentID, Prenume FROM Studenti;

Selectarea tuturor campurilor dintr-o tabela:

SELECT * FROM Studenti

WHERE - filtreaza inregistrarile dupa un anumit criteriu

SELECT * FROM Studenti WHERE Prenume = 'Vlad'

O conditie mai complexa:

SELECT * FROM Studenti WHERE Prenume = 'Vlad' AND Nume = 'Tepes'

Operatorul IN:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 101 of 203

Page 102: Aplicatii in Visual.net

SELECT Prenume, Nume FROM Studenti WHERE OrasNatal IN ('Deva', 'Bod')

Operatorul BETWEEN:

SELECT * FROM Studenti WHERE Media BETWEEN 8.5 AND 10

Sabloane:

SELECT * FROM Studenti WHERE Prenume LIKE 'Vla_'

Sablonul se va potrivi pentru prenume de 4 litere care incep cu Vla.

SELECT * FROM Studenti WHERE Prenume LIKE 'Vla%'

Se vor returna studentii al caror prenume incepe cu Vla.

Clausa ORDER BY

SELECT * FROM Studenti ORDER BY Medie DESC

DELETE

Elimina in mod ireversibil inregistrari din baza de date.

DELETE FROM Studenti WHERE Prenume = 'Vlad' AND Nume = 'Tepes';

Clauza WHERE are acceasi sintaxa ca in cazul comenzii SELECT.

UPDATE

Sintaxa generala:

UPDATE tabela

SET coloana1 = valoare1, ... ,coloanaN = valoareN

[WHERE predicat]

Exemplu:

UPDATE Studenti

SET Nume = 'Diaconu'

WHERE Prenume = 'Maria' AND Nume = 'Popescu'

Operatorii IN, BETWEEN, LIKE si clauza WHERE au aceeasi utilizare ca in cazulcomenzii SELECT.

INSERT INTO

Insereaza o inregistrare intr-o tabela. Sintaxa:

INSERT INTO tabela [(coloana1, ..., coloanaN)]

VALUES (valoare1, ... , valoareN)

Exemplu:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 102 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 103: Aplicatii in Visual.net

INSERT INTO Studenti (Prenume, Nume, Varsta, Sex) VALUES ('Vlad', 'Tepes', 500,'M')

3. Accesarea datelor

Conectarea la o baza de date

Exista mai multe posibilitatati de conectare la o baza de date:

- crearea unei conexiuni in mod design utilizand uneltele grafice din Visual Studio .NETConexiunile curente sunt vizualizate in fereastra Server Explorer, ca noduri copil alenodului Data Connections. Adaugarea unei conexiuni la proiect se face prin drag anddrop

- in fereastra Server Explorer se executa clic dreapta pe nodul Data Connections si seselecteaza Add Connection, setandu-se proprietatile conexiunii in fereastra Data Linkcare se deschide

- varianta manuala - adaugarea unui obiect Connection din Toolbox sau declararea siinstantierea obiectului in cod

- crearea unei conexiuni direct in cod - se seteaza manual proprietateaConnectionString. Exemplu:

// declararea si instantierea unui obiect OleDbConnection

OleDbConnection firstConnection = new OleDbConnection();

// setarea proprietatii connection string

firstConnection.ConnectionString =

"Provider=Microsoft.Jet.OLEDB.4.0;DataSource=" +

"C:\\Mdb_databases\\studenti.mdb";

Utilizarea comenzilor asupra bazelor de date

Un obiect Command contine o referinta la o procedura stocata in cadrul bazei de datesau o comanda SQL si poate executa comanda respectiva prin intermediul uneiconexiuni active la baza de date. Un astfel de obiect contine toate informatiile necesareexecutiei comenzii, inclusiv o referinta la conexiunea activa, specificarea efectiva acomenzii si, eventual, parametrii solicitati de comanda.

Clase de tip Command:

-OleDbCommand - interactiunea cu diverse tipuri de baze de date

-SqlCommand - interactiunea cu SQL Server 7 sau cu versiuni mai noi

Deoarece obiectele de tip Command implica existenta unei conexiuni active si nunecesita interactiunea cu un DataAdapter, ele furnizeaza o modalitate rapida sieficienta de interactiune cu baza de date.

Actiuni posibile:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 103 of 203

Page 104: Aplicatii in Visual.net

- executia unor comenzi care nu returneaza inregistrari - INSERT, UPDATE, DELETE

- executia unor comenzi care returneaza o singura valoare

- executia unor comenzi de tipul Database Definition Language (DDL), cum ar fiCREATE TABLE sau ALTER

- interactiunea cu un DataAdapter pentru a returna un DataSet

- extragerea unei multimi de inregistrari utilizand direct o instanta a unui obiectDataReader

- returnarea unei multimi de inregistrari in format XML (numai utilizand SqlCommand)

- returnarea unei multimi de inregistrari din mai multe tabele sau constructii caredesemneaza comenzi

Crearea si configurarea unei comenzi (Command):

- prin atasarea la proiect (in mod design) a unei proceduri stocate pe serverul de bazede date, utilizand fereastra Server Explorer

- prin selectarea unui obiect Command din Toolbox, adaugarea acestuia in proiect siconfigurarea sa folosind fereastra Properties

- prin declararea, instantierea si configurarea manuala a unui obiect Command, in cod

La crearea manuala a unui obiect Command, trebuie setate proprietatile Connection,CommandType si CommandText.

CommandType - tipul comenzii specificate de proprietatea CommandText. Exista 3valori posibile:

- Text - valoarea proprietatii CommandText va fi tratata drept comanda SQL (una saumai multe, separate prin punct si virgula (;), comenzile executandu-se secvential)

- StoredProcedure - valoarea proprietatii CommandText trebuie sa contina, in acestcaz, numele unei proceduri stocate pe serverul de baze de date; executia acesteicomenzi determina executia procedurii specificate

- TableDirect - se indica numele unei (mai multor) tabela(e); se va returna continutultabelei(lor) specificate

Proprietatea Connection trebuie setata la o conexiune existenta, avand tipul adecvat(SqlCommand - SqlConnection, OleDbCommand - OleDbConnection).

Executia comenzilor

Se face prin intermediul a trei metode specifice:

-ExecuteNonQuery - specifica comenzilor de tip INSERT, UPDATE si DELETE(comenzi non-query) si comenzilor de tip DDl, CREATE si ALTER

-ExecuteScalar - returneaza prima coloana a primei linii din multimea de inregistrarireturnate de comanda

-ExecuteReader - returneaza un obiect DataReader (forward-only, read-only), cu accesrapid la date, utilizat atunci cand nu este necesara modificarea datelor in baza

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 104 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 105: Aplicatii in Visual.net

-ExecuteXmlReader (numai pentru SqlCommand)-returneaza un obiect XmlReader(forward-only, read-only), in format XML

Parametri

Frecvent, comenzile implica utilizarea parametrilor, valorile anumitor entitati din cadrulunei comenzi nefiind cunoscute pana in momentul executiei aplicatiei. Exemplu deconstructie SQL cu parametri:

SELECT * FROM Studenti WHERE (Prenume LIKE [sir])

sir este o valoare furnizata de utilizator la executie. Parametrii sunt valori careinlocuiesc entitati din cadrul textului unei comenzi. Fiecare parametru este identificatefectiv in program ca o instanta a clasei OleDbParameter sau SqlParameter. Ei suntstocati in proprietatea Parameters a clasei Command si, la run-time, valorile sunt cititedin proprietate si plasate in constructia SQL sau furnizate procedurii. ColectiaParameters contine obiecte Parameter, avand urmatoarele proprietati mai importante:

- DbType

- Direction - cu valorile posibile Input, Output, InputOutput, or ReturnValue

- OleDbType

- ParameterName

- Precision

- Scale

- Size

- SourceColumn

- SourceVersion

- SQLType

- Value

Exemplu:

// setarea valorii primului parametru din colectie prin index

OleDbCommand1.Parameters[0].Value = "Primul parametru...";

// setarea valorii unui parametru identificat prin nume

OleDbCommand1.Parameters["nume_parametru1"].Value ="valoare...";

Proprietatile Precision, Scale si Size stabilesc dimensiunea si acuratetea parametrilor -pentru parametri numerici, binari sau de tip string.

SourceColumn si SourceVersion sunt utilizati atunci cand parametrul este legat de ocoloana intr-un DataTable.

Proprietatea Value contine valoarea reprezentata de parametru.

Pentru obiecte OleDbCommand, atunci cand CommandType este setata la valoarea

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 105 of 203

Page 106: Aplicatii in Visual.net

Text, parametri sunt specificati in cadrul comenzii SQL prin caractere (?). De exemplu:

SELECT StudentId, Prenume, Nume

FROM Studenti

WHERE (Prenume = ?) AND (Nume = ?)

Parametrii sunt inserati in ordinea in care apar in colectia Parameters.

Obiectele de tip SqlCommand utilizeaza parametri identificati prin nume, mai precis, incadrul comenzii SQL, un parametru este identificat prin simbolul @, urmat de valoareaproprietatii ParameterName a parametrului respectiv:

SELECT StudentId, Prenume, Nume

FROM Studenti

WHERE (Nume = @Nume)

Executia unei comenzi non-query utilizand un obiect Command

- INSERT, UPDATE, DELETE, CREATE TABLE si ALTER

- CommandType - setata la StoredProcedure sau Text - se specifica eventualiiparametri - se apeleaza metoda Command.ExecuteNonQuery

// apel identic pentru OleDbCommand sau SqlCommand

firstCommand.ExecuteNonQuery();

Utilizarea unui obiect Command pentru a returna o valoare singulara

- CommandType - setata la StoredProcedure sau Text

- se specifica eventualii parametri

- se apeleaza metoda Command.ExecuteScalar

Object o;

o = firstCommand.ExecuteNonScalar();

DataReader

Pentru a utiliza un obiect Command care are asociate interogari care returneaza valorimultiple, se apeleaza metoda ExecuteReader pentru a returna un DataReader. UnDataReader este un obiect care gestioneaza date intr-o maniera read-only,forward-only, eficienta si rapida. Un DataReader itereaza inregistrarile returnate intr-omultime rezultat. Viteza de accesare a datelor este mare, dar limitarile provin din faptulca maniera de prelucrarea este read-only, forward-only si nu se pot face modificariasupra bazei de date. Mai mult, este necesara mentinerea unei conexiuni active pedurata efectuarii acestor operatii, ceea ce determina un consum destul de semnificativde resurse.

Crearea unui DataReader

Un DataReader nu poate fi creat explicit. El este instantiat printr-un apel al metodei

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 106 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 107: Aplicatii in Visual.net

ExecuteReader a unui obiect Command. Exemplu:

// firstOleDbCommand si firstSqlCommand sunt doua

// obiecte OleDbCommand, respectiv SqlCommand create anterior

System.Data.OleDb.OleDbDataReader firstOleDbReader;

System.Data.SqlClient.SqlDataReader firstSqlReader;

// creare si asignare

firstOleDbReader = firstOleDbCommand.ExecuteReader();

firstSqlReader = firstSqlCommand.ExecuteReader();

Accesarea datelor utilizand un DataReader

Iterarea inregistrarilor se poate realiza folosind metoda Read:

while (firstDataReader.Read())

{

// code care se va executa pentru fiecare inregistrare

}

Valorile coloanelor individuale din fiecare inregistrare pot fi accesate prin index sau prinnume. De exemplu:

while (firstDataReader.Read())

{

object o = firstDataReader[3];

object oo = firstDataReader["StudentID"];

}

Toate valorile furnizate de un DataReader sunt preluate ca obiecte, dar se pot retunavalori si in maniera puternic tipizata. Orice obiect DataReader mentine un accesexclusiv asupra conexiunii utilizate, de accea, dupa efectuarea operatiilor, trebuieapelata metoda Close a obiectului DataReader.

firstDataReader.Close();

Accesarea coloanelor de date cu un DataReader

Exemplu: afisarea valorilor unei coloane la consola.

firstConnection.Open();

// se creaza un DataReader

System.Data.OleDb.OleDbDataReader firstReader =

firstOleDbCommand.ExecuteReader();

// se apeleaza Read

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 107 of 203

Page 108: Aplicatii in Visual.net

while (firstReader.Read())

{

// accesarea coloanelor prin nume

Console.WriteLine(firstReader["Prenume"].ToString());

}

firstReader.Close();

// se inchide DataReader-ul

firstConnection.Close();

// se inchide conexiunea

DataReader - tipizare

Clasa DataReader expune, de asemenea, metode tipizate de extragere a informatiilor,de tip Get:

bool bool_var;

bool_var = myDataReader.GetBoolean(3);

// se utilizeaza numarul coloanei

Metoda GetOrdinal

int StudID;

string student;

// se preia indexul coloanei, utilizand numele acesteia

StudID = firstDataReader.GetOrdinal("StudentID");

student = firstDataReader.GetString(StudID);

Multimi rezultat multiple

Daca proprietatea CommandType a obiectului Command este setata la valoarea Text,se pot returna mai multe multimi de inregistrari drept rezultat. Exemplu de comandaSQL care va furniza rezultate multiple:

SELECT *

FROM Studenti;

SELECT *

FROM Profesori;

Un DataReader returneaza implicit prima multime de inregistrari in mod automat.Pentru a accesa urmatoarea multime rezultat, se apeleaza metoda NextResult.Exemplu:

do

{

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 108 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 109: Aplicatii in Visual.net

while (firstReader.Read())

{

// iterarea inregistrarilor multimii rezultat curente

}

} while (firstReader.NextResult());

Executia interogarilor SQL Ad Hoc

Sunt comenzi ale caror interogari se construiesc la run-time. Exemplu 1:

string cmd;

cmd = "SELECT * FROM Studenti WHERE Nume = '" + sir_de_caractere+ "'";

Exemplu 2:

public void DeleteRecord(string sir)

{

string cmd;

cmd = "DELETE * FROM Studenti WHERE Nume = '" + sir + "'";

OleDbCommand firstCommand = new OleDbCommand(cmd,firstConnection);

firstConnection.Open();

firstCommand.ExecuteNonQuery();

firstConnection.Close();

}!

Atentie la validarea continutului variabilelor utilizate in constructia comenzilor SQL!

Crearea si configurarea obiectelor DataAdapter

Asigura legatura intre o sursa de date si un DataSet, gestionand schimbul de date intreaceste doua entitati. Un DataAdapter incorporeaza functionalitatea necesara extrageriidatelor, popularii unui DataSet si aplicarii modificarilor in baza de date.

Clase .Net Framework: SqlDataAdapter, OleDbDataAdapter.

Un DataAdapter este utilizat, in general, pentru gestionarea schimbului de date dintreun obiect DataTable continut intr-un DataSet si o singura tabela sursa.

Modalitati de creare a unui DataAdapter:

- utilizand fereastra Server Explorer (se adauga, prin drag and drop, o tabela indesign-ul aplicatiei)

- folosind Data Adapter Configuration Wizard (utilizand componenta DataAdapter dinToolbox)

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 109 of 203

Page 110: Aplicatii in Visual.net

- manual

Extragerea multimilor de date utilizand obiecte DataAdapters

Un DataSet este o reprezentare in-memory a datelor extrase la un moment dat dinbaza de date si nu implica existenta unei conexiuni active. Un DataSet poate continetabele multiple, relatii intre tabele si constrangeri. Pot fi incluse intr-un DataSet dateprovenind de la diverse surse de date. Obiectele DataAdapter gestioneazainteractiunea dintre obiectele DataSet si bazele de date.

Popularea unui DataSet cu date se efectueaza prin apelarea metodei Fill a obiectuluiDataAdapter. Metoda Fill executa instructiunile specificate de proprietateaSelectCommand, in cadrul conexiunii specificate de proprietatea Connection sipopuleaza DataSet-ul cu datele returnate. Exemplu:

DataSet firstDataSet = new DataSet();

firstDataAdapter.Fill(firstDataSet);

Popularea unui DataSet care contine mai mumte tabele:

- se creaza o instanta DataSet

- se creaza un DataAdapter pentru fiecare tabela din DataSet

- se apeleaza secvential metoda Fill pentru fiecare DataAdapter, specificandDataSet-ul drept target

Obiecte DataSet tipizate

Exemplu 1: obiecte DataSet netipizate.

string stud;

stud =(string)dsFacultate.Tables["Studenti"].Rows[0]["StudentID"];

Exemplu 2: obiecte DataSet tipizate.

string stud;

stud = dsFacultate.Studenti[0].StudentID;

Un DataSet tipizat este, de fapt, o instanta a unei clase noi, derivare din clasa DataSet.Structura noii clase este bazata pe un fisier XSD (XML Schema Definition) caredefineste structura DataSet-ului, incluzand numele tabelelor si al coloanelor. Se potcrea DataSet-uri tipizate numai in momentul in care se cunoaste structura exacta adatelor.

Pentru a genera un DataSet se poate selecta optiunea Generate Dataset din meniulData.

Sinteza

- Connection

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 110 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 111: Aplicatii in Visual.net

- Command

* ExecuteNonQuery

* ExecuteScalar

* ExecuteReader

- parametri

- DataReader

- DataAdapter

4. Mai multe despre DataSet

DataSet reprezinta componenta centrala a arhitecturii ADO.NET, fiind o reprezentarein-memory a datelor. Obiectele DataSet pot fi populate cu date prin intermediulobiectelor DataAdapter, din fisiere XML, din fisiere text sau prin constructiiprogramatice.

Crearea si popularea obiectelor DataSet fara a utiliza un DataAdapter

Exemplu de creare a unui DataSet prin scrierea de cod:

DataSet firstDataSet = new DataSet();

DataTable firstTable = new DataTable();

firstDataSet.Tables.Add(firstTable);

In cadrul unui DataSet, tabelele sunt gestionate prin intermediul colectiei Tables, deasemenea, in cadrul unei tabele, colectia Columns manipuleaza coloanele.

DataColumn StudentColumn = new DataColumn("Student");

firstDataSet.Tables[0].Columns.Add(StudentColumn);

Dupa adaugarea tuturor coloanelor dintr-o tabela, se pot adauga inregistrari, prinintermediul obiectelor DataRows.

DataRow firstRow;

// nu se instantiaza, se apeleaza metoda NewRow

firstRow = firstDataSet.Tables[0].NewRow();

Un obiect DataRow poate fi populat cu date provenind dintr-o colectie, un array sauinput-ul utilizatorului. Exemplu:

// SourceString este un ArrayList

...

firstRow[i] = SourceString[i];

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 111 of 203

Page 112: Aplicatii in Visual.net

Adaugarea unui DataRow la colectia Rows a unui DataTable:

firstDataSet.Tables[0].Rows.Add(firstRow);

Accesarea fisierelor text

In multe aplicatii, datele sunt stocate in fisiere text de dimensiuni mari, fiind necesaracitirea datelor din aceste fisiere si popularea unui DataSet ADO.NET. Spatiul de numeutilizat este System.IO. Un fisier text poate fi manipulat prin intermediul claseiSystem.IO.StreamReader. Un format foarte des utilizat de structurare a informatiilor incadrul fisierelor text este .CSV. Exemplu: vezi resurse - Curs6, 1_flat_file.txt.

DataRelation

Un obiect DataRelation reprezinta o relatie intre doua coloane din doua tabele diferite.De exemplu, pot exista doua tabele, Studenti si Optionale, fiecare continand o coloanaStudentID. Fiecare student apare o singura data in tabela Studenti, dar poate apareade mai multe ori in tabela Optionale. StudentID in tabela Optionale specifica studentuldin tabela Studenti care a ales optionalul respectiv. Acesta este un exemplu de relatieone-to-many . Obiectele DataRelation sunt utilizate pentru identificarea acestor tipuride relatii.

Obiectele DataRelation ale unui DataSet particular sunt continute in proprietateaRelations a DataSet-ului. Un obiect DataRelation este creat specificand numele relatiei,coloana parinte si coloana copil. Intr-un DataSet tipizat, ambele coloane trebuie sa aibaacelasi tip. Exemplu:

// coloana1, coloana2 sunt doua instante DataColumns

DataRelation oRelatie =

new DataRelation("Data Relation 1", coloana1,

coloana2);

Adaugarea la colectia Relations a DataSet-ului

unDataSet.Relations.Add(oRelatie);

Accesarea inregistrarilor implicate intr-o relatie

Se utilizeaza metodele GetChildRows si GetParentRow ale clasei DataRow. Exemplu:

DataRow[] ChildRows;

DataRow ParentRow;

// se returneaza liniile din Optionale care sunt in relatie cu

// linia 1 din tabela Studenti

ChildRows =

unDataSet.Tables["Studenti"].Rows[1].GetChildRows(oRelatie);

// linia din Studenti care este in relatie cu linia 3 din

// tabela Studenti

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 112 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 113: Aplicatii in Visual.net

ParentRow = unDataSet.Tables["optionale"].

Rows[2].GetParentRow(oRelatie);

Constrangeri

Constrangerile definesc reguli de adaugare si manipulare a datelor in tabele. Tipuri deconstrangeri: UniqueConstraint (o coloana nu trebuie sa aiba valori duplicate) siForeignKeyConstraint (defineste regulile de modificare a liniilor copil atunci cand semodifica o linie parinte).

Constrangerile sunt manipulate prin intermediul colectiei Constraints a tabelei si suntactive atunci cand proprietatea EnforceConstraints a DataSet-ului este setata la true.Exemple:

myDataColumn.Unique = true;

// se creaza o canstrangere UniqueConstraint

Creare manuala:

UniqueConstraint myConstraint = new

UniqueConstraint(myDataColumn);

myDataTable.Constraints.Add(myConstraint);

Stabilirea unei chei multiple:

DataColumn[] KeyColumns = new DataColumn[2];

KeyColumns[0] = StudentsTable.Columns["FirstName"];

KeyColumns[1] = StudentsTable.Columns["LastName"];

UniqueConstraint myConstraint = newUniqueConstraint(KeyColumns);StudentsTable.Constraints.Add(myConstraint);

Constrangeri Foreign Key

ForeignKeyConstraint myConstraint = new

ForeignKeyConstraint(Studenti.Columns["StudentID"],

Optionale.Columns["StudentID"]);

Adaugarea la colectia Constraints:

Studenti.Constraints.Add(myConstraint);

Reguli ForeignKeyConstraint referitoare la relatia parent-child :

• UpdateRule: invocata la modificarea unei linii parinte

• DeleteRule: invocata la stergerea unei linii parinte

• AcceptRejectRule: invocata la apelarea metodei AcceptChanges a obiectuluiDataTable caruia ii apartine constrangerea.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 113 of 203

Page 114: Aplicatii in Visual.net

Fiecare dintre aceste reguli sunt expuse ca proprietati ale obiectului care desemneazaconstrangerea si pot avea diverse valori: Cascade, None, SetDefault, SetNull.

Fiecare DataSet mentine doua versiuni ale informatiilor continute: versiunea curenta,care contine copia client a DataSet-ului si evidenta modificarilor efectuate, si versiuneaoriginala, care contine datele in formatul in care se gaseau la prima populare aDataSet-ului. La apelul metodei Update a obiectului DataAdapter, valorile initiale suntutilizate de comenzi UPDATE, INSERT si DELETE pentru a executa modificarile inbaza de date.

Editarea datelor

- prin intermediul controalelor din interfata utilizator conectate la anumite entitati dinbaza de date

- prin constructii programatice (vezi exemplu)

// accesare prin index sau nume

aDataRow[3] = "M";

aDataRow["Studenti"] = "Vlad";

Metoda RejectChanges anuleaza modificarile efectuate asupra unui DataRow:

aDataRow.RejectChanges();

AcceptChanges - se aplica modificarile efectuate asupra obiectului DataRow apelant:with the edited version.

aDataRow.AcceptChanges();

Se poate determina starea unui obiect DataRow analizand proprietatea RowState.Valori posibile:

- Unchanged

- Modified

- Added

- Deleted

- Detached

Obiectele DataTable si DataSet contin, de asemenea, metode RejectChanges siAcceptChanges, care permit refuzarea sau acceptarea modificarilor din DataTable,respectiv DataSet.

Modificarea bazei de date

firstDataAdapter.Update();

secondOtherDataAdapter.Update();

Metoda Update are ca efect copierea versiunii client a datelor in baza de date.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 114 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 115: Aplicatii in Visual.net

// se pot modifica numai anumite entitati din DataSet

aDataAdapter.Update(someDataSet);

aDataAdapter.Update(someDataTable);

aDataAdapter.Update(someDataRows);

Tranzactii

Reprezinta un set de operatii asupra bazei de date care se efectueaza ca unansamblu: daca una dintre operatii esueaza, tranzactia nu se efectueaza. Exemplu:

// tranzactiile trebuie incluse in blocuri

//Try...Catch...Finally

System.Data.OleDb.OleDbTransaction aTransaction = null;

try

{

aConnection.Open();

aTransaction = aConnection.BeginTransaction();

// crearea unei tranzactii si asocierea la conexiune

// adaugare de operatii la tranzactie

Update1.Transaction = aTransaction;

Update2.Transaction = aTransaction;

// se executa comenzile Update1 si Update2

Update1.ExecuteNonQuery();

Update2.ExecuteNonQuery();

// daca nu s-au lansat exceptii, se efectueaza tranzactia

aTransaction.Commit();

}

catch (Exception ex)

{

// tranzactia nu s-a efectuat, s-au lansat exceptii

aTransaction.Rollback();

}

finally

{

// se inchide conexiunea

aConnection.Close();

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 115 of 203

Page 116: Aplicatii in Visual.net

}

Tratarea erorilor de Update

Clasele SqlDataAdapters si OledbDataAdapters contin un eveniment RowUpdatedcare se lanseaza dupa modificare unei linii, inainte de lansarea eventualelor exceptii.Acest eveniment trebuie tratat in mod adecvat. Evenimentul RowUpdated contine oinstanta SqlRowUpdatedEventArgs sau OleDbRowUpdatedEventArgs, care furnizeazainformatii utile in determinarea erorii care a survenit.

Proprietati ale RowUpdatedEventArgs:

• Command

• Errors

• RecordsAffected

• Row

• Status

• Continue

• ErrorsOccurred

• SkipAllRemainingRows

• SkipCurrentRow

Exemplu:

private void aDataAdapter_RowUpdated(object sender,

System.Data.SqlClient.SqlRowUpdatedEventArgs e)

{

// se verifica proprietatea Status

if (e.Status == UpdateStatus.ErrorsOccurred)

{

MessageBox.Show("A survenit o eroare de tipul " +e.Errors.ToString()+".

Informatii aditionale : " + e.Errors.Message);

// se ignora modificarile de la linia curenta,

// continuandu-se cu urmatoarele

e.Status = UpdateStatus.SkipCurrentRow;

}

}

5. Accesarea, vizualizarea si filtrarea datelor

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 116 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 117: Aplicatii in Visual.net

Vizualizarea datelor reorezinta o parte vitala a multor aplicatii. Pentru aceasta,inregistrarile din cadrul unei surse de date trebuie asociate cu o serie de controale depe o forma (binding), permitandu-se accesaream parcurgerea si modificarea datelor.

Data Binding - crearea unei relatii intre un data provider si un data consumer. Un dataprovider poate fi orice obiect la care poate fi legat un consumator. In .NET Framework,orice obiect care implementeaza interfata IList poate fi furnizor de date. Aceasta nuinclude obiecte ADO.NET, cum ar fi DataSet, DataTable sau DataColumn, care pot fiprin constructie furnizori de date.

Parcurgerea datelor se realizeaza prin intermediul unui obiect CurrencyManagerasociat implicit fiecarei surse de date.

Data Consumer Orice control conectat, intr-un anumit fel, la o sursa de date poate ficonsiderat consumator. Exemplu: o forma care permite introducerea de date. In cadrulacesteia, anumite controale, cum ar fi TextBox, CheckBox, ListBox, etc. sunt conectatela anumite coloane dintr-un DataSet.

Tipuri de legare (binding): simpla si complexa.

Un control simplu legat identifica o singura inregistrare. De exemplu, un Label asociatunei coloane dintr-un DataTable.

Legarea complexa permite asocierea controlului cu mai multe inregistrari. Exemplu:ListBox sau ComboBox asociate unei coloane dintr-un DataTable sau un DataGridasociat unui DataTable sau chiar unui DataSet.

Crearea unui control simplu legat

Prin intermediul proprietatii DataBindings. Aceasta este o instanta a claseiControlBindingsCollection care gestioneaza controalele legate la surse de date. Pentruun anumit control, in fereastra Properties se poate expanda nodul din dreptulproprietatii DataBindings si selecta un anumit data provider.

Legare la executie

Scenarii:

- modificarea unei surse de date pentru un control legat

- identificarea sursei de date a unui control legat

- legarea unui control la un array sau colectie care este instantiata la run time

Exemplu:

// legarea unei etichete la coloana StudentID

// din tabela Students

LabelID.DataBindings.Add("Text", DataSet1.Students,"StudentID");

// Text este proprietatea care va fi legata

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 117 of 203

Page 118: Aplicatii in Visual.net

Exemplu 2:

String[] studenti = new String[3];

studenti[0] = "Aionesei";

studenti[1] = "Agafitei";

studenti[2] = "Georgescu";

TextBox1.DataBindings.Add("Text", studenti, "");

// al treilea parametru este vid, sursa de date

// nu este complexa, nu are membri

Eliminarea unei legaturi:

Label1.DataBindings.Remove(Label1.DataBindings["Text"]);

// se elimina legatura existenta pentru proprietatea

// Text a etichetei Label1

Eliminarea tuturor legaturilor asociate unui control - prin apelarea metodei Clear:

Label1.DataBindings.Clear();

Navigare (Data Currency)

Fiecare forma gestioneaza obiecte CurrencyManager asociate surselor de date prinintermediul unui obiect central BindingContext. Accesarea unui anumit currencymanager se face prin intermediul proprietatii BindingContext, specificand sursa de datea obiectului in cauza. De exemplu:

this.BindingContext[DataSet1.Students];

Inregistrarea curenta poate fi setata prin intermediul proprietatii Position a unuiBindingContext:

// tabela Studenti face parte din DataSet1

// setarea inregistrarii curente la prima

// inregistrare din sursa de date

this.BindingContext[DataSet1.Studenti].Position = 0;

// setarea inregistrarii curente la a

//treia inregistrare din sursa de date

this.BindingContext[DataSet1.Studenti].Position = 2;

// avansarea la urmatoarea inregistrare

this.BindingContext[DataSet1.Studenti].Position ++;

Navigarea prin colectia de date dintr-o forma Windows

Se seteaza proprietatea Position a membrului BindingContext dorit.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 118 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 119: Aplicatii in Visual.net

Este imposibila deplasarea inaintea primei inregistrari sau dupa ultima inregistrare.Exemplu: utilizarea evenimentului PositionChanged din cadrul clasei CurrencyManagerpentru dezactivarea butoanelor de navigare atunci cand linia curenta este pozitionatape prima sau ultima inregistrare.

// handler

public void OnPositionChanged(object sender, System.EventArgs e)

{

if (this.BindingContext[DataSet1.Students].Position == 0)

// dezactivarea butonului Back

BackButton.Enabled = false;

else

// activare

BackButton.Enabled = true;

// similar pentru butonul Forward

}

// linia de adaugat in constructorul formei

this.BindingContext[DataSet1.Customers].PositionChanged += new

EventHandler(this.OnPositionChanged);

Legare complexa

Prin setarea proprietatii DataSource:

DataGrid1.DataSource = DataSet1.Students;

Proprietatea DisplayMember desemneaza numele coloanei la care se leaga controlul.Exemplu:

ComboBox1.DataSource = DataSet1.Students;

ComboBox1.DisplayMember = "StudentID";

Filtrarea si sortarea datelor

DataView permite lucrul cu un subset al datelor continute intr-un DataTable. Aceastaclasa contine metode pentru sortarea si filtrarea datelor, permitand si modificareaobiectului DataTable pe care il reprezinta.

Crearea unui DataView

Se specifica obiectul DataTable care va fi filtrat. Exemplu:

DataView aDataView = new DataView(aDataTable);

Alternativa:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 119 of 203

Page 120: Aplicatii in Visual.net

DataView anotherDataView = new DataView();

anotherDataView.Table = anotherDataTable;

Un DataView poate fi creat utilizand Toolbox-ul.

Filtrare si sortare in DataSet

Exemple: sortare dupa una sau mai multe coloane.

aDataView.Sort = "StudentID";

anotherDataView.Sort = "Prenume, Nume";

Filtrare: prin setarea proprietatii RowFilter. Se specifica un string care reprezinta oexpresie prin care se selecteaza inregistrari. Exemplu:

aDataView.RowFilter = "Nume = 'Popescu'";

In general, expresiile RowFilter urmeaza sintaxa SQL.

Proprietatea DataView.RowState permite filtrarea obiectelor DataRow in functie destarea lor. Valori posibile ale acestei proprietati (se poate seta la una sau mai multe dinaceste valori):

- Unchanged

- Added

- Deleted

- OriginalRows

- CurrentRows

- ModifiedCurrent

- ModifiedOriginal

Editarea datelor folosind un DataView

Proprietati care stabilesc daca datele dintr-un DataView pot fi editate.

- AllowDelete - se permite sau nu stergerea

- AllowEdit - se permite sau nu editarea

- AllowNew - se permite sau nu adaugarea de noi linii

Clasa DataViewManager

O instanta a acestei clase este asociata cu un DataSet, gestionand obiecte DataViewpentru diverse tabele. Exemplu:

DataViewManager aDataViewManager = newDataViewManager(aDataSet);

DataViewManager anotherDataViewManager = new DataViewManager();

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 120 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 121: Aplicatii in Visual.net

anotherDataViewManager.DataSet = anotherDataSet;

Colectia DataViewSettings contine proprietatile DataView asociate tabelelor dintr-unDataSet. Exemplu:

aDataViewManager.DataViewSettings["Students"].RowFilter =

"Prenume = 'Costel'";

Sinteza:

- data binding

- data provider

- data consumer

- CurrencyManager

- DataView

- RowFilter si Sort

- DataViewManager

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 121 of 203

Page 122: Aplicatii in Visual.net

Section 8. GDI+. Controale utilizator. Atribute - VII

1. GDI+

Interfetele grafice sunt entitati frecvent intalnite in lumea utilizatorilor. Desi exista foartemulti adepti ai interfetelor text, cu siguranta nimeni nu va ezita sa foloseasca o interfatagrafica prietenoasa, cu ajutorul careia sa interactioneze cu usurinta cu aplicatia care opune la dispozitie. Microsoft Windows este, in principiu, o interfata grafica. Utilizatoriiinteractioneaza cu aplicatiile prin intermediul ferestrelor, care sunt reprezentari graficeale optiunilor si datelor din cadrul aplicatiilor. Pentru o utilizare facila, aplicatiile trebuiesa isi expuna functionalitatea prin intermediul interfetei grafice. Desi .NET Frameworkpune la dispozitie un set complex de controale grafice, apare adesea necesitateavizualizarii propriului continut grafic si crearii unui aspect personalizat pentru un anumitcontrol. Toate acestea implica utilizarea Graphic Device Interface (GDI). In .NETFramework, aceasta interfata este gestionata prin intermediul GDI+. Clasele .NETFramework care expun functionalitatea GDI+ sunt incluse in spatiul de numeSystem.Drawing si in spatiile de nume asociate.

GDI+ este o implementare managed a GDI, utilizata pentru vizualizarea informatiilorgraphice pe ecranul computerului. Aceasta interfata utilizeaza clase divizate in sasespatii de nume, pe baza functionalitatii.

Spatii de nume System.Drawing

Spatiu de nume Continut

System.Drawing O mare parte din clasele implicate in randarea continutului grafic peecran. Este principalul spatiu de nume utilizat in programarea grafica.

System.Drawing.Design Clase care expun functionalitati aditionale pentru operatiile grafice.

System.Drawing.Drawing2D Clase care transpun efecte vizuale avansate.

System.Drawing.Imaging Clase care permit manipularea avansata a fisierelor imagine.

System.Drawing.Printing Clase care faciliteaza printarea continuturilor textuale sau grafice.

System.Drawing.Text Clase care faciliteaza manipularea avansata a fonturilor.

Majoritatea claselor care faciliteaza randarea grafica sunt incluse in spatiul de numeSystem.Drawing. Pentru randare avansata, se utilizeaza clase din spatiul de numeSystem.Drawing.2D, iar pentru implementarea unor functionalitati de printare, clase dinSystem.Drawing.Printing.

Clasa Graphics

Clasa Graphics, localizata in spatiul de nume System.Drawing, este principala clasautilizata pentru randare grafica. Un obiect Graphics reprezinta suprafata grafica a unuielement vizual, cum ar fi o forma, un control sau un obiect Image. Deci, o forma areasociat un obiect Graphics utilizat pentru a desena in interiorul formei; un control areasociat un obiect Graphics folosit pentru a desena in interiorul controlului, s.a.m.d.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 122 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 123: Aplicatii in Visual.net

Obiectul Graphics este, deci, responsabil de randarea elementelor vizuale.

Deoarece fiecare obiect Graphics trebuie asociat cu un element vizual, nu se poateefectua o instantiere directa a acestuia. In schimb, un obiect Graphics se creaza directpornind de la elementul vizual respectiv. Clasele derivate din Control (incluzand Form)expun o metoda CreateGraphics care permite preluarea unei referinte a obiectuluiGraphics asociat controlului.

Urmatorul exemplu demonstreaza crearea unui obiect Graphics pentru o forma aForm:

System.Drawing.Graphics firstGraphics;

firstGraphics = aForm.CreateGraphics();

Obiectul Graphics astfel creat poate fi ulterior utilizat pentru vizualizarea elementelorgrafice pe forma.

In cazul imaginilor, se poate utiliza metoda statica Graphics.FromImage pentru a creaun obiect Graphics asociat unui obiect particular Image. Obiectul Image poate fi oriceobiect derivat din clasa Image, de exmplu, Bitmap. Exemplu: crearea unui obiectBitmap utilizand un fisier existent si apoi asocierea unui obiect Graphics:

Bitmap aImage = new Bitmap("C:\\someImage.bmp");

System.Drawing.Graphics secondGraphics;

secondGraphics = Graphics.FromImage(aImage);

!

Imaginea nu trebuie sa fie vizibila pentru a se putea crea obiectul Graphics asociat saupentru a il putea manipula.

Coordonate

Randarea se efectueaza pe ecran in regiunea determinata de marginile controlului.Acesta regiune este masurata in coordonate bidimensionale, constand in valori (x, y).Implicit, originea coordonatelor sistemului pentru fiecare control este data de coltul dinstanga sus, care are coordonatele (0,0). Coordonatele sunt masurate in pixeli. Spatiulde nume System.Drawing contine o varietatea de structuri utilizate pentru a descrielocatii sau regiuni din acdrul sistemului de coordonate. Tabelul urmator sumarizeazaaceste structuri:

Structura Descriere

Point un punct reprezentat prin doua valori Integer (int), x si y

PointF un punct reprezentat prin doua valori Single (float), x si y

Size o suprafata rectangulara specificata printr-o pereche de intregi Heightsi Width

SizeF o suprafata rectangulara specificata printr-o pereche de valori Single(float), reprezentand Height si Width

Rectangle o reprezentare a unei regiuni rectangulare prin patru valori intregi Top,Bottom, Left si Right

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 123 of 203

Page 124: Aplicatii in Visual.net

RectangleF o reprezentare a unei regiuni rectangulare prin patru valori flotanteTop, Bottom, Left si Right

Exemplu:

// conversie de la o structura punct reprezentata

// prin valori float la un punct

// reprezentat prin intregi

Point aPoint;

PointF aPointF = new PointF(10.9F,31.23F);

aPoint = new Point((int)aPointF.X, (int)aPointF.Y);

Exemplu:

crearea unei structuri Rectangle prin specificarea unui structuri Size si a unei structuriPoint:

Point pointOrigin = new Point(100, 50);

Size aSize = new Size(40, 50);

// se creaza un Rectangle 40 pe 50 avand

// coltul din stanga sus specificat de Point(100,50)

Rectangle aRectangle = new Rectangle(pointOrigin, aSize);

Desenarea formelor

Orice obiect Graphics incapsuleaza o varietate de metode pentru randarea formelorsimple si complexe pe ecran. Acestea sunt incadrate in doua categorii generale:

- metode de tip Draw - linii, arce, contururi ale formelor;

- metode de tip Fill - forme solide - dreptunghiuri, elipse sau poligoane

Metode pentru desenarea structurilor bazate pe linii:

Metoda Descriere

DrawArc deseneaza un arc reprezentand o portiune a unei elipse

DrawBezier deseneaza o curba Bezier

DrawBeziers deseneaza o serie de curbe Bezier

DrawClosedCurve deseneaza o curba inchisa pe baza unei serii de puncte

DrawCurve deseneaza o curba deschisa pe baza unei serii de puncte

DrawEllipse deseneaza o elipsa pe baza unui dreptunghi

DrawLine deseneaza o linie conectata prin doua puncte

DrawLines deseneaza o serie de linii pe baza unui tablou de puncte

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 124 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 125: Aplicatii in Visual.net

DrawPath deseneaza un obiect GraphicsPath care reprezinta o formacomplexa

DrawPie deseneaza o forma de tip pie ca sector de elipsa

DrawPolygon deseneaza un poligon pe baza unei serii de puncte

DrawRectangle deseneaza un dreptunghi

DrawRectangles deseneaza o serie de dreptunghiuri

Metode pentru desenarea formelor solide:

Metoda Descriere

FillClosedCurve deseneaza o curba inchisa specificata printr-un tablou depuncte

FillEllipse deseneaza o elipsa plina

FillPath reda un obiect solid GraphicsPath reprezentand o formacomplexa

FillPie deseneaza o forma pie solida

FillPolygon reda un poligon solid specificat printr-un tablou de puncte

FillRectangle deseneaza un dreptunghi solid

FillRectangles o serie de dreptunghiuri solide

FillRegion umple un obiect Region care corespunde de obicei uneiforme complexe

Fiecare dintre aceste metode primesc diversi parametri care specifica coordonatelepunctelor si locatia formelor care se vor desena. Fiecare metoda necesita un obiectcare sa efectueze randarea. Pentru structuri liniare, se utilizeaza un obiect Pen. Pentruforme solide, se folosesc obiecte Brush.

Color, Brush si Pen

Aceste tipuri sunt utilizate pentru a determina modul de randare a unei imagini grafice.Obiectele Pen redau linii si arce, obiectele Brush redau forme solide, iar obiectele detip Color definesc culorile folosite in vizualizare.

Color

Structura Color reprezinta o singura culoare si se gaseste in spatiul de numeSystem.Drawing. Culorile individuale sunt derivate din patru valori: Alpha - gradul detransparenta, Red, Green si Blue, cuprinse intre 0 to 255. O noua culoare se poatecrea folosind metoda Color.FromArgb:

Color aColor;

aColor = Color.FromArgb(128, 255, 12, 50);

Pentru culori opace, parametrul Alpha se omite:

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 125 of 203

Page 126: Aplicatii in Visual.net

Color aColor;

aColor = Color.FromArgb(255, 12, 43);

Exista un set de culori definite in .NET Framework. Exemplu:

Color aColor;

aColor = Color.Tomato;

Brush

Obiectele Brush sunt sunt folosite pentru randarea formelor solide. Toate acesteobiecte sunt derivate din clasa abstracta de baza Brush si furnizeaza implementaridiferite ale obiectelor utilizate pentru randarea obiectelor solide, in diferite stiluri.

Tipuri de obiecte Brush:

Tip Spatiu de nume Descriere

SolidBrush System.Drawing o singura culoare solida

TextureBrush System.Drawing umple obiecte inchise cu oimagine

HatchBrush System.Drawing.Drawing2D hasureaza interiorulobiectelor

LinearGradientBrush System.Drawing.Drawing2D combina doua culori pe bazaunui gradient

PathGradientBrush System.Drawing.Drawing2D randarea de efecte vizualecomplexe

Crearea unui SolidBrush:

SolidBrush sBrush = new SolidBrush(Color.PapayaWhip);

Constructorii altor tipuri de obiecte brush necesita parametri aditionali.

Pen

Obiectele de acest tip sunt utilizate pentru a desena linii si arce, putand fi utilizatepentru aplicarea unei varietati de efecet speciale structurilor bazate pe linii. Clasa Pennu poate fi mostenita direct. Exemplu de creare a unui obiect Pen:

Pen aPen = new Pen(Color.BlanchedAlmond);

Grosimea implicita este 1. O alta grosime poate fi specificata prin intermediulconstructorului, ca in exemplul urmator:

Pen aPen = new Pen(Color.Red, 5);

Crearea unui pen pe baza unui obiect brush existent:

Pen aPen = new Pen(aBrush);

Anumite aplicatii trebuie sa aiba interfete grafice care sa aiba aceleasi caracteristici ca

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 126 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 127: Aplicatii in Visual.net

si interfata sistemului pe care va rula aplicatia. .NET Framework pune la dispozitieculori specifice sistemului prin intermediul clasei SystemColors. Aceasta clasa contineun set de membri statici care contini culorile utilizate de sistem. Deci, se pot definielemente ale interfetei utilizator care sa foloseasca culori preluate la executie din setulde culori puse la dispozitie de sistemul pe care ruleaza aplicatia. Exemplu:

Color aColor = SystemColors.HighlightText;

Similar, exista clasele SystemPens si SystemBrushes.

Randarea formelor simple

Toate metodele care redau forme simple, bazate pe linii, necesita un obiect valid de tipPen. Metodele specializate in vizualizarea formelor solide au ca parametru un obiectBrush. Exemplu:

// un obiect Rectangle

Rectangle aRectangle = new Rectangle(0, 0, 30, 50);

// crearea obiectului Graphics asociat formei

Graphics g = this.CreateGraphics();

g.DrawRectangle(SystemPens.ControlDark, aRectangle);

// dealocarea obiectului Graphics

g.Dispose();

Exemplu 2:

SolidBrush aBrush = new SolidBrush(Color.MintCream);

Graphics g = this.CreateGraphics();

// o elipsa care va fi inscrisa intr-un dreptunghi

Rectangle aRectangle = new Rectangle(0, 0, 50, 20);

g.FillEllipse(aBrush, aRectangle);

g.Dispose();

aBrush.Dispose();

!

Este indicata apelarea metodei Dispose pentru obiectele Graphics, deoarece acesteasunt mari consumatoare de resurse.

Vizualizarea textelor

Se utilizeaza metoda DrawString a obiectelor Graphics, care vizualizeaza un stringreprezentand un text pe ecran. Textul este vizualizat folosit un font specificat si esteredat printr-un obiect Brush. Trebuie specificate, de asemenea, coordonatele la care seva face afisarea. Exemplu:

Graphics g = this.CreateGraphics();

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 127 of 203

Page 128: Aplicatii in Visual.net

String aString = "Salut, anul 4!";

Font aFont = new Font("Times New Roman", 40, FontStyle.Regular);

g.DrawString(aString, aFont, SystemBrushes.Highlight, 20, 30);

g.Dispose();

Vizualizarea formelor complexe

Vizualizarea formelor complexe necesita parcurgerea catorva pasi in proiectare.Principalul obiect utilizat pentru randarea formelor complexe este o instanta a claseiGraphicsPath. Membru al spatiului de nume System.Drawing.Drawing2D, clasaGraphicsPath poate descrie orice fel de obiecte inchise sau multimi de formecomplexe.

Crearea unui GraphicsPath

Se utilizeaza unul din constructorii clasei GraphicsPath. Exemplu 1: constructorul faraparametru.

GraphicsPath aPath = new Drawing2D.GraphicsPath();

Exemplul 2: constructor cu parametri care specifica un set de puncte din cadrul formeisi caracteristicile anumitor sectiuni ale formei:

GraphicsPath aPath = new GraphicsPath(new Point[]

{new Point(1, 1), new Point(38, 70), new Point(33, 20)}, newbyte[] {

(byte)PathPointType.Start, (byte)PathPointType.Line,

(byte)PathPointType.Bezier});

Dupa creare, se pot adauga figuri obiectului GraphicsPath. O astfel de figura reprezintao forma inchisa - forme simple (elipse, dreptunghiuri) sau complexe (curbe neregulates.a.).

Clasa GraphicsPath contine mai multe metode care permit adaugarea de figuri laobiectul respectiv. Aceste metode sunt sintetizate in tabelul urmator:

Metoda Descriere

AddClosedCurve adauga o curba inchisa descrisa printr-un tablou de puncte

AddEllipse adauga o elipsa

AddPath adauga o instanta GraphicsPath la instanta curenta

AddPie adauga o forma de tip pie

AddPolygon adauga un poligon descris printr-un tablou de puncte

AddRectangle adauga un dreptunghi

AddRectangles adauga o multime de dreptunghiuri

AddString adauga o reprezentare grafica a unui string, cu un fontspecificat

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 128 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 129: Aplicatii in Visual.net

O figura poate fi creata si pas cu pas, prin adaugare de linii, arce si curbe (se utilizeazametodele din tabelul de mai jos). Primul pas in crearea figurii este aplearea metodeiGraphicsPath.StartFigure. Se adauga apoi elemente la figura respectiva, apelandu-se,in final, metoda GraphicsPath.CloseFigure pentru inchiderea figurii. Exemplu:

GraphicsPath somePath = new GraphicsPath();

somePath.StartFigure();

// adaugare de elemente ...

somePath.CloseFigure();

O figura pentru care s-a apelat StartFigure, fara a se apela CloseFigure, va ramanedeschisa.

!

La run-time, o figura deschisa se va inchide prin adaugarea unei linii intre primul siultimul punct ale figurii.

Metode GraphicsPath pentru adaugarea de elemente liniare la o figura:

Metoda Descriere

AddArc adauga un arc

AddBezier adauga o curba Bezier

AddBeziers adauga o serie de curbe Bezier

AddCurve adauga o curba descrisa de un tablou de puncte

AddLine adauga o linie

AddLines adauga o serie de linii conectate

Sinteza

- Graphics

- Pen, Brush, Color

- SystemPens, SystemBrushes, SystemColors

- GraphicsPath

2. Controale utilizator

Programarea Windows Forms este bazata pe controale. Controalele permitincapsularea unui set de unitati functionale discrete si furnizeaza utilizatorului oreprezentare grafica a acestor functionalitati. .NET Framework pune la dispozitie ovarietate de unelte si tehnici care ajuta la crearea controalelor personalizate din cadrulaplicatiei utilizator.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 129 of 203

Page 130: Aplicatii in Visual.net

In .NET Framework, controale sunt clase specializate care includ cod pentru randareaunei interfete grafice. Exista mai multe surse posibile pentru controalele utilizate inaplicatii. Controalele incluse in Microsoft Visual Studio .NET acopera o gama larga defunctionalitati si permit dezvoltarea de aplicatii cu o serie intreaga de caracteristici. Potfi utilizate, de asemenea, o serie de controale implementate de alti programatori saupot fi folosite controale ActiveX.

Controale personalizate - privire de ansamblu

Toate controalele din .NET Framework sunt derivate direct sau indirect din clasa debaza Control. Acesta clasa pune la dispozitie functionalitatea de baza necesara unuicontrol. De exemplu, clasa Control implementeaza logica tratarii input-ului utilizatoruluiprin interactiunea cu tastatura si mouse-ul si logica interactiunii cu mediul Windows. Inplus, un control derivat din clasa Control contine un set de proprietati, metode sievenimente comune tuturor controalelor. Crearea functionalitatii specifice controlului,precum si vizualizarea grafica a acestuia sunt sarcini ce revin utilizatorului.

Exista trei tehnici de baza pentru crearea unui control:

- derivarea dintr-un control existent :

reprezinta cel mai rapid si facil mod de dezvoltare a unui control; noul control continetoata functionalitatea controlului de baza si poate actiona ca baza pentru alte controale,mostenind reprezentarea vizuala a controlului din care de deriveaza. Aceasta tehnicaeste folosita atunci cand este necesara duplicarea functionalitatii unui control WindowsForms si adaugarea de functionalitati specifice sau definirea unui aspect vizual nou.Majoritatea controalelor Windows Forms pot fi utilizate drept clase de baza pentrucrearea de controale noi. Exemplu: crearea unui TextBox cu validare implicita(functionalitate specifica) sau crearea unui Button cu colturile rotunjite (aspect vizualspecific).

- derivarea din clasa UserControl:

tehnica utilizata pentru crearea de controle care inglobeaza un numar de controaleWindows Form sub forma unei singure unitati functionale. Se deriveaza din clasaUserControl care pune la dispozitie o functionalitate de baza, la care se pot adaugaproprietati, metode, evenimente si alte controale. Dupa adaugarea controalelorcomponente, se scrie cod pentru implementarea functionalitatilor specifice. Rezultatuleste un control proiectat de utilizator, alcatuit dintr-un set de controale care secomporta ca o singura unitate functionala. Majoritatea modificarilor vizuale adusecontroalelor componente constau in simpla configurare si repozitionare a controalelorconstituente.

- derivarea din clasa Control:

utilizata in cazul in care este necesara o interfata vizuala sau/si o functionalitatecomplexa care nu pot fi implementate prin intermediul unui user-control sau a unuicontrol derivat. Controalele personalizate sunt derivate din clasa Control, clasa de bazaa tuturor controalelor. Pasii necesari dezvoltarii unuii astfel de control pot ficonsumatori de timp, oferind insa posibilitatea implementarii unui control personalizat,cu functionalitate si aspect vizual specifice.

Adaugarea de membri unui control

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 130 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 131: Aplicatii in Visual.net

Se pot adauga proprietati, metode, campuri si evenimente controalelor in aceeasimaniera in care se adauga membri unei clase. Pot fi declarati membri cu diverse nivelede acces, iar forma care gazduieste controlul va putea apela orice membru public alcontrolului.

Proprietatile publice adaugate controalelor sunt vizualizate automat in fereastraProperties la design-time. Deci, acestea pot fi editate si configurate de orice utilizator alaplicatiei. Daca nu se doreste vizualizarea unei proprietati in fereastra Properties, seseteaza atributul Browsable la false. Exemplu:

[System.ComponentModel.Browsable(false)]

public int CustomNumber

{

// cod...

}

Crearea unui control derivat

Un control derivat contine toata functionalitatea pusa la dispozitie de clasa de baza sipoate servi, de asemenea, ca baza pentru alte controale. Un control derivat se creazaspecificand un control Windows Forms drept clasa de baza pentru noul control. Acestapastreaza acelasi aspect si functionalitate ca si controlul de baza. Exemplu:

public class DerivedButton : System.Windows.Forms.Button

{

// implementare...

}

Adaugarea de noi functionalitati unui control derivat

Acest lucru se poate realiza prin suprascrierea membrilor clasei de baza. De exemplu,pentru crearea unui text box care accepta numai numere ca input, se suprascriemetoda OnKeyPress, ca in exemplul urmator:

// nu se permite transmiterea focusului unui alt

// control daca se introduc alte caractere

// decat cifre in textBox

public class NumberBox :

System.Windows.Forms.TextBox

{

protected override void OnKeyPress(KeyPressEventArgs e)

{

if (char.IsNumber(e.KeyChar) == false)

e.Handled = true;

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 131 of 203

Page 132: Aplicatii in Visual.net

}

}

Modificarea aspectului vizual al unui control

Se suprascrie motoda OnPaint. Pentru modificarea formei unui control, se seteazaproprietatea Region a controlului in metoda OnPaint. Region este o clasa care descrieo regiune regulata sau neregulata de pe ecran, similar unui GraphicsPath. O regiunepoate fi creata pe baza unui GraphicsPath. Exemplu - un buton care este vizualizat subforma unui string:

public class TextButton :

System.Windows.Forms.Button

{

protected override void OnPaint(PaintEventArgs pe)

{

System.Drawing.Drawing2D.GraphicsPath aPath = new

System.Drawing.Drawing2D.GraphicsPath();

aPath.AddString("Cool", Font.FontFamily,

(int)Font.Style, 72, new PointF(0, 0),StringFormat.GenericDefault);

// se creaza o noua regiune pornind de la aPath

Region aRegion = new Region(aPath);

// se asigneaza regiunea proprietatii Region a controlului

this.Region = aRegion;

}

}

!

- butonul astfel creat nu este rectangular, ci are forma determinata de literelecuvantului "Cool". Pentru a executa clic pe buton, trebuie utilizata regiunea determinatade literele acestui cuvant;

- exista controale pentru care nu se lanseaza evenimentul Paint, fiind desenate deforma parinte.

Crearea unui user-control

Un astfel de control consta in unul sau mai multe controale legate sub forma uneisingure unitati. Controalele componente pot fi adaugate controlului utilizator ladesign-time. Un control utilizator poate fi adaugat la proiect utilizand optiunea Add UserControl din meniul Project.

Exemplu, crearea unui control utilizator format din doua TextBox-uri si un Label care

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 132 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 133: Aplicatii in Visual.net

afiseaza automat suma celor doua numere introduse in TextBox-uri. Pentru aceasta,se suprascrie metoda OnKeyPress pentru fiecare TextBox:

protected override void OnKeyPress(object sender,KeyPressEventArgs e)

{

// se verifica daca s-a tastat o cifra

if (char.IsNumber(e.KeyChar) == false)

e.Handled = true;

Label1.Text = (int.Parse(TextBox1.Text) +

int.Parse(TextBox2.Text)).ToString();

}

La crearea unui control utilizator in Visual Studio .NET, controalele constituente sunttratate implicit ca private. Pentru a permite altor utilizatori sa modifice proprietatilecontroalelor constitutive, acestea trebuie expuse prin intermediul proprietatilorcontrolului utilizator parinte. Exemplu:

public Color ButtonColor

// proprietate a controlului parinte

// Button1 este un constituent al acestuia

{

get

{

return Button1.BackColor;

}

set

{

Button1.BackColor = value;

}

}

Expunerea completa a unui control constituent se poate efectua prin intermediulproprietatii Modifiers, disponibila in fereastra Properties, numai in faza de design.

Crearea unui control custom

Controalele de acest tip confera cel mai inalt nivel de configurabilitate si personalizare,dar sunt si cele mai consumatoare de timp in faza de dezvoltare. Deoarece clasaControl nu furnizeaza o reprezentare vizuala, utilizatorul are sarcina de a scrie codcare sa redea vizualizarea grafica a controlului. In cazurile in care este necesara oreprezentare vizuala complexa, aceasta faza poate ocupa cea mei mare perioada de

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 133 of 203

Page 134: Aplicatii in Visual.net

timp in procesul de dezvoltare a controlului.

Procesul vizualizarii unui control pe o suprafata se numeste painting. Atunci cand uncontrol primeste instructiuni de desenare, se lanseaza evenimentul Paint. Aceastadetermina executia handlerelor evenimentului Paint. Pentru clasa Control, handlerulimplicit al evenimentului Paint este metoda OnPaint.

Metoda OnPaint are un singur argument, o instanta PaintEventArgs. Acesta clasacontine informatii despre suprafata de desenare disponibila controlului.

Membri PaintEventArgs:

- Graphics - un obiect Graphics care reprezinta suprafata de desenare a controlului

- ClipRectangle - o suprafata rectangulara disponibila controlului pentru desenare. Laprima desenare a controlului, obiectul ClipRectangle defineste marginile intreguluicontrol. Uneori, anumite regiuni ale controlului pot fi acoperite de alte controale. Laredesenarea controlului, obiectul ClipRectangle reprezinta numai regiunea care trebuieredesenata, fiind folosit, deci, pentru determinarea marimii controlului. Coordonatele, ininteriorul unui control, sunt masurate relativ la coltul din stanga sus, considerat dreptorigine. Exemplu de custom-control:

// o elipsa

protected override void OnPaint(PaintEventArgs e)

{

Brush aBrush = new SolidBrush(Color.Red);

Rectangle clientRectangle = new

Rectangle(new Point(0,0), this.Size);

e.Graphics.FillEllipse(aBrush, clientRectangle);

}

La redimensionarea unui control, membrul ClipRectangle este modificat, dar controlulnu este neaparat redesenat. Pentru redesenarea controlului la fiecare redimensionare,se apeleaza metoda Control.SetStyle pentru a seta flagul ResizeRedraw la true. Acestapel trebuie plasat in constructor. Exemplu:

SetStyle(ControlStyles.ResizeRedraw, true);

Ca alternativa, se poate apela metoda Refresh, ori de cate ori se doreste redesenarea:

Refresh();

Sinteza:

- controale derivate (derived controls)

- controale utilizator (user controls)

- controale personalizate (custom controls)

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 134 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 135: Aplicatii in Visual.net

3. Gestionarea, utilizarea, configurarea controalelor

Adaugarea controalelor la Toolbox

Dupa crearea unui control, acesta va putea fi utilizat in proiecte de dezvoltare.Adaugarea unui control in Toolbox va permite utilizarea acestuia in proiecte.

Adaugarea unui control la Toolbox se face prin intermediul optiunii Customize Toolbox.(.NET Framework Controls, Browse, se alege fisierul DLL sau EXE asociat controlului).Controlul este, in urma selectarii fisierului asociat, adaugat in lista afisata de optiuneaCustomize Toolbox. Controlul este adaugat astfel la Toolbox.

In Visual Studio .NET 2003, controalele utilizator construite ca parte a unui proiect suntadaugate automat in Toolbox, in lista de controale My UserControls. Pot fi adaugate sicontroale derivate sau controale custom folosind procedura de mai sus.

Asocierea unui Toolbox Bitmap unui control

Visual Studio .NET asociaza un icon implicit care apare in dreptul controlului inToolbox. Se poate specifica un icon dorit, in format bitmap. Pentru aceasta seutilizeaza clasa ToolboxBitmapAttribute. Acasta este o clasa specializata bazata peatribute, o clasa care contine metadate despre un control. FolosindToolboxBitmapAttribute, se poate specifica fie un bitmap de dimensiune 16 pe 16, fietype. Daca se specifica type, controlul va avea asociat acelasi bitmap ca si controlul.NET avand acel tip (type) specificat.

Exemple care ilustreaza cele doua situatii:

// icon specificat printr-un fisier bitmap

[ToolboxBitmap(@"C:\some.bmp")]

public class SomeUserControl : Control

{

// implementare...

}

[ToolboxBitmap(typeof(Label))]

public class UserLabelControl : Label

{

// implementare...

}

Debugging-ul unui control

In orice proiect de dezvoltare, poate aparea necesitatea debugging-ului controalelor.Deoarece acestea nu sunt proiecte de sine statatoare, ele trebuie gazduite in cadrulunei forme Windows pe durata debugging-ului.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 135 of 203

Page 136: Aplicatii in Visual.net

Controlul trebuie construit (built) inainte de a putea fi testat. Odata ce proiectul carecontine controlul a fost construit, controlul poate fi adaugat la o forma si testat ca incazul oricarui alt proiect.

In cazul in care controlul face parte dintr-un proiect executabil, precum un proiectWindows Forms, se poate adauga o noua forma la proiect care sa gazduiascacontrolul. In cazul in care controlul face parte dintr-un proiect non-executabil, cum ar fio librarie de clase sau un control Windows, trebuie creat un proiect aditional pentru aputea testa controlul (se adauga proiectul continand controlul ca referinta a nouluiproiect creat - Solution Explorer - References - Add Reference ).

Gazduirea unui control in Internet Explorer

Orice control Windows Forms poate fi incarcat in Internet Explorer; pentru a profita deaceasta posibilitate, se creaza pagini HTML care contin controale Windows Forms.

Pentru a putea incarca un control in Internet Explorer, acesta trebuie instalat in GlobalAssembly Cache (vezi cursul 10...) sau trebuie plasat in acelasi director virtual in carese gaseste pagina HTML care utilizeaza controlul.

Adaugarea unui control Windows Forms intr-o pagina HTML se efectueaza utilizandtagul <OBJECT>. Acest tag specifica faptul ca un obiect compilat va fi inserat inpagina. Tagul <OBJECT> examineaza proprietatea classid a obiectului pentru aidentifica tipul obiectului care va fi incarcat. Deci, in proprietatea classid se va specificapropriul control Windows Forms.

classid-ul unui control Windows Forms consta in doua parti. Prima parte este caleacatre fisierul care contine controlul, cea de-a doua este numele complet al controlului.Separarea celor doua parti se face utilizand caracterul #. Exemplu: utilizarea tagului<OBJECT> pentru un control din fisierul ControlLibraryExample.dll (aflat in acelasidirector ca si pagina HTML) avand numele ControlLibraryExample.firstControl:

<OBJECT id="firstControl"

classid="http:ControlLibraryExample.dll#ControlLibraryExample.firstControl

VIEWASTEXT>

</OBJECT>

Sinteza

- adaugarea controalelor utilizator la Toolbox prin intermediul optiunii CustomizeToolbox

- asocierea unui bitmap controalelor utilizand clasa ToolboxBitmapAttribute

- debugging-ul controalelor

- incarcarea controalelor in Internet Explorer utilizand tagul <OBJECT>

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 136 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 137: Aplicatii in Visual.net

4. Atribute

Atributele sunt entitati din program utilizate pentru a asocia informatii, cum ar fiadnotari, tipurilor C# definite de utilizator. Aceste informatii sunt arbitrare, adica nu suntdependente de limbaj in sine, utilizatorul avand libertatea de a crea si asocia informatiide orice tip.

Utilizari:

- furnizarea de informatii la design-time (documentatii)

- furnizarea de informatii la run-time (de exemplu numele unei coloane dintr-o tabela)

- stabilirea de comportamente la run-time (stabilirea caracteristicilor unei entitati dinprogram, configurari etc)

Definirea atributelor

Un atribut este, de fapt, o clasa derivata din clasa System.Attribute.

Exemplu:

public class FirstAttribute: Attribute

{

public FirstAttribute(string s)

{

// cod...

}

// alte campuri, proprietati, metode...

}

Aplicare:

[First("John")] // lipseste prefixul Attribute

public class Test

{

// clasa Test are asociat atributul First,

cu valoarea "John"

}

Interogarea atributelor

Se utilizeaza mecanismul de Reflection - determinarea dinamica la run-time acaracteristicilor tipurilor dintr-o aplicatie. Exemplu: determinarea listei tuturor claselor,tipurilor si metodelor definite intr-o aplicatie.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 137 of 203

Page 138: Aplicatii in Visual.net

Atribute asociate claselor:

- se asociaza atributul

- interogarea se executa folosind metoda GetCustomAttributes din clasa Type:

...

Type t = typeof(MyAttribClass)

// clasa careia i se aplica atributele

foreach (Attribute attr in t.GetCustomAttributes(true))

// do something

...

Atribute asociate metodelor

- se aplica atributele metodei.

Exemplu:

...

[InputMethod]

public ReadNumbers()

{

...

}

- se interogheaza atributele folosind metoda GetMethods din clasa Type si, apoi,metoda GetCustomAttributes din clasa MethodInfo.

Atribute asociate campurilor

- se aplica atributele campului.

Exemplu:

...

[InputField("Popescu")]

public string nume;

{

...

}

- se interogheaza atributele folosind metoda GetFields din clasa Type si, apoi, metodaGetCustomAttributes din clasa FieldInfo.

Exista, desigur, un set de alte utilizari si aspecte legate de utilizarea atributelor. De

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 138 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 139: Aplicatii in Visual.net

retinut este ca atributele furnizeaza practic facilitati nelimitate, fiind foarte utile in fazade reflection si introspectie a aplicatiei.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 139 of 203

Page 140: Aplicatii in Visual.net

Section 9. Programare folosind fire de executie - VIII

1. Fir de executie - definitie, abordare .NETFramework

Un fir de executie este unitatea minimala (atomul) careia un procesor ii aloca timpi deexecutie. Mecanismul gestionarii firelor de executie este urmatorul:

- procesorul executa un thread atat timp cat mai exista timp alocat;

- dupa scurgerea timpului, firului de executie curent ii este salvat contextul (registri,stiva, etc);

- procesorul restaureaza contextul urmatorului fir de executie (firele de executiesuspendate sunt pastrate intr-o coada)

. Deoarece unitatile de timp alocate fiecarui fir de executie sunt mici (marimea lordepinde de sistemul de operare si de procesor), exista impresia unor executii paralelechiar si pe o masina cu un singur procesor.

Fire de executie

Clasa prin care sunt abstractizate firele de executie .NET esteSystem.Threading.Thread. Aceasta clasa pune la dispozitie metode si proprietatipentru crearea, suspendarea, trezirea sau distrugerea unui fir de executie. Mai mult,sunt permise operatii de control a starii sau de planificare a unui thread.

Un proces poate crea unul sau mai multe fire de executie care sa execute o sectiunedin codul programului asociat procesului. Pentru a specifica codul programului executatde un thread, se utilizeaza un delegat ThreadStart.

Pe durata existentei sale, un thread se gaseste intotdeauna in una sau mai multe dinstarile definite de ThreadState. Object.GetHashCode identifica firele de executiemanaged. Pe durata de viata a unui thread, nu vor exista coliziuni (in sens hash) cualte fire de executie, indiferent de domeniul de aplicatie utilizat pentru a obtine valoareahash.

Application Domain

Un AppDomain este un proces logic in cadrul unui proces fizic. La formarea unuiAppDomain se creaza un fir de executie, dar la un moment dat, in cadrul unuiAppDomain pot exista mai multe fire (derivate in cele din urma din firul initial).

Dintr-un AppDomain pot fi apelate metode sau invocate obiecte care fac parte dintr-unalt AppDomain, spre deosebire de platforma Win32, in care un thread face partedintr-un singur proces si nu poate apela o metoda dintr-un thread din alt proces (veziclasa AppDomain).

Exemplu: vezi resurse, curs 8.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 140 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 141: Aplicatii in Visual.net

2. Mai multe despre clasa Thread

Membri ai clasei Thread

• IsAlive - proprietate, contine o valoare care indica starea executiei firului curent

• IsBackground - proprietate, contine o valoare care indica daca firul se executa saunu in background

• Name - proprietate, contine numele firului de executie

• Priority - proprietate, stabileste prioritatea firului de executie; valorile posibile suntcontinute de enumerarea Thread.Priority

• Priority - proprietate, enumerare cu urmatoarele valori: AboveNormal,BelowNormal, Highest, Lowest, Normal; valoarea implicita este Normal; ordineaplanificarii firelor: Highest, AboveNormal, Normal, BelowNormal, Lowest

• ThreadState - proprietate, enumerare care contine valori indicand starile firului deexecutie curent

• abort - metoda, stopeaza firul de executie, lansand o exceptie ThreadAbortException

• GetDomain - metoda, returneaza o instanta AppDomain, reprezentand domeniulcurent, in care ruleaza firul de executie

• Interrupt - metoda, intrerupe un thread aflat in starea WaitSleepJoin

• Join - metoda, blocheaza firul apelant, pana la terminarea unui alt fir

• Resume - metoda, reia executia unui fir, suspendat anterior

• Sleep - metoda, blocheaza executia firului curent pentru un numar specificat demilisecunde

• Start - metoda, schimba starea firului la valoarea ThreadState.Running

• Suspend - metoda, suspenda firul curent

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 141 of 203

Page 142: Aplicatii in Visual.net

Section 10. .NET Framework Advanced - IX

1. Functionalitati avansate de printare

Printarea (tiparirea) datelor si documentelor constituie o sarcina comuna oricarui mediude dezvoltare de aplicatii complexe. .NET Framework pune la dispozitie componentaPrintDocument pentru a facilita tiparirea si pentru a gazdui alte clase care ofera suportsi posibilitati de configurare a setarilor printerului.

Printarea va fi, fara indoiala, o componenta indispensabila a oricarei aplicatii complexe.Cu toate ca dispozitivele electronice de stocare a datelor se bucura de o popularitatecrescanda, materialele tiparite nu vor putea fi inlocuitere in viitorul apropiat. Deci, oriceprogramator trebuie sa fie capabil sa implementeze propriile functionalitati de tiparire inaplicatiile pe care le dezvolta. .NET Framework ofera clase si componente care permitimplementarea rapida si facila in programe a suportului de printare.

Componenta PrintDocument

Un document care urmeaza si/sau va fi tiparit este reprezentat in .NET Framework princomponenta PrintDocument. Desi aceasta nu are o reprezentare vizuala, ea poate figasita in tabul Windows Forms din Toolbox, de unde poate fi adaugata la aplicatie inmod design.

Un obiect PrintDocument incapsuleaza toata informatia necesara printarii unei pagini.

- proprietatea PrinterSettings contine informatii despre functionalitatea si setarileprinterului;

- proprietatea DefaultPageSettings incapsuleaza configurarile pentru printarea uneipagini;

- proprietatea PrintController descrie modalitatea in care fiecare pagina este gestionatain procesul de printare.

Prin intermediul acestor proprietati, se poate atinge un nivel avansat de control asupraprocesului de printare.

Crearea unui obiect PrintDocument

- in mod design - prin adaugarea unei instance PrintDocument direct din Toolbox

- utilizand scrierea de cod

// using System.Drawing.Printing;

PrintDocument firstPrintDocument = new PrintDocument();

O instanta PrintDocument creata in cod este configurata automat la setarile impliciteale printerului sistemului.

Cum functioneaza printarea?

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 142 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 143: Aplicatii in Visual.net

In modelul de printare .NET Framework, continutul care va fi printat este furnizat directde logica aplicatiei. Un proces de printare este initiat utilizand metodaPrintDocument.Print. Aceasta starteaza procesul si lanseaza unul sau mai multeevenimente PrintPage. Daca nu exista metode client pentru tratarea acestuieveniment, printarea nu va avea loc. Furnizand o metoda care sa trateze evenimentul,se poate specifica continutul care va fi printat.

Daca continutul care va fi printat contine mai multe pagini, se va lansa cate uneveniment PrintPage pentru fiecare pagina din procesul de printare. Acest lucrucauzeaza event-handlerului asociat evenimentului PrintPage sa se execute de maimulte ori. Deci, aceasta metoda trebuie sa implementeze functionalitati care sagestioneze procesul de printare si sa asigure faptul ca sunt printate, succesiv, paginileanumit document. Altfel, prima pagina a documentului va fi printata de mai multe ori.

Evenimentul PrintPage

Evenimentul PrintPage este principalul eveniment implicat in printarea documentelor.Pentru transmiterea efectiva a continutului care va fi printat catre printer, trebuieimplementata o procedura de tratare a acestui eveniment, in cadrul careia sa se scriecod pentru redarea continutului care va fi printat in formatul dorit. Toate obiectele siinformatiile necesare transmiterii continutului catre printer sunt incapsulate in obiectulPrintPageEventArgs, primit ca parametru de event handler. Acest obiect contineproprietatile listate in tabelul urmator:

Proprietate Descriere

Cancel indica daca un proces de printare va fi sau nuanulat

Graphics obiectul Graphics utilizat pentru redareacontinutului paginilor care vor fi printate

HasMorePages gestioneaza o valoare indicand daca vor fiprintate pagini aditionale

MarginBounds returneaza un obiect Rectangle care reprezintaportiunea din pagina obtinuta excluzandmarginile

PageBounds returneaza un obiect Rectangle care reprezintaintreaga suprafata a paginii

PageSettings gestioneaza setarile PageSettings pentrupagina curenta

Continutul care va fi printat este redat prin intermediul obiectului Graphics continut deinstanta PrintPageEventArgs. In acest caz, pagina printata se va comporta ca o forma,ca un control sau ca orice alta suprafata de desenare care poate fi reprezentataprintr-un obiect Graphics. Pentru a reda continutul, se utilizeaza aceleasi metode ca incazul utilizarii formelor. Exemplu, printarea unei elipse:

// acesta metoda va trata evenimentul PrintPage

public void PrintEllipse(object sender,

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 143 of 203

Page 144: Aplicatii in Visual.net

System.Drawing.Printing.PrintPageEventArgs e)

{

e.Graphics.DrawEllipse(Pens.Black, e.MarginBounds);

}

Proprietatile MarginBounds si PageBounds reprezinta dimensiunile care definescsuprafata paginii. Se poate specifica ca printarea sa aiba loc in interiorul limitelorpaginii calculand coordonatele de printare pe baza dreptunghiului definit deMarginBounds. Printarea care se va efectua inafara limitelor marginilor, ca in cazulantetelor sau notelor din subsolul paginilor, poate fi specificata calculand coordonatelede printare pe baza dreptunghiului definit de PageBounds. Similar desenarii pe ecran,coordonatele de printare sunt specificate, implicit, in pixeli.

Se poate specifica faptul ca un proces de printare contine mai multe pagini utilizandproprietatea HasMorePages. Implicit, aceasta proprietate este setata la false. Atuncicand, prin logica programului, se stabileste ca vor fi mai multe pagini de printat incazdrul unui astfel de proces, se seteaza aceasta proprietate la valoarea true. Atuncicand ultima pagina este printata, proprietatea trebuie resetata la false.

!

Metoda care trateaza evenimentul PrintPage trebuie sa tina cont de numarul de paginidin proces, in caz contrar, putandu-se obtine comportamente nedorite ale aplicatiei. Deexemplu, daca se omite resetarea proprietatii HasMorePages la valoarea false dupa ceultima pagina a fost printata, aplicatia va continua sa lanseze evenimente PrintPage.Un proces de printare poate fi oprit, fara a fi necesara terminarea printarii paginiicurente, prin setarea proprietatii Cancel la valoarea true.

Crearea unei metode de tratare a evenimentului PrintPage: prin dublu-clic pe instantaPrintDocument in mod design sau prin declararea in codul programului.

Printarea

Initierea unui proces de printare se realizeaza, simplu, prin apelul metodeiPrintDocument.Print. Ramane de indeplinit sarcina selectarii continutului care estetrimis la printer.

Printarea elementelor grafice

Acesta implica randarea elementelor grafice pe ecran. Se utilizeaza obiectul Graphicsdin cadrul instantei PrintPageEventArgs pentru a randa elementele grafice pe ecran.Se pot printa forme simple sau forme complexe, utilizand System.Drawing sauSystem.Drawing.Drawing2D.

Exemplu: printarea unei forme complexe utilizand un obiect GraphicsPath:

// event handler pentru PrintPage

public void PrintGraphics(object sender,

System.Drawing.Printing.PrintPageEventArgs e)

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 144 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 145: Aplicatii in Visual.net

{

System.Drawing.Drawing2D.GraphicsPath myPath = new

System.Drawing.Drawing2D.GraphicsPath();

myPath.AddPolygon(new Point[] {new Point(1, 1),

new Point(12, 55), new Point(34, 8), new Point(52, 53),

new Point(99, 5)});

myPath.AddRectangle(new Rectangle(33, 43, 20, 20));

e.Graphics.DrawPath(Pens.Black, myPath);

}

Pentru a printa elemente grafice care ocupa mai multe pagini, se divide, prin logicaprogramului, continutul care va fi printat. De exemplu, urmatoarea metoda va desena oelipsa pe doua pagini:

bool FirstPagePrinted = false;

// event handler pentru PrintPage

public void PrintBigEllipse(object sender,

System.Drawing.Printing.PrintPageEventArgs e)

{

if (FirstPagePrinted == false)

{

FirstPagePrinted = true;

e.HasMorePages = true;

e.Graphics.DrawEllipse(Pens.Black, new Rectangle(0, 0,

e.PageBounds.Width, e.PageBounds.Height * 2));

}

else

{

e.HasMorePages = false;

FirstPagePrinted = false;

e.Graphics.DrawEllipse(Pens.Black, new Rectangle(0,

-(e.PageBounds.Height), e.PageBounds.Width,

e.PageBounds.Height * 2));

}

}

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 145 of 203

Page 146: Aplicatii in Visual.net

Acest exemplu utilizeaza variabila FirstPagePrinted pentru a stabili pagina care seprinteaza: prima sau a doua pagina. ! Acesta pagina este declarata inafara procedurii.Daca aceasta metoda ar fi fost declarata in interiorul metodei, s-ar fi reinitializat lafiecare apel al metodei, returnand intotdeauna false. Dupa ce programul printeazafiecare pagina, se redeseneaza imaginea de fiecare data, schimband pozitiadreptunghiului care incadreaza elipsa, pentru a orienta corect elipsa pe cele douapagini.

Printarea textelor

Un text se printeaza in aceeasi maniera in care este redat pe ecran. Se utilizeazametoda Graphics.DrawString pentru a trimite textul catre printer. In mod uzual, sespecifica un font pentru a randa textul, textul de randat, un obiect Brush sicoordonatele la care se printeaza. De exemplu:

Font afont = new Font("Arial", 36, FontStyle.Regular,

GraphicsUnit.Pixel);

string Hello = "Hello Soccer Team!";

e.Graphics.DrawString(Hello, afont, Brushes.Red, 50, 50);

!

La printarea textului, trebuie eliminata posibilitatea printarii inafara marginilor paginii.Daca se incearca acest lucru, continutul dinafara marginilor paginii nu va fi printat.

Printarea textelor pe mai multe linii

La printarea mai multor linii de text, ca in cazul tablourilor de stringuri sau a liniilor cititedin fisiere text, trebuie inclusa in program o logica de calculare a spatierii dintre linii. Sepoate calcula numarul liniilor de pe o pagina impartind inaltimea spatiului de printare lainaltimea fontului. Similar, se poate calcula pozitia fiecarei linii multiplicand numarulliniei cu inaltimea fontului. Exemplu: printarea unui tablou de stringuri myStrings:

// pozitia curenta din tablou

// declarare inafara procedurii

int ArrayCounter = 0;

private void PrintStrings(object sender, PrintPageEventArgs e)

{

// variabile care vor gestiona

// spatierea si paginarea

float LeftMargin = e.MarginBounds.Left;

float TopMargin = e.MarginBounds.Top;

float MyLines = 0;

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 146 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 147: Aplicatii in Visual.net

float YPosition = 0;

int Counter = 0;

string CurrentLine;

// numarul de linii pe pagina

MyLines = e.MarginBounds.Height/myFont.GetHeight(e.Graphics);

// printeaza fiecare linie,

// oprindu-se la sfarsitul fiecarei pagini

while (Counter < MyLines and ArrayCounter <=

myStrings.GetUpperBound(0))

{

CurrentLine = myStrings[ArrayCounter];

YPosition = TopMargin + Counter *

myFont.GetHeight(e.Graphics);

e.Graphics.DrawString(CurrentLine, myFont, Brushes.Black,

LeftMargin, YPosition, new StringFormat());

Counter +=1;

ArrayCounter +=1;

}

// daca mai sunt linii de printat,

// se trece la o alta pagina

if (!(ArrayCounter == myStrings.GetUpperBound(0)))

e.HasMorePages = true;

else

e.HasMorePages = false;

}

Daca printerul ofera suport pentru folosirea culorilor, aplicatia trebuie sa tina cont deacest lucru. Proprietatea PrinterSettings.SupportsColor poate fi consultata pentru adetermina daca printerul suporta sau nu utilizarea culorilor. Pentru a forta printareaalb-negru, chiar daca printerul este color, se seteaza proprietateaDefaultPageSettings.Color la false. Exemplu:

// using System.Drawing,

// System.Drawing.Drawing2D si System.Drawing.Printing...

Brush BrushOne;

Brush BrushTwo;

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 147 of 203

Page 148: Aplicatii in Visual.net

if (printDocument1.PrinterSettings.SupportsColor == true)

{

// color...

BrushOne = Brushes.Red;

BrushTwo = Brushes.Blue;

}

else

{

// alb-negru...

BrushOne = new HatchBrush(HatchStyle.DarkVertical, Color.Black);

BrushTwo = new HatchBrush(HatchStyle.DashedHorizontal,

Color.Black);

}

PrintPreviewControl

.NET Framework implementeaza un control PrintPreviewControl care permiteefectuarea unei previzualizari grafice a continutului care va fi printat inainte ca acestasa fie trimis catre printer. Controlul PrintPreviewControl se gaseste in tabul WindowsForms din Toolbox, putandu-se adauga o instanta a sa prin drag-and-drop pe o forma.

Pentru a putea previzualiza o pagina, controlul PrintPreviewControl trebuie asociat uneiinstante PrintDocument. Aceasta asociere se creaza prin setarea proprietatiiPrintPreviewControl.Document:

aPrintPreview.Document = aPrintDocument;

Din acest moment, controlul PrintPreviewControl va putea afisa continutul care va fiprintat. Acest lucru se realizeaza prin apelarea metodei care trateaza evenimentulPrintDocument.Print si preluand outputul grafic al acelei metode. Acest output esteapoi redat prin intermediul controlului PrintPreviewControl.

Pe masura ce conditiile din program se modifica, docuentul printat se poate modifica,de asemenea. Actualizarea previzualizarii se poate realiza prin apelarea metodeiInvalidatePreview:

aPrintPreview.InvalidatePreview();

O alta proprietate importanta a controlului PrintPreviewControl este proprietatea Zoom.Valoarea 1 determina vizualizarea la dimensiunea maxima. O valoare fractionara vareduce imaginea, iar o valoare supraunitara o va mari.

PrintPreviewDialog

Acest control reprezinta o resursa pentru previzualizarea documentelor printate sicrearea de previzualizari personalizate. .NET Framework implementeaza un control

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 148 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 149: Aplicatii in Visual.net

PrintPreviewDialog standard care expune o serie de functionalitati uzuale legate deprevizualizarea continutului care va fi printat.

Odata vizualizat, controlul PrintPreviewDialog ofera posibilitatea vizualizarii mai multorpagini, redimensionarii sau printarii documentului. Ca in cazul oricarei alte forme,vizualizarea unei ferestre de dialog PrintPreviewDialog se realizeaza prin apelareametodelor Show sau ShowDialog. Exemplu: asocierea unei componentePrintPreviewDialog cu o componenta PrintDocument si vizualizarea ferestrei de dialogPrintPreviewDialog.

// using System.Drawing.Printing;

PrintDocument aDocument = new PrintDocument();

PrintPreviewDialog aDialog = new PrintPreviewDialog();

aDialog.Document = aDocument;

aDialog.ShowDialog();

Configurarea printarii

Interfata .NET Framework care contine functionalitatile pe printare pune la dispozitie ogama bogata de optiuni de configurare. Proprietatea PrintDocument.PrinterSettingscontine informatii legate de dispozitivele de printare disponibile in sistem. ProprietateaPrintDocument.DefaultPageSettings contine setarile legate de paginare care vor fiutilizate implicit. La crearea unui obiect PrintDocument, configuratia implicita aprinterului implicit este incarcate in proprietatea PrinterSettings, iar setarile implicite depaginare sunt incarcate in proprietatea DefaultPageSettings. Deci, se poate crea siexecuta un proces de printare fara a modifica configuratia implicita.

PrintDialog

Fereastra de dialog PrintDialog permite utilizatorilor sa seteze proprietateaPrinterSettings a unui obiect PrintDocument la run-time.

// vizualizarea ferestrei PrintDialog

PrintDialog1.ShowDialog();

Un PrintDialog trebuie asociat unui obiect PrintDocument. La vizualizare, fereastraPrintDialog este legata de proprietatea PrinterSettings a obiectului PrintDocumentspecificat de proprietatea Document si furnizeaza o interfata grafica pentru a permiteutilizatorului stabilirea unei configuratii. Exemplu:

// using System.Drawing.Printing;

PrintDocument aDocument = new PrintDocument();

PrintDialog aDialog = new PrintDialog();

aDialog.Document = myDocument;

aDialog.ShowDialog();

PageSetupDialog

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 149 of 203

Page 150: Aplicatii in Visual.net

Fereastra PageSetupDialog este similara ferestrei PrintDialog, furnizand i interfatagrafica care permite utilizatorilor configurarea setarilor legate de paginare la run-time.Se poat modifica orientarea in pagina, formatul utilizat, marginile, s.a.

Exemplu:

// using System.Drawing.Printing;

PrintDocument aDocument = new PrintDocument();

PageSetupDialog aDialog = new PageSetupDialog();

aDialog.Document = aDocument;

aDialog.ShowDialog();

Configurarea PageSettings la run-time

Setarile de paginare pot fi modificate la run-time utilizand proprietateaPrintPageEventArgs.PageSettings. Acesta proprietate contine setarile asociatepaginilor care sunt printate. Modificarile efectuate acestei proprietati sunt utilizatepentru a printa pagina curenta, dar nu vor fi pastrate pentru celelalte pagini.

Exemplu: modificarea formatului unei pagini la landscape.

// variabila e este o instanta

// PrintPageEventArgs

e.PageSettings.Landscape = true;

Sinteza

- un document printat este reprezentat de o instanta a clasei PrintDocument

- proprietatea PrinterSettings specifica setarile printerului

- proprietatea DefaultPageSettings specifica setarile implicite de paginare

- printarea unui document: prin apelul metodei PrintDocument.Print

- Evenimentul PrintPage lansat la apelul metodei PrintDocument.Print

- obiectul PrintPageEventArgs contine toate informatiile si functionalitatea necesarerandarii outputului catre printer

- controlul PrintPreviewControl permite previzualizarea unui document care va fi printat

- fereastra de dialog PrintPreviewDialog

- PrintDialog si PageSetupDialog

2.Facilitati de help in aplicatii Visual Studio .NET

Adesea, existenta unei documentatii elaborate in program este foarte importanta.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 150 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 151: Aplicatii in Visual.net

Furnizarea de help in aplicatii permite utilizatorilor sa inteleaga mai usor aplicatia, ceeace conduce la cresterea productivitatii.

Pentru aplicatii complexe si dificile, este necesara scrierea de help built-in , integrat inaplicatie. Help-ul poate fi scris in fisiere HTML care contin un set informatii accesibileprin linkuri sau in fisiere CHM (Compressed HTML) care se pot crea cu MicrosoftHTML Help Workshop. Ambele abordari permit vizualizarea dinamica a informatiileaccesibile prin linkuri.

Clasa Help

O aplicatie poate vizualiza fisiere HTM sau CHM prin intermediul clasei Help. Aceastaclasa incapsuleaza HTML Help 1 engine si pune la dispozitie metode statice carepermit vizualizarea fisierelor de help. Cele doua metode expuse de clasa Help suntShowHelp si ShowHelpIndex.

Metoda ShowHelp afiseaza un fisier de help pentru un anumit control. Controlul carecontine fereastra de dialog HelpDialog trebuie sa fie vizualizat pentru a putea afisafisierul de help specificat printr-un URL. URL-ul poate fi un fisier (de exemplu,C:\fileHelp.htm) sau un HTTP URL (de exemplu,http://someserver.com/someHelp.htm). Pentru ca metoda ShowHelp este statica, nueste necesara crearea unei instante a clasei Help pentru a o putea utiliza. De fapt,clasa Help nu poate fi instantiata.

Exemplu:

Help.ShowHelp(someForm, @"C:\someHelpFile.htm");

Aditional, se poate specifica un parametru HelpNavigator. Acesta specifica care dintreelementele fisierului de help vor fi vizualizate. Acest parametru poate fi setat laTableOfContents, Find, Index sau Topic. Se poate specifica, de asemenea, un cuvantde cautare, ca in exemplul urmator:

Help.ShowHelp(someForm, @"C:\someHelpFile.htm", "HelpMenu");

Clasa Help contine metoda ShowHelpIndex care vizualizeaza indexul unui fisier dehelp specificat. Apelul metodei ShowHelpIndex se executa in aceeasi maniera ca simetoda ShowHelp.

Help.ShowHelpIndex(someForm, @"C:\someHelpFile.htm");

Metodele clasei Help pot fi apelate ca raspuns la o varietate de evenimente lansate deinteractiunea cu interfata utilizator. De exemplu, mai multe aplicatii includ un meniu deHelp sau meniuri care pot fi accesate prin clic dreapta pe un anumit control. De aceea,aplicatiile trebuie sa ofere facilitati de help organizate intr-o maniera logica si eficienta.

Componenta HelpProvider

Componenta HelpProvider permite furnizarea de help pentru controalele din interfatautilizator. HelpProvider este un extender provider; deci, coordoneaza si mentineproprietati pentru fiecare control adaugat pe o forma. Se poate specifica un HelpStringpentru fiecare control de pe forma. Acest string este vizualizat atunci cand controlul

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 151 of 203

Page 152: Aplicatii in Visual.net

primeste focusul si se tasteaza F1. Se poate specifica, de asemenea, unHelpNameSpace care specifica URL-ul fisierului de help asociat HelpProvider-ului.

Componenta HelpProvider asociaza trei proprietati fiecarui control de pe forma parinte:

- HelpString

- HelpKeyWord

- HelpNavigator

Aceste proprietati pot fi setate in fereastra Properties pentru fiecare control sau prinscrierea de cod:

aHelpProvider.SetHelpString(Button1, "Apasati si veti fimultumit...");

Daca proprietatea HelpNameSpace nu este setata, se va vizualiza stringul continut deHelpString si celelalte doua proprietati sunt ignorate. Daca proprietateaHelpNameSpace este setata la un fisier de help, se vizualizeaza fisierul de helpspecificat utilizand parametrii proprietatilor HelpNavigator si HelpKeyword. ProprietateaHelpNavigator poate fi setata la una din urmatoarele valori:

- TableOfContents - vizualizeaza scheletul continutului help-ului

- Find - afiseaza pagina de cautare

- Index - vizualizeaza indexul

- Topic - afiseaza un anumit element de help (topica)

- AssociatedIndex - vizualizeaza indexul unei topici specificate

- KeywordIndex - afiseaza rezultatul cautarii dupa un anumit cuvant cheie

Daca este setata proprietatea HelpNameSpace, nu se mai afiseaza stringul dinHelpString atunci cand se apasa tasta F1, dar acesta poate fi returnat prin altemodalitati. Se poate obtine HelpString-ul asociat unui anumit control prin apelareametodei HelpProvider.GetHelpString ca in exemplul urmator:

someHelpProvider.GetHelpString(Button1);

Sinteza:

- clasa Help

- metoda Help.ShowHelp

- componenta HelpProvider

- proprietatile HelpString, HelpKeyWord si HelpNavigator

- HelpNameSpace

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 152 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 153: Aplicatii in Visual.net

3. Globalizare si localizare

.NET Framework pune la dispozitia programatorilor un suport bogat pentru scrierea deaplicatii accessibile global. Se pot crea aplicatii care se adapteaza la diverse limbaje,formate monetare, calendaristice sau alte informatii legate de cultura.

In cazul dezvoltarii de aplicatii pentru o companie care face afaceri pe planinternational, trebuie avut in vedere faptul va vor exista utilizatori provenind dintr-ovariatate de culturi. Utilizatorii din anumite regiuni ale lumii pot fi nefamiliarizati custandardele legate de monede sau date calendaristice din tara din care provinedezvoltatorul aplicatiei, sau nu pot intelege limba engleza, de exemplu. Integrandsuport international in aplicatii, se largeste aria de utilizare a aplicatiei.

Globalizare si localizare

Globalizarea si localizarea sunt procese interdependente dar diferite. Globalizareaimplica aplicarea formatarii datelor existente pe baza specificului unei anumite culturi,in timp ce localizarea implica extragerea anumitor date pe baza unei culturi.

Exemplu:

* Globalizare: scrierea numerelor reprezentand sume de bani este in anumite tariimplica utilizarea (.) ca separator pentru mii si o virgula ca separator zecimal. Oaplicatie globalizata formateaza numerele reprezentand sume de bani pe baza regulilorde acest gen din regiunea respectiva.

* Localizare: titlul unei forme este afisat intr-un anumit limbaj, dependent de tara in careeste utilizata aplicatia. O aplication localizata preia stringul potrivit si il afiseaza infunctie de locatie.

Culture

Intr-o aplicatie, termenul cultura se refera la informatia culturala legat de regiunea incare este utilizata aplicatia. In .NET Framework, culturile sunt identificate utilizand uncod cultural care reprezinta limba curenta folosita in mediul de lucru. Un cod de culturapoate, de asemenea, specifica informatii despre o anumita regiune. In general, codulculturii este fie un cod din doua litere, care specifica limba, fie un cod din doua litere,urmat de o liniuta si alte doua litere care specifica regiunea. Codurile care specificanumai limbajul se numesc culturi neutre,in timp ce codurile care specifica limba siregiunea sunt cunoscute drept culturi specifice. Exemple:

* en - limba engleza, nici o regiune

* en-CA - limba engleza, Canada

* ro - limba romana

Lista completa a codurilor culturale poate fi consultata utilizand documentatia aferentaclasei CultureInfo in the .NET Framework.

Setarea culturii curente

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 153 of 203

Page 154: Aplicatii in Visual.net

Orice aplicatie citeste automat setarile legate de cultura sistemului si leimplementeaza. Se poate medifica cultura curenta dintr-o aplicatie setand, in modprogramatic, cultura curenta la o noua instanta a clasei CultureInfo. Acesta clasacontine informatii despre o cultura si despre modalitatea in care va interactiona cuaplicatia. De exemplu, clasa CultureInfo contine informatii despre tipul de calendar,formatarea monetara, formatul datei, s.a.m.d. pentru o cultura specificata. Stabilireaunei culturi: setand proprietatea CurrentThread.CurrentCulture la o noua instanta aclasei CultureInfo. Clasa CultureInfo are un constructor care primeste ca parametru unstring reprezentand codul culturii respective. Exemplu:

System.Threading.Thread.CurrentThread.CurrentCulture = new

System.Globalization.CultureInfo("fr-CA");

Returnarea culturii curente se se realizeaza prin accesarea claseiCultureInfo.CurrentCulture dupa cum urmeaza:

// using System.Globalization

CultureInfo theCurrentCulture;

theCurrentCulture = CultureInfo.CurrentCulture;

Implementarea globalizarii

Atunci cand proprietatea Thread.CurrentThread.CurrentCulture este setata la o nouainstanta CultureInfo, toate datele formatate de aplicatie sunt modificate pe baza nouluiformat. Datele neformatate nu vor fi afectate in vreun fel. Sa consideram o forma cu uncontro Label. Sa presupunem ca urmatoarea atribuire:

label1.Text = "$1000.00";

Daca se schimba cultura la en-GB , eticheta va afisa exact acelasi lucru, contrarasteptarilor. Setarile legate de cultura au efect numai pentru informatiile formatate. Pede alta parte, sa presupunem ca textul etichetei a fost formatat in felul urmator:

label1.Text = (1000).ToString("C");

Setarea culturii la en-GB , va face ca eticheta sa afiseze L1000.00. Valoarea esteformatata pe baza comventiilor monetare locale. Nu se executa, insa, nici un fel deconversie monetara.

Implementarea localizarii

.NET Framework faciliteaza localizarea prin crearea de fisiere de resurse care retindatele pentru forme alternative asociate culturilor pe care le suporta aplicatia. Larun-time, se incarca o anumita forma, pe baza proprietatii CultureInfo.CurrentUICulture.

Setarea UI-culturii curente

O UI-cultura este reprezentata de o instanta CultureInfo, si este diferita de proprietateaCultureInfo.CurrentCulture. Setarile CurrentCulture determina formatarile care vor fiaplicate datelor, in timp ce CurrentUICulture specifica resurse pentru forme localizatecare vor fi incarcate la run-time. Se poate prelua instanta CurrentUICulture accesandproprietatea CultureInfo.CurrentUICulture, dupa cum urmeaza:

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 154 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 155: Aplicatii in Visual.net

// using System.Globalization

CultureInfo theCurrentCulture;

theCurrentCulture = CultureInfo.CurrentUICulture;

UI-cultura curenta se seteaza in acceasi maniera ca si cultura curenta: accesandThread-ul curent. De exemplu:

System.Threading.Thread.CurrentThread.CurrentUICulture = new

System.Globalization.CultureInfo("th-TH");

La setarea culturii curente, sistemul de operare incarca resursele specifice aceleiculturi, in cazul in care sunt disponibile. Daca resursele specifice nu sunt disponibile,interfata utilizator vizualizeaza resursele pentru cultura respectiva.

!

UI-cultura trebuie setata inainte de o forma sa poata vizualiza resursele localizate.Daca UI-cultura se seteaza programatic, ea trebuie setata in constructorul formeiprincipale sau in metoda main a aplicatiei.

Crearea formelor localizate

Crearea formelor localizate in .NET Framework este un proces facil. Fiecare formacontine o proprietate Localizable care determina daca forma este localizata sau nu.Setarea acestei proprietati la true permite localizarea. In acest caz, Visual Studio .NETcreaza automat fisierele resursa necesare, utilizand proprietatea Language a formei.Atunci cand aceasta proprietate este setata la (Default), pot fi editate toateUI-proprietatile sau controalele pentru a furniza o reprezentare a UI-culturii curente.Pentru a crea o versiune localizata a formei, se poate seta proprietatea Language la oalta valoare, diferita de (Default). Visual Studio .NET va crea un fisier resursa pentrunoul limbaj si va stoca in acel fisier toate valorile UI-specifice setate.

!

Desi, de obicei, UI-elementele sunt siruri de caractere, orice proprietate poate filocalizata. Deci, putem avea, de exemplu, butoane care isi modifica dimensiunilepentru a putea vizualiza corect texte in diverse limbi. Aceste fisiere pot fi vizualizate inSolution Explorer, existand cate un fisier resursa pentru fiecare limbaj pentru careforma are o versiune.

Atunci cand CurrentUICulture este setata la o cultura localizata, aplicatia va incarcaversiunea corespunzatoare a formei consultand fisierele resursa aferente. Daca nuexista fisierele resursa necesare, se va vizualiza UI-cultura implicita.

Validarea input-ului cu specific international

se pot utiliza metodele de validare din structura Char pentru a valida inputul introdus(acesta poate contine caractere specifice unei anumite limbi). Metodele Char.IsDigit,Char.IsLetter si altele vor returna true sau false, independent de caracterele utilizate.Deci, validarile de acest gen vor functiona corect, fara alte modificari speciale.

Formatari specifice culturilor

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 155 of 203

Page 156: Aplicatii in Visual.net

Se pot specifica valori pentru anumiti membri ai clasei CultureInfo pentru a croiaplicatia astfel incat sa raspunda unor necesitati cu specific cultural. De exemplu, saconsideram o aplicatie pentru un client care colaboreaza cu un grup din Japonia, darmoneda utilizata in aplicatie este dolarul american. Aplicatia trebuie sa implementeze oformatare cu specific japonez pentru anumite elemente.

Membri ai clasei CultureInfo care specifica formatari legate de globalizare:

* DateTimeFormat - formatarea datelor calendaristice si a timpului

* NumberFormat - formatarea datelor numerice si financiare

* TextInfo - formatarea textelor

Exemplu:

// using System.Globalization

// using System.Threading

CultureInfo modJPCulture = new CultureInfo("jp-JN");

modJPCulture.NumberFormat.CurrencySymbol = "$";

// se foloseste caracterul $

Thread.CurrentThread.CurrentCulture = modJPCulture;

Implementarea scrierii de la dreapta la stanga

Anumite limbaje folosesc o astfel de scriere. Formele Windows tandard contin oproprietate RightToLeft care permite implementarea unei interfete cu un astfel despecific.

Valori posibile ale proprietatii RightToLeft : Yes, No si Inherit, ultima fiind valoareaimplicita, caz in care afisarea este determinata de valoarea setata pentru controlulparinte.

Efectul setarii proprietatii RightToLeft a unui control la valoarea Yes:

- aliniera textului este inversata

- pentru o forma, titlul va fi aliniat la dreapta

- barele de derulare verticale vor aparea pe partea stanga

- barele de derulare orizontale sunt initializate cu slider-ul in partea dreapta

- check-box-urile vor avea proprietatea CheckAlign inversata

- butoanele taburilor vor fi inversate

- la fel, alinierea elementelor in list box si combo box

Pe short, formatarea fiecarui control consta in oglindirea continutului acestuia.

Continutul unui control RightToLeft ramane, totusi, neschimbat.

Conversia caracterelor codificate

.NET Framework utilizeaza o reprezentare Unicode UTF-16 a caracterelor. Un caracter

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 156 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 157: Aplicatii in Visual.net

Unicode este un standard universal standard de reprezentare a caracterelor, acoperindo multime foarte mare de caractere, cu posibilitate de extindere.

.NET Framework permite conversii ale datelor din alte formate in date reprezentate inUnicode. Aceste conversii sunt indeplinite de clasa Encoding, din spatiul de numeSystem.Text. Aceasta clasa nu poate fi instantiata direct, dar se poate obtine o instantaa acestei clase utilizand metoda statica Encoding.GetEncoding, pentru a obtine ocodificare specifica:

// using System.Text

Encoding jpEncoding;

// pagina de coduri 932 reprezinta caracterele japoneze

jpEncoding = Encoding.GetEncoding(932);

Dupa ce a fost creata o instanta a unei codificari, poate fi utilizata pentru a converticaractere din aceasta codificare in caractere in format Unicode si vice versa. Exemplu:

// using System.Text

byte[] tgtData;

Encoding srcEncoding;

UnicodeEncoding tgtEncoding = new UnicodeEncoding();

srcEncoding = Encoding.GetEncoding(932);

// caracterele japoneze sursa

// tgtData contine acum un tablou de bytes care reprezintacodificarea

// Unicode a tabloului myData

tgtData = Encoding.Convert(srcEncoding, tgtEncoding, myData);

Sinteza:

- globalizare

- localizare

- cultura

- UI-cultura

- conversii de caractere

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 157 of 203

Page 158: Aplicatii in Visual.net

Section 11. Assemblies. Aplicatii - configurare,securizare, instalare, rulare - X

1. Assemblies si resurse

Un assembly reprezinta unitatea primara de dezvoltare intr-o aplicatie Microsoft .NETFramework, constand intr-o colectie de tipuri si resurse care sunt interconectate pentrua crea o unitate functionala logica. Assembly-urile sunt auto-descriptive si contin toatainformatia solicitata de common language runtime pentru a interpreta continutul sipentru a configura executia acestora.

Pe scurt, un assembly este un proiect care este compilat intr-un fisier executabil sauintr-un fisier DLL. Structura interna a unui assembly este, intrucatva, diferita de cea afisierelor .exe sau .dll create cu unelte de dezvoltare anterioare. Un assembly continepatru sectiuni interne:

- un manifest (metadata)

- metadate despre tipuri

- limbajul intermediar al assembly-ului

- fisiere de resurse

Manifestul assembly-ului contine metadata care descrie assembly-ul in contextul CLR.Common language runtime utilizeaza aceste informatii pentru a lua decizii legate deexecutia assembly-ului. Un manifest contine urmatoarele informatii:

- identitate: contine numele si numarul versiunii assembly-ului, putand contineinformatii optionale, cum ar fi semnatura aplicatiei

- tipuri si resurse: lista tuturor tipurilor continute, precum si informatii despremodalitatea de accesare a tipurilor

- fisiere: lista tuturor fisierelor din assembly, precum si informatii legate dedependentele dintre acestea

- permisiuni de securitate: descriu restrictiile de securitate impuse la executiaassembly-ului

Identitatea unui assembly este continuta in fisierul AssemblyInfo.vb sau .cs din cadrulproiectului, putand fi modificata de catre utilizator.

[assembly: AssemblyTitle("")]

[assembly: AssemblyDescription("")]

[assembly: AssemblyConfiguration("")]

[assembly: AssemblyCompany("")]

[assembly: AssemblyProduct("")]

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 158 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 159: Aplicatii in Visual.net

[assembly: AssemblyCopyright("")]

[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]

Informatiile legate de identitatea assembly-ului pot fi modificate prin setarea valoriloracestor atribute in fisierul AssemblyInfo. Urmatorul exemplu de cod demonstreaza cumse poate seta atributul AssemblyTitle:

[assembly: AssemblyTitle("Acesta este un assembly!")]

Crearea assembly-urilor de tip biblioteca de clase (class library)

Acestea reprezinta o multime de tipuri care pot fi referentiate si utilizate in alteassembly-uri. De exemplu, un control personalizat care va fi utilizat in alte aplicatii va ficonstruit in cadrul unui assembly de aces tip. Un astfel de assembly nu este executabil,trebuind adaugat ca referinta intr-o alta aplicatie executabila.

Tipurile de proiecte asociate unui astfel de assembly sunt Class Library sau WindowsControl Library. Se scrie codul, se seteaza informatiile legate de identitateaassembly-ului in fisierul AssemblyInfo si se executa Build.

Resurse si assembly-uri de resurse

O mare parte dintre aplicatii utilizeaza resurse. Acestea reprezinta datenon-executabile partajate in cadrul aplicatiei. Exemple de resurse: siruri de caracterevizualizate in cadrul interfetei utilizator pe baza culturii setate in aplicatie sau un set deimagini. Impachetarea acestor date in fisiere resursa permit modificarea datelornecesare programului fara a recompila intreaga aplicatie.

Crearea fisierelor de resurse

Aplicatia ResEditor din .NET Framework poate fi utilizata pentru a crea fisiere resursacare contin texte si imagini. ResEditor este o aplicatie de sine statatoare, nefiindintegrata in Visual Studio .NET. Ea va fi rulata separat, utilizand command prompt-ulVisual Studio .NET. ResEditor permite crearea de fisiere .resources sau .resx carecontin siruri de caractere sau imagini. Se pot specifica tipul si numele resurselor dincadrul fisierului. Dupa adaugarea elementelor din cadrul fisierului, se pot specificavalori ale sirurilor de caractere resursa sau imaginile care vor fi adaugate in cadrulresurselor de imagini. In final, fisierele pot fi salvate ca fisiere binare de tip .resourcessau fisiere XML de tip .resx.

Odata create, fisierele .resources sau .resx pot fi adaugate la proiect din meniulProject, optiunea Add Existing Item si selectand apoi fisierul resursa dorit. ExecutandBuild, resursele vor fi partajate corespunzator in cadrul proiectului.

Crearea assembly-urilor de resurse

Pot fi create assembly-uri care contin numai resurse. Acest lucru este util in situatia incare este necesara modificarea datelor continute in fisiere resursa fara a recompilaaplicatia pentru modificarea efectiva a acestora.

Un assembly de tip resursa se poate crea prin adaugarea de fisiere resursa la un

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 159 of 203

Page 160: Aplicatii in Visual.net

proiect vid. Atunci cand se va executa build, resursele vor fi compilate intr-un assemblycomun care va putea fi apoi referentiat si accesat.

Crearea unui assembly satelit

La crearea aplicatiilor internationalizate, este necesara furnizarea diferitelor multimi deresurse pentru culturile utilizate in aplicatie. Assembly-urile satelit permit acestormultimi de resurse sa fie incarcate automat, pe baza setarii CurrentUICulture pentrufirul de executie curent.

Pentru a fi incorporata intr-un assembly satelit, un fisier resursa trebuie sa se supunaunei scheme specifice de nume, bazata pe cultura pentru care a fost proiectat. Numeleunui fisier resursa specific unei culturi este similar numelui fisierului resursa pentrucultura invarianta, avand inserat, in plus, codul culturii respective intre numele de bazasi extensie. Deci, daca exista un fisier de resurse fileResources.resx, un fisier resursacare va contine resurse pentru cultura neutra fr (Franta) va avea numelefileResources.fr.resx. Pentru culturi specifice, un exemplu ar putea fi:anotherFileResources.en-CA.resx.

Dupa adaugare, Visual Studio .NET va compila aceste fisiere resursa alternative inassembly-uri satelit, creandu-se o structura de directoare asociata. La run-time,resursele specifice culturii curente vor fi localizate automat de catre common languageruntime.

Interogarea resurselor la run-time

La run-time, se poate utiliza clasa ResourceManager pentru a returna resurselepartajate. Un ResourceManager gestioneaza accesul si interogarea resurselorpartajate in assembly. Fiecare instanta a clasei ResourceManager este asociata cu unassembly care contine resurse.

Un ResourceManager se poate crea prin specificarea a doi parametri: numele de bazaal fisierului resursa si assembly-ul in care se gaseste acest fisier. NoulResourceManager va fi dedicat fisierului resursa specificat. Numele de baza specificateste numele spatiului de nume care contine fisierul, urmat de numele fisierului, fara aspecifica extensiile. De exemplu, un fisier resursa denumit fileResources.de-DE.resxintr-un spatiu de nume Namespace1 va avea numele de bazaNamespace1.fileResources.

Al doilea parametru refera assembly-ul in care este localizat fisierul resursa. Dacaassembly-ul care contine resursele este acelasi assembly care contine obiectul incadrul caruia de creaza ResourceManager-ul, se poate obtine o referinta la assemblyutilizand tipul obiectului respectiv. De exemplu:

// crearea unui ResourceManager pentru

// a accesa fisiere resursa dintr-un fisier partajat

// myResources.resx

// intr-un namespace myNamespace si acelasi assembly in care

// se gaseste obiectul curent

// se utilizeaza System.Resources

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 160 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 161: Aplicatii in Visual.net

ResourceManager myManager = new ResourceManager

("myNamespace.myResources", this.GetType().Assembly);

Daca resursele care vor fi accesate se gasesc intr-un alt assembly, cum ar fi unassembly de resurse, assembly-ul trebuie incarcat inainte de a accesa resurselecontinute. Acest lucru se poate realiza prin intermediul unui obiect Assembly din spatiulde nume System.Reflection. Exemplu:

// using System.Resources

System.Reflection.Assembly myResources;

// numele assembly-ului ca parametru

myResources =System.Reflection.Assembly.Load("ResourceAssembly");

ResourceManager myManager = new

ResourceManager("ResourceAssembly.Resources",

myResources);

Proiectul trebuie sa contina o referinta la assembly-ul care va fi accesat. Odata ce afost creat un manager de resurse, acesta poate fi utilizat pentru a returna siruri decaractere si obiecte continute in fisierul de resurse. Pentru a accesa un sir decaractere, se utilizeaza metoda ResourceManager.GetString, specificand numeleresursei care va fi accesata. Imaginile sau alte obiecte dintr-un fisier resursa pot fiobtinute prin metoda ResourceManager.GetObject. Aceasta metoda returneaza unobiect corespunzator numelui specificat. In plus, trebuie executata o conversie explicitapentru a obtine rezultatul scontat. Exemplu:

System.Drawing.Image myImage;

myImage =(System.Drawing.Image)myManager.GetObject("ImageResource");

Assembly-uri partajate

Assembly-urile pot fi private sau partajate:

- un assembly privat este un assembly utilizat de o singura aplicatie

- un assembly partajat poate fi utilizat de mai multe aplicatii

Majoritatea assembly-urilor care se creaza sunt assembly-uri private, find createimplicit. Un astfel de assembly poate fi utilizat de o singura aplicatie, fiind integrat sidisponibil numai acelei aplicatii. Din aceste motive, nu exista informatii legate deversiunea sau identitatea assembly-ului.

Toate assembly-urile cu care ne-am obisnuit pana acum au fost private. La adaugareaunei referinte catre un assembly privat in proiect, Visual Studio .NET creaza o copie aDLL-ului care contine assembly-ul si aceasta este copiata in directorul proiectului. Deci,mai multe proiecte pot referentia acelasi DLL si utiliza tipurile pe care le contine, dar

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 161 of 203

Page 162: Aplicatii in Visual.net

fiecare proiect are propria sa copie a DLL-ului, acesta fiind, deci, un assembly privat.Pentru ca mai multe aplicatii sa partajeze un assembly, acesta trebuie instalat in GlobalAssembly Cache. Avantaje:

- locatie partajata

- securitate (assembly-ul este instalat in directorul sisteului de operare)

- versionare (pot fi instalate mai multe versiuni ale aceluiasi assembly

Partajarea unui assembly si instalarea in Global Assembly Cache implica semnareaassembly-ului cu un strong name.

Strong Naming

Un strong name este un nume care garanteaza identitatea assembly-ului. Acestacontine informatii despre assembly, cum ar fi numele, numarul versiunii, informatialegata de cultura si o pereche de chei publica/privata. Aceste informatii sunt incriptateutilizand cheia privata si pot fi decriptate folosind cheia publica. Dezvoltatorul aplicatieieste singurul care detine cheia privata, ceea cea determina securitatea aplicatiei.

O pereche de chei poate fi generata prin intermediul aplicatiei sn.exe (strong name).Un fisier care contine astfel de chei are extensia .snk. Exemplu:

sn k myKey.snk

Pentru a semna un assembly cu un strong name: - se deschide fisierul AssemblyInfodin cadrul proiectului

- se verifica numarul versiunii assembly-ului:

[assembly: AssemblyVersion("1.0.1.1")]

- se specifica fisierul care contine cheile de criptare. Exemplu:

[assembly: AssemblyKeyFile("..\\..\\myKey.snk")]

Se executa build. Strong name-ul va fi generat si aplicat assembly-ului.

Instalarea in Global Assembly Cache

Se utilizeaza aplicatia Global Assembly Cache utility (gacutil.exe):

gacutil /i mypath\myAssembly.dll

Sinteza:

- assembly - manifest, tipuri de date, fisiere de cod si reurse

- assembly-uri de tip biblioteca de clase

- resurse

- assembly-uri de resurse

- resurse asociate culturilor

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 162 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 163: Aplicatii in Visual.net

- clasa ResourceManager

- assembly-uri private si partajate

- Global Assembly Cache

- strong name

- aplicatiile sn.exe si gacutil.exe

2. Configurarea si optimizarea aplicatiilor

.NET Framework pune la dispozitie unelte de configurare si optimizare a aplicatiei dupace aceasta a fost instalata. Fisierele de configurare permit specificarea locatiei sauinformatiilor legate de versiune assembly-urilor si permit configurarea proprietatiloraplicatiei.

Pentru orice aplicatie se poate crea un fisier de configurare. Acesta permiteconfigurarea proprietatilor aplicatiei dupa ce aceasta a fost instalata, fara a recompilacodul. Fisierul de configurare este un fisier XML care contine informatii desprecomportamente care vor fi imprimate aplicatiei.

Crearea fisierului de configurare

Un fisier de configurare este un fisier XML care contine o serie de taguri specifice si unnume care trebuie sa respecte anumite regului. Un fisier de configurare pentru oaplicatie va avea numele <name>.<extension>.config, unde <name> este numeleaplicatiei, iar <extension> este extensia aplicatiei (de exemplu .exe). Un fisier deconfigurare trebuie sa se afle in acelasi director ca si assembly-ul asociat aplicatieipentru care se face configurarea.

Structura de baza a unui fisier de configurare este urmatoarea:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<...elemente de configurare...>

</configuration>

Inafara primului element, care specifica versiunea XML si codificarea, si a ultimuluielement, <configuration>, nu exista elemente obligatorii pentru un fisier de configurare.Toate celelalte elemente sunt optionale.

In C#, fisierul de configurare .config trebuie creat manaul, cu ajutorul unui editor, pebaza schemei descrise mai sus, adaugand o serie de elemente.

Schema fisierului de configurare .config

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 163 of 203

Page 164: Aplicatii in Visual.net

Elemente ale schemei fisierului de configurare:

• <startup>- contine numai elementul <requiredRuntime>, care permite specificareaversiunii common language runtime utilizate

• <runtime> - permite configurarea informatiilor legate de executia assembly-ului siconportamentul garbage colectorului

• <system.runtime.remoting> - contine informatii despre configurarea canalelor decomunicatie si a obiectelor de tip remote

• <system.net> - contine informatii despre aplicatii pe Internet

• <mscorlib> - contine un tag <cryptographySettings> care permite configurareaelementelor criptografice din cadrul aplicatiei

• <configSections> - contine configurari personalizate

• <system.diagnostics> - informatii de configurare a claselor Trace si Debug din cadrulaplicatiei

Configurarea aplicatiei utilizand proprietati dinamice

Proprietatile dinamice permit configurarea valorilor de startup ale obiectelor din cadrulaplicatiei. Se poate realiza o mapare a proprietatilor specifice ale obiectelor laelemente din cadrul fisierului de configurare file si returnarea dinamica a acestora larun-time. Proprietatile dinamice sunt utile in cazul resurselor externe care se potmodifica pe durata timpului de viata a aplicatiei, cum ar fi un string de conectare la obaza de date. Consultand valoarea unei astfel de proprietati dinamice, se poatereconfigura aplicatia fara a fi necesara recompilarea si reinstalarea.

Configurarea proprietatilor dinamice utilizand ferestrea Properties

Fereastra Properties corespunzatoare fiecarui control din interfata utilizator contine unnod expandabil care permite utilizatorului setarea proprietatilor care vor fi tratate caproprietati dinamice. Proprietatile care vor fi legate la resurse externe sunt adaugateimplicit la acest nod, putandu-se adauga si alte proprietati (Advanced ...).

Pentru a putea consulta o proprietate dinamica din fisierul .config, trebuie mai intaidefinita o cheie. Aceasta cheie este scrisa in fisierul .config si corespunde valoriicorespunzatoare care va fi returnata din fisierul .config. La setarea unei chei pentru oproprietate dinamica, cheia si valoarea proprietatii sunt scrise automat in fisierul.config. Exemplu: transformarea proprietatii Button1.Text in proprietate configurabila.

<add key="Button1.Text" value="Button1" />

Cheia (Button1.Text) este utilizata de aplicatie pentru a returna valoarea (Button1) larun-time. Deoarece cheile sunt citite de utilizatori, trebuie sa primeasca valori care sarespecte un pattern consistent. Pattern-ul implicit este <control>.<propertyname>, undecontrol este numele controlului, iar propertyname este numele proprietatii.

Dupa ce programul a fost instalat, pot fi configurate proprietatile dinamice prin editareadirecta a fisierului de configurare. La urmatoarea rulare a aplicatiei, modificarileefectuate isi vor face simtite efectul.

!

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 164 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 165: Aplicatii in Visual.net

Nu toate proprietatile sunt disponibile in fereastra Dynamic Properties. Pot ficonfigurate doar proprietatile reprezentate ca siruri de caractere sau tipuri care pot ficonvertite explicit de la tipul string.

Setarea si consultarea manuala a proprietatilor dinamice

Uneori, este util ca si alte proprietati, inafara proprietatilor din interfata utilizator, sapoata fi configurabile. Sa consideram exemplul unei clase instantiate la run-time. Pot fistabilite proprietati implicite pentru obiecte create dinamic in fisierul de configurare;acestea pot fi setate si consultate dinamic la run-time utilizand clasaAppSettingsReader.

Clasa AppSettingsReader se gaseste in spatiul de nume System.Configuration siutilizeaza chei pentru a returna valori din fisierul de configurare. Principala metoda aacestei clase este GetValue. Prametri: un string reprezentand cheia si un tip carereprezinta valoarea returnata. Desi se specifica un tip, valoarea este returnata ca unObject si trebuie convertita explicit la tipul corect de date. Exemplu:

// crearea unui obiect AppSettingsReader

System.Configuration.AppSettingsReader myReader = new

System.Configuration.AppSettingsReader();

// crearea unui obiect utilizator

Widget myWidget = new Widget();

// returnarea valorii unei proprietati dinamice

// DynamicWidget.Text repreinta cheia,

// valoarea este returnata ca un string

// urmeaza o conversie explicita

myWidget.Text = myReader.GetValue("DynamicWidget.Text",

typeof(System.String)).ToString();

La incercarea de utilizare a unei chei inexistente in fisierul de configurare, se arunca oexceptie de tipul InvalidOperationException. Elementele continand perechi de tipulkey/data se adauga prin intermediul tagului <add> si vor fi introduse drept copii aitagului <appSettings>. Exemplu:

<appSettings>

<... setari ale proprietatilor configurabile etc... >

<... Example: <add key="settingName" value="settingValue"/>... >

<add key="Widget.Visible" value="True" />

<add key="Widget.Text" value="I love my Widget!" />

</appSettings>

Optimizarea performantei aplicatiiilor

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 165 of 203

Page 166: Aplicatii in Visual.net

Optimizare in faza de dezvoltare

Un cod eficient, optimizat este rezultatul unei bune planificari si a unei experientebogate in scrierea de cod. Cateva idei mai importante legate de tehnica scrierii de cod:

- evitarea legarii tarzii (late binding) - evitarea, pe cat posibil, a folosirii tipului object si,deci, a conversiilor

- evitarea utilizarii variabilelor globale

- traterea atenta a structurilor iterative - reprezinta structurile de program care implicaexecutia unui numar foarte mare de operatii

Optimizarea este un proces iterativ

Planul general de optimizare a codului este urmatorul:

* masurarea datelor legate de performanta

* identificarea bottleneck-urilor

* rafinarea codului

Masurarea performantei

Windows 2000 si Windows XP includ un utilitar denumit perfmon.exe care poatemonitoriza o serie de parametri legati de performanta aplicatiei. Rezultatele pot firedate in forma grafica sau salvate sub forma de log-uri.Exista, de asemenea,posibilitatea optimizarii aplicatiei prin setari ale compilatorului.

Sinteza:

- fisiere de configurare

- proprietati dinamice

- clasa AppSettingsReader

- tagul <add>

- utilitarul perfmon.exe

- optimizari in faza de compilare

3. Securitatea aplicatiilor

Securitate inseamna protectie. Pot fi utilizate facilitatile de securitate puse la dispozitiede .NET Framework pentru a proteja codul aplicatiilor fata de utilizatori neautorizati sipentru a proteja sistemul in cazul utilizarii neautorizate a anumitor fragmente de cod.Administratorul sistemului seteaza politica de securitate a sistemului. Acesta decidetipurile de cod care vor putea fi utilizate de o masina, daca un anumit assembly poate firulat pe o masina, s.am.d. Politica de securitate setata de administratorul sistemului nupoate fi suprascrisa in cod: ea confera cel mai inalt nivel de securitate pe o anumita

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 166 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 167: Aplicatii in Visual.net

masina.

Permisiuni

O permisiune este un obiect care reprezinta un utilizator, o identitate sau o resursa(cod). Obiectele de tip permisiune sunt utilizate intr-o varietate de functii legate desecuritate.

Interfata IPermission

Orice permisiune de securitate in .NET Framework trebuie sa implementeze interfataIPermission, care contine un nivel de functionalitate comun tuturor obiectelor desecuritate deci, arareori va fi necesara o implementare efectiva a acestei interfete.Metodele membre ale interfetei IPermission sunt descrise in continuare:

* Copy - creaza si returneaza o copie identica a permisiunii

* Demand - parcurge stiva de apeluri si arunca o exceptie de tipul SecurityExceptiondaca un apelant de pe stiva nu are permisiunea sa execute apelul respectiv

* Intersect - creaza si returneaza o permisiune care reprezinta intersectia a douapermisiuni

* IsSubsetOf - determina daca permisiunea curenta este un subset al unei permisiunispecificate

* Union - creaza o permisiune care reprezinta reuniunea permisiunii curente cu o altapermisiune specificata.

Configurarea autorizarilor bazate pe roluri

Securitatea role-based reprezinta garantarea sau blocarea accesului la o aplicatie sauresursa pe baza unei identitati sau rol al unui utilizator. De exemplu, sa presupunem capentru o aplicatie utilizata in mediu universitar, numai profesorii vor avea acces la oanumita sectiune a aplicatiei. Autorizarea bazata pe roluri implementeaza securitateade acest tip.

Clasa Principal

In .NET Framework, utilizatorii care se autentifica sunt reprezentati de obiectePrincipal. Acestea contin informatii despre identitatea sau rolul utilizatorului si poate fifolosit pentru validarea identitatii fata de un obiect PrincipalPermission, utilizat pentru aproteja partile sensibile ale unei aplicatii fata de utilizatori neautorizati.

Exemplu de implementare a unui model de securitate built-in:

// WindowsPrincipal reprezinta identitatea

// utilizatorului curent

AppDomain.CurrentDomain.SetPrincipalPolicy

(PrincipalPolicy.WindowsPrincipal);

WindowsPrincipal contine o referinta la un obiect WindowsIdentity care reprezinta

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 167 of 203

Page 168: Aplicatii in Visual.net

utilizatorul curent. Se pot obtine informatii despre utilizatorul curent accesandproprietatea Identity a obiectului WindowsPrincipal. WindowsPrincipal returneazaproprietatea Identity ca o interfata IIdentity, va fi nevoie, deci, de o conversie explicitala un obiect WindowsIdentity. Exemplu:

WindowsPrincipal myPrincipal;

myPrincipal = (WindowsPrincipal)

System.Threading.Thread.CurrentPrincipal;

WindowsIdentity myIdentity;

// se preia identitatea WindowsIdentity

myIdentity = (WindowsIdentity)myPrincipal.Identity;

// se afiseaza numele utilizatorului curent

MessageBox.Show(myIdentity.Name);

Securitate role-based imperativa (la run-time)

Se utilizeaza obiecte PrincipalPermission. Un astfel de obiect poate specifica oidentitate si un rol, putand impune faptul ca utilizatorul curent trebuie sa aiba numele sirolul specificat de obiectul PrincipalPermission. Metoda Demand verifica concordantaintre obiectul Principal si numele si rolul specificate de PrincipalPermission. Exemplu:

// constructorul are ca parametri

// numele si rolul utilizatorului ca stringuri

PrincipalPermission myPermission = newPrincipalPermission("John",

"Manager");

// CurrentPrincipal trebuie sa contina user-ul John,

// cu rol de manager

myPermission.Demand();

Utilizarea metodei Union pentru a crea permisiuni care combina doua permisiuniexistente. Exemplu:

PrincipalPermission Permission1 = newPrincipalPermission("John",

"Manager");

PrincipalPermission Permission2 = newPrincipalPermission("Smith",

"Group Manager");

PrincipalPermission Permission3;

// reuniunea celor doua permisiuni

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 168 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 169: Aplicatii in Visual.net

Permission3 =(PrincipalPermission)Permission2.Union(Permission1);

// John sau Smith vor putea accesa codul programului

Permission3.Demand();

La crearea unui obiect PrincipalPermission, se poate specifica null pentru nume saurol. Aceasta permite crearea unei permisiuni care valideaza numai numele sau numairolul permisiunii. Exemplu: validarea rolului obiectului CurrentPrincipal (fara validareanumelui):

// utilizatorul trebuie sa aiba rol de manager

PrincipalPermission myPermission = new

PrincipalPermission(null, "Manager");

Intersectia a doua permisiuni:

PrincipalPermission Permission1 = new PrincipalPermission(null,

"Manager");

PrincipalPermission Permission2 = newPrincipalPermission("John",

null);

PrincipalPermission Permission3;

// intersectia permisiunilor

// Permission1 si Permission2

Permission3 =(PrincipalPermission)Permission2.Intersect(Permission1);

// Principal-ul care acceseaza acest cod trebuie sa fie John

// cu rol de manager

Permission3.Demand();

Verificarea apartenentei utilizatorilor la roluri stabilite de sistemul de operare:

// se utilizeaza sintaxa cu doua backslash-uri (\\)

PrincipalPermission myPermission = new

PrincipalPermission("John", "BUILTIN\\Administrators");

Securitate role-based declarativa (in cadrul manifestului assembly-ului)

Orice obiect Permission are un atribut corespunzator. Aceste atribute pot fi atasateclaselor si/sau membrilor si sunt utilizate pentru a controla accesul la aceste clase simembri. In contextul securitatii declarative, atributele de permisiune sunt atasatemembrilor protejati. Administratorul poate lua o decizie care sa permita executia

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 169 of 203

Page 170: Aplicatii in Visual.net

assembly-ului pe baza metadatei. Fiecare atribut de permisiune contine ca parametrual constructorului un obiect SecurityAction care indica actiunea care se va executa. Insecuritate role-based , acesta este de obicei o actiune Demand. Exemplu: securitatepentru o metoda myMethod.

[PrincipalPermission(SecurityAction.Demand, Name="John",

Role="Student")]

public void myMethod()

{

// Method implementation omitted

}

Configurarea securitatii accesului la cod

Securitatea accesarii codului previne executia apelurilor neautorizate catre anumitefragmente de cod. Se pot stabili, de asemenea, nivele de securitate care sa comunicecerintele de securitate administratorului de sistem.

La fel ca in cazul securitatii bazate pe roluri, securitatea accesului la cod se bazeazape permisiuni. In acest context, o permisiune reprezinta resursele sistemului sicontrolul accesarii acestor resurse. Un exemplu foarte bun este sistemul de fisiere. Incazul unei aplicatii care utilizeaza scrierea in fisiere, trebuie sa ne asiguram caapelurile neautorizate nu sunt capabile sa utilizeze anumite resurse, evitandu-se astfelproducerea de erori in structura de fisiere.

Permisiuni de accesare a codului

Fiecare permisiune reprezinta o resursa. Majoritatea permisiunilor se gasesc in spatiulde nume System.Security. Cele mai importante permisiuni referitoare la accesareacodului:

* DirectoryServicesPermission - controleaza accesul la Active Directory

* EnvironmentPermission - controleaza accesul la variabilele de mediu

* EventLogPermission - controleaza scrierea/citirea in/din loguri de evenimente

* FileDialogPermission - controleaza accesul la fisiere sau directoare prin intermediulunei ferestre de dialog

* FileIOPermission - controleaza crearea, citirea si scrierea in sistemul de fisiere

* OleDbPermission - stabileste accesul la o baza de date OleDb

* PrintingPermission - controleaza accesul la dispozitivele de printare

* ReflectionPermission - controleaza abilitatea claselor din System.Reflection de aextrage informatii despre tipuri la run-time

* RegistryPermission - controleaza citirea/scrierea din/in registri

* SecurityPermission - stabileste drepturi, incluzand dreptul de a executa cod,controleaza manipularea firelor de executie si a obiectelor Principals, si apelurile decode unmanaged

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 170 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 171: Aplicatii in Visual.net

* SQLClientPermission - stabileste accesul la baze de date Microsoft SQL Server

* UIPermission - controleaza accesul la interfata utilizator

Crearea permisiunilor de acces la cod

Fiecare permisiune contine un anumit set de constructori care permit specificarearesurselor protejate. O permisiune care permite accesul nerestrictionat la resurse estedescrisa de flagul PermissionState.Unrestricted. PermissionState.None permitecrearea unei permisiuni care restrictioneaza total accesul la resursele specificate.Exemplu:

// acces nerestrictionat la resurse Reflection

ReflectionPermission myPermission = new

ReflectionPermission(PermissionState.Unrestricted);

// acces complet restrictionat la resurse UI

UIPermission anotherPermission = new

UIPermission(PermissionState.None);

Fiecare permisiune contine constructori aditionali care permit configurari specifice alepermisiunii. Exemplu: crearea unei permisiuni care reprezinta dreptul de a scrie intr-unsingur fisier din sistemul de fisiere:

FileIOPermission myPermission = new

FileIOPermission(FileIOPermissionAccess.Write, "C:\\aFile.txt");

Membrii clasei CodeAccessPermission

Toate permisiunile de acces la cod sunt derivate din clasa CodeAccessPermission.Metode ale clasei CodeAccessPermission

: * Assert - se presupune ca fragmentul de cod care apeleaza aceasta metoda poateaccesa resursele reprezentate de permisiune chiar daca apelantii aflati la un nivelsuperior in stiva de executie nu au aceasta permisiune

* Demand - impune faptul ca toti apelantii de la un nivel superior in stiva aupermisiunea de a accesa resursa reprezentata de aceasta permisiune

* Deny - interzice codului apelant al acestei metode sa acceseze resursa reprezentatade aceasta permisiune

* PermitOnly - Interzice codului apelant sa acceseze resursa reprezentata depermisiune, cu exceptia unui subset al resursei specificat de permisiune

* RevertAll - elimina efectul tuturor metodelor Assert, Deny si PermitOnly apelateanterior

* RevertAssert - elimina apelurile Assert anterioare

* RevertDeny - elimina apelurile Deny anterioare

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 171 of 203

Page 172: Aplicatii in Visual.net

* RevertPermitOnly - elimina apelurile PermitOnly anterioare

Securitate imperativa de acces la cod

Securitatea imperativa actioneaza la run-time.

Metoda Demand este si, in acest caz, metoda principala utilizata. Permisiunea de aaccesa resurse protejate este verificata de common language runtime, care consultapolitica de securitate a assembly-ului setata de administratorul sistemului. La apelulmetodei Demand a unui obiect de tip permisiune, se verifica in stiva de executie dacafiecare dintre apelantii de pe nivele superioare au garantata permisiunea de a accesaresursele reprezentate de permisiune. Deci, un assembly poate avea o metoda careapeleaza o alta metoda protejata de o permisiune de acces la cod. Daca apelul catrecea de-a doua metoda provine de la un assembly securizat (trusted), apelul va fipermis si resursa protejata va putea fi utilizata. In cazul unui assembly untrusted, carenu are permisiunea necesara, apelul se va solda cu esec.

Exemplu:

// permisiune care reprezinta acces

// nerestrictionat la sistemul de fisiere

FileIOPermission myPermission = new

FileIOPermission(PermissionState.Unrestricted);

// toti apelantii acestui cod au permisiune pentru

// acces nerestrictionat la sistemul de fisiere

myPermission.Demand();

Metoda Deny interzice apelantilor codului accesul la resursa protejata, chiar dacapermisiunea era garantata de common language runtime. De exemplu:

FileIOPermission myPermission = new

FileIOPermission(PermissionState.Unrestricted);

myPermission.Deny();

Metoda PermitOnly interzice accesul la resurse, cu exceptia celor specificate depermisiune. Exemplu:

// o permisiune care garanteaza accesul la un

// fisier specific

FileIOPermission myPermission = new

FileIOPermission(FileIOPermissionAccess.Write,"C:\\myFile.txt");

myPermission.PermitOnly();

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 172 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 173: Aplicatii in Visual.net

Metoda Assert. Exemplu:

// acces nerestrictionat la

// sistemul de fisiere

FileIOPermission myPermission = new

FileIOPermission(PermissionState.Unrestricted);

// asertiune: acces la sistemul de fisiere

myPermission.Assert();

Metoda statica Revert: elimina toate apelurile Deny, Assert sau PermitOnly anterioare.Exemplu:

ReflectionPermission.RevertAll();

EnvironmentPermission.RevertDeny();

FileIOPermission.RevertAssert();

MessageQueuePermission.RevertPermitOnly();

Securitate declarativa de acces la cod

Ca si in cazul securitatii role-based , fiecare permisiune de acces la cod are un atributcorespunzator care poate fi atasat metodelor sau claselor pentru a specifica actiuni desecuritate. Aditional, se pot specifica permisiuni pentru intregul assembly.

Se specifica in cadrul atributelor o valoare SecurityAction (nu un rol, cum era in cazulsecuritatii role-based).

Exemplu:

[FileIOPermission(SecurityAction.Deny)]

public class aClass

{

// Class implementation omitted

}

Flagurile SecurityAction.Demand, SecurityAction.Deny, SecurityAction.Assert siSecurityAction.PermitOnly corespund metodelor Demand, Deny, Assert si PermitOnly.Exista si actiuni aditionale de securitate, in contextul securitatii declarative.SecurityAction.LinkDemand impune primului apelant al clasei sau metodei sa aibapermisiunea ceruta. SecurityAction.InheritanceDemand verifica daca clasele derivateale acestei clase sau care suprascriu metoda au permisiunea potrivita.

Flag-uri asociate intregului assembly:

- SecurityAction.RequestMinimum executa o cerere catre common language runtime

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 173 of 203

Page 174: Aplicatii in Visual.net

sa indeplineasca o anumita permisiune. In cazul unui raspuns negativ, assembly-ul nuse va executa.

- SecurityAction.RequestOptional este similar, dar assembly-ul va rula chiar dacapermisiunea nu este indeplinita.

- SecurityAction.RequestRefuse cere assembly-ului sa interzica permisiuneaspecificata. Pentru aceste actiuni, se utilizeaza directiva assembly:

[assembly: FileIOPermission(SecurityAction.RequestMinimum)]

[FileIOPermission(SecurityAction.Assert,

Write="C:\\myFile.txt")]

public void WriteFile()

{

// implementare...

}

Sinteza

* securitate role-based

* securitate de acces la cod

* clasa Permission

* interfata IPermission

* securitate imperativa si declarativa

* obiecte Principal (pentru securitate role-based )

* resurse sistem (pentru acces la cod)

* directiva assembly

4. Instalarea si rularea aplicatiilor

Dupa fazele de proiectare, dezvoltare, compilare si executie a unei aplicatii VisualStudio .NET, urmeaza, in mod firesc, o procedura de instalare si rulare a aplicatiilor peo anumita masina. Iata, pe scurt, scenarii posibile in cadrul unei astfel de proceduri:

* In anumite conditii, o aplicatie .NET se poate instala utilizand comanda XCOPYpentru a copia directorul principal si toate subdirectoarele aplicatiei pe o anumitamasina. Acest lucru este posibil (va avea efectul scontat) numai daca pe masinarespectiva este instalat .NET Framework si daca aplicatia nu are referinte catreassembly-uri sau resurse partajate. In multe circumstante, XCOPY nu constituie omodalitate viabila de instalare a aplicatiilor.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 174 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 175: Aplicatii in Visual.net

* Utilizand Visual Studio .NET, se pot crea Windows Installer setup projects sauWindows Installer merge modules. Un proiect de setup poate fi executat pe uncalculator care are instalat Windows Installer 1.5 si care contine toata informatianecesara instalarii unei aplicatii pe un calculator client. Un merge module este utilizatpentru impachetarea fisierelor DLL si nu poate fi instalat aparte, ci numai princoncatenare la un proiect de setup.

Setup Project Wizard permite crearea unui proiect de setup care poate fi apoi,eventual, configurat intr-un mediu integrat de dezvoltare (IDE). Pentru a asocia unproiect de setup unei aplicatii, se selecteaza meniul File, Add Project, New Project,Setup And Deployment Projects, Setup Project Wizard. Se creaza astfel un proiect desetup, specificandu-se tipul outputului proiectului si alte fisiere aditionale care vor fiadaugate la proiect.

* Pot fi configurate proprietatile de Build ale proiectului, utilizand Setup Property Pages.Se poate specifica modalitatea de impachetare a fisierelor, setarile de compresie, dacase va crea sau nu un bootstrapper, directorul de instalare si setarile Authenticode(referitoare la semnatura aplicatiei).

- Output File Name: reprezinta locatia in care va fi plasat fisierul de instalare rezultat inultima construirii proiectului de setup. Acest fisier are extensia .msi, in cazul aplicatiilorWindows Installer si .msm, pentru Windows Installer merge modules.

- gruparea si compresia fisierelor - se pot utiliza fisiere de tip Cabinet (.cab), pentruintegrarea fisierelor de instalare in fisiere de o anumita dimensiune (de exemplu,salvarea fisierelor de instalare in fisiere .cab de dimensiune 1.44M)

- optiunea Bootstrapper - se selecteaza in cazul in care pe masina pe care se vainstala proiectul nu exista Windows Installer 1.5, avand ca efect instalarea acestuiprogram, adaugand la proiectul de instalare 4 fisiere aditionale: Setup.exe,InstMsiA.exe, InstMsiW.exe si Setup.ini.

* Dupa ce proiectul de instalare a fost construit, poate fi distribuit intr-o varietate demoduri: cd-uri, dvd-uri, dischete, prin retea, pe web etc.

Aplicatiile de tip setup prezinta un nivel inalt de configurabilitate. Pot fi setateproprietatile care furnizeaza informatii legate de originea aplicatiei care va fi instalate sicomportamentul aplicatiei la design-time, in fereastra Properties.

• proprietate Register ofera posibilitatea inregistrarii unei componente COM sau a unuifont pe durata instalarii aplicatiei

• File System Editor permite editarea sistemului de fisiere de pe masina pe care seinstaleaza aplicatia (target)

• Registry Editor permite adaugarea/editarea intrarilor din registrii masinii target

• File Types Editor permite crearea asocierilor dintre fisiere si programe de pe masinatarget (exemplu: specificarea programului care va deschide implicit fisiere de tip .wav- Winamp, Media Player etc).

• User Interface Editor faciliteaza personalizarea interfetei programului de instalare

• Custom Actions Editor permite stabilirea unor actiuni personalizate pe duratainstalarii (fragmente de cod care se vor executa ca raspuns la anumite evenimentelansate pe durata instalarii)

• Launch Conditions Editor permite adaugarea de criterii/conditii de cautare si executie

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 175 of 203

Page 176: Aplicatii in Visual.net

(conditiile sunt impuse masinii target, se pot cauta fisiere, intrari in registri saucomponente Windows Installer; in functie de respectarea conditiilor impuse si/saurezultatele cautarii, se permite sau nu executia anumitor actiuni la instalare)

• utilitarul Ngen.exe permite crearea unei imagini native a aplicatiei/assembly-ului (lajit-compilare, fisierele sunt compilate in cod nativ, ceea ce permite maximum deeficienta, viteza si utilizare a resurselor; Ngen.exe creaza o imagine nativa aaplicatiei, ceea ce duce la posibilitatea obtinerii acestor avantaje)

• utilitarul Permview.exe permite vizualizarea permisiunilor asociate unui assembly

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 176 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 177: Aplicatii in Visual.net

Section 12. XML, Web Services - XI

1. Visual Studio .NET si XML

XML

Xml (eXtensible Markup Language) este un limbaj care permite definirea documentelorce contin informatii intr-un mod structurat. Informatia structurata dintr-un document xmlare atat continut (cuvinte, imagini, etc.), cat si o indicatie despre rolul pe care il are acelcontinut (de exemplu continutul din sectiunea header are alt rol fata de cel din footer,care la randul lui e diferit de continutul dintr-un tabel al unei baze de date). Toatedocumentele au o anumita structura. Aceste structuri se construiesc utilizandmarcatori. W3.org se ocupa de standardizarea XML-ului, si specificatiile complete aleacestui limbaj se afla la adresa http://www.w3.org/TR/WD-xml .

XML e la fel cu HTML?

Nu. In HTML, atat multimea de tag-uri (marcatori), cat si semantica asociata fiecaruitag sunt predefinite. Spre exemplu <H1> va reprezenta intotdeauna un header de nivel1, iar tag-ul <documentHTML> nu are nici un sens (nu are asociata nici o valoaresemantica). Standardul XML nu specifica nici semantica si nici multimea de tag-uri alelimbajului. De fapt XML este un metalimbaj pentru definirea limbajelor bazate pemarcatori (markup language). Cu alte cuvinte XML permite definirea de tag-uri precumsi relatia dintre acestea. Deoarece nu exista o multime de tag-uri predefinita, nu existanici o semantica asociata cu acestea. Definirea semantica documentelor XML este osarcina a aplicatiilor care folosesc documentelor respective sau a foilor de stiluri(stylesheet).

Definitii XML

* DTD - validarea unui document XML este realizata folosind DTD (Document TypeDefinition)

* XSL - Extensible Style Language este un limbaj de stiluri care permite asocierea uneisemantici fiecarui nod dintr-un document XML

* XML Pointer Language (XPointer) and XML Linking Language (XLink) - acestedoua tehnologii definesc o metoda standard pentru reprezentarea legaturilor dintreresurse. Spre deosebire de asocierile simple, cum ar fi tagul HTML <a>, XMLimplementeaza un mecanism de a defini legaturi intre mai multe resurse. XPointerdescrie modul de adresare a acestor resurse, in timp ce XLink descrie modul in carepot fi asociate doua sau mai multe resurse.

Avantaje XML

- XML descrie continutul si modul de afisare al continutului;

- informatia este mai usor de gasit si manipulat daca este in format XML;

- XML ofera facilitati multiple si imbunatatite de prezentare (de exemplu folosindbrowserele)

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 177 of 203

Page 178: Aplicatii in Visual.net

XML si .Net .Net Framework pune la dispozitia programatorilor un set de clase pentrumanipularea documentelor XML. Aceste clase se afla, in marea lor majoritate, in spatiulde nume System.Xml.

Principalele clase din System.Xml sunt:

* XmlTextReader - permite accesul rapid, forward only, la continutul unui documentXML;

* XmlNodeReader - clasa care furnizeaza un XmlReader pentru un subarbore DOM;

* XmlValidatingReader - permite validarea documentelor XML folosind scheme DTD,XSD si XDR;

* XmlTextWriter - clasa folosita pentru generarea de documente XML;

* XmlDocument - clasa care implementeaza specificatiile DOM

* XmlDataDocument - furnizeaza o implementare a unui XmlDocument care poate fiasociat cu un DataSet. Acest document poate fi apoi manipulat folosind atatreprezentarea relationala furnizata de DataSet, cat si reprezentarea sub forma dearbore a unui XmlDataDocument;

* XPathDocument - permite procesari XSLT rapide asupra unui document XML;

* XslTransform - permite transformari XSLT asupra unui document XML;

* XmlSchema - permite crearea, pe durata rularii programului, a schemelor XSD,respectand specificatiile W3C XSD;

* XmlSchemaCollection - furnizeaza o multime de scheme XSD si XDR (XMl DataReduced). Aceste scheme, incarcate in memorie, permit o validare rapida pe durataparsarii pentru XmlValidatingReader.

Citirea unui fisier XML

Clasa XmlReader furnizeaza un API (Application Program Interface) pentru parsareadocumentelor XML. O implementare a acestei clase este XmlTextReader. De obicei,se foloseste XmlTextReader daca se doreste accesul rapid la un document XML, faraoverheadul introdus de construirea arborelui DOM.

XmlTextReader reader = new XmlTextReader ("books.xml");

In exemplul anterior, documentul XML este incarcat dintr-un fisier. XmlTextReaderfurnizeaza constructori si pentru incarcarea din stream-uri. Un stream este oreprezentare abstracta a unui dispozitiv de intrare/iesire, care este sursa sau destinatiadatelor. Un stream este independent de dispozitivul din care citeste/scrie astfel încâtprogramul nu necesita modificari daca sursa streamului se schimba. In exemplulurmator este prezentata metoda de incarcare a unui document XML dintr-un stream:

StringReader stream;

XmlTextReader reader = null;

try

{

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 178 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 179: Aplicatii in Visual.net

stream = new StringReader ("<?xml version='1.0'?>" +

"<book>some book</book>");

reader = new XmlTextReader (stream);

//proceseaza documentul incarcat

if (reader != null)

reader.Close();

}

In acelasi timp, un document XML poate fi incarcat de pe web, furnizand ca sursa oadresa web:

private const string URLString = "http://localhost/books.xml";

XmlTextReader reader = new XmlTextReader (URLString);

O data incarcat fisierul, XmlTextReader citeste secvential (folosind metoda Read())continutul xml. Metoda Read() returneaza valoarea false cand nu mai este nimic decitit:

while (reader.Read())

{

// do something... ;

}

Pentru a procesa informatiile XML, fiecare inregistrare (nod) citita din fisier are un tip(ce poate fi obtinut folosind proprietatea NodeType).

while (reader.Read())

{

switch (reader.NodeType)

{

case XmlNodeType.Element:

Console.Write ("<" + reader.Name);

while (reader.MoveToNextAttribute())

Console.Write(" " + reader.Name + "='" + reader.Value + "'");

Console.Write (">");

break;

case XmlNodeType.DocumentType:

Console.WriteLine (reader.NodeType + "<" + reader.Name + ">" +reader.Value);

break;

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 179 of 203

Page 180: Aplicatii in Visual.net

}

}

Valoarea intoarsa de NodeType depinde de clasa care este utilizata. De exemplu,XmlTextReader nu intoarce niciodata XmlNodeType care reprezinta un nod Document,DocumentFragment, Entity, EndEntity sau Notation. Tipul continut de NodeType esteconform specificatiilor W3C DOM. Proprietatea Depth intoarce nivelul nodului curent inarborele Xml. Aceste informatii sunt utilizate in formatarea unui document XML. Nodulradacina are Depth = 0. Combinand informatiile furnizate de proprietatile Name, Valuesi Depth, se poate executa scrierea formatata a unui document XML la consola sauintr-un fisier.

Sinteza:

- XmlTextReader furnizeaza acces rapid, forward only, la continutul XML;

- XmlTextReader implementeaza specificatiile W3C;

- XmlTextReader furnizeaza constructori pentru citirea unui document XML dintr-unfisier, stream sau XmlReader;

- metoda Read citeste secvential toate nodurile din documentul XML;

- pentru nodurile element, atributele pot fi obtinute folosind metodaMoveToNextAttribute(), ceea ce furnizeaza tot o citire secventiala a atributelor;

- atributele sunt reprezentate ca o lista atasata nodului curent;

Scrierea unui fisier XML

Pentru scrierea unui document XML, se folosesc clase derivate din XmlWriter.XmlWriter furnizeaza un API care permite scrierea intr-un fisier, intr-un stream sauintr-un TextWriter. O clasa derivata din XmlWriter este XmlTextWriter. XmlTextWriternu construieste arborele DOM, furnizand astfel un acces rapid la output (fisier, stream,etc) si inlaturand overhead-ul introdus de arborele DOM. Aceasta clasa executa o seriede verificari si validari ale documentului xml, pentru a asigura structura corecta adocumentului care este scris. Atunci can una din aceste validari esueaza (documentulnu este un document xml valid), se arunca o exceptie, fiind recomandata specificareade handleri care sa trateze aceste exceptii.

XmlTextWriter myXmlTextWriter = new XmlTextWriter ("books.xml",null);

Cel de-al doilea parametru al contructorului precizeaza care este encoding-ul fisierului.Daca acesta este null, se considera ca fisierul este scris in format UTF-8 . Exemplulurmator demonstreaza modul in care poate fi scris un singur element (book) intr-unfisier xml:

myXmlTextWriter.Formatting = System.Xml.Formatting.Indented;

myXmlTextWriter.WriteStartDocument(false);

myXmlTextWriter.WriteDocType("bookstore", nothing, "books.dtd",nothing);

myXmlTextWriter.WriteComment("Cartile lui Mark Twain");

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 180 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 181: Aplicatii in Visual.net

myXmlTextWriter.WriteStartElement("bookstore");

myXmlTextWriter.WriteStartElement("book", null);

myXmlTextWriter.WriteAttributeString("genre","autobiography");

myXmlTextWriter.WriteAttributeString("publicationdate","1979");

myXmlTextWriter.WriteAttributeString("ISBN","0-7356-0562-9");

myXmlTextWriter.WriteElementString("title", null, "TheAutobiography of Mark Twain");

myXmlTextWriter.WriteStartElement("Author", null);

myXmlTextWriter.WriteElementString("first-name", "Mark");

myXmlTextWriter.WriteElementString("last-name", "Twain");

myXmlTextWriter.WriteEndElement();

myXmlTextWriter.WriteElementString("price", "7.99");

myXmlTextWriter.WriteEndElement();

myXmlTextWriter.WriteEndElement();

//Scrie tot textul XML si inchide fisierul

myXmlTextWriter.Flush();

myXmlTextWriter.Close();

Scrierea diverselor elemente ale unui document xml se face folosind functiispecializate: WriteDocType, WriteComment, WriteStartElement, WriteAttributeString,WriteElementString, WriteEndElement, etc. Se observa ca exista o corespondenta intreapelul functiilor WriteStart... si apelul functiilor WriteEnd....

Sinteza

- XmlTextWriter permite scrierea de documente XML care respecta specificatiile W3C;

- XmlTextWriter are constructori care permit scrierea intr-un fisier, stream sauTextWriter;

- pentru fiecare tip de nod exista o functie permite scrierea acestuia.

Validarea unui document XML in timpul citirii

Utilizand clasa XmlValidatingReader se poate face validarea unui document XML intimpul citirii sale. Validarea se poate face conform definitiilor dintr-un fisier DTD, XSDsau XDR. Pentru a specifica exact tipul de validare se foloseste proprietateaValidationType, astfel (tip de validare - descriere): - Auto: implicit

- None: nu se face validare in timpul parsarii

- DTD: validare conforma definitiilor DTD

- Schema: validare conform definitiilor XSD

- XDR: validare conform definitiilor XDR

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 181 of 203

Page 182: Aplicatii in Visual.net

Exemplu:

XmlTextReader myXmlTextReader = new XmlTextReader (document1);

XmlValidatingReader myXmlValidatingReader = newXmlValidatingReader(myXmlTextReader);

myXmlValidatingReader.ValidationType = ValidationType.DTD;

Parserul nu se opreste la erorile de validare, ci in cazul in care documentul XML nueste bine format (nu respecta standardul XML). Datorita acestui fapt este permisadetectarea tuturor erorilor de validare printr-o singura parsare, si nu este necesarareparsarea documentului. In exemplul urmator este prezentat modul in care esteapelata o metoda handler atunci când se intalneste o eroare la validare. Atasareaacestui handler se face folosind clasa ValidationEventHandler inainte de a incepecitirea documentului XML. Daca nu este furnizat un astfel de handler,XmlValidatingReader arunca o exceptie de tipul XmlSchemaException atunci cand seintalneste prima eroare.

private void Validate ()

{

try

{

// setarea handler-ului pentru erorile la validare

myXmlValidatingReader.ValidationEventHandler += new

ValidationEventHandler (ValidationEvent);

while (myXmlValidatingReader.Read())

{

// instructiuni...

}

}

catch (Exception e)

{

Console.WriteLine ("Exception: {0} ", e.ToString());

}

}

private void ValidationEvent (object, errorID,ValidationEventArgs) args)

{

Console.Write ("Eroare la validare: " + args.Message);

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 182 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 183: Aplicatii in Visual.net

}

Sinteza:

- validarea poate fi efectuata folosind scheme DTD, XSD si XDR

- validarea are loc pe durata efectuarii operatiilor de citire si parsare

- handlerul ValidationEventHandler trebuie initializat pentru a primi toate notificarilelegate de erorile de validare aparute

- erorile de validare nu stopeaza parsarea documentului XML

2. Servicii Web

Introducere...

XML Web services reprezinta componente program care permit construirea de aplicatiiscalabile, independente de platforma. Serviciile Web permit aplicatiilor sa interschimbemesaje utilizand protocoale standard cum ar fi HTTP, XML, XSD, SOAP si WSDL.

Pot fi create servicii web care sa ofere functionalitati specifice aplicatiilor client pe web.Mediul de dezvoltare integrat Visual Studio .NET ofera posibilitatea crearii de proiectepentru aplicatii desktop distribuite, aplicatii Web applications si servicii XML Web.

Dupa crearea unui serviciu Web, acesta trebuie instalat pe un server Web pentru adeveni disponibil aplicatiilor care doresc sa utilizeze acest serviciu. Instalarea unuiserviciu Web pe un Web server se poate realiza prin copierea fisierelor asociate peserverul Web.

Mecanismul de descoperire a serviciilor XML Web permite aplicatiilor client salocalizeze documentele care descriu unserviciu XML Web service. Se returneaza,astfel, catre client, un document care descrie serviciul web. Acest document este scrisin WSDL (Web Service Description Language) si contine informatii despre capabilitatileserviciului XML Web, locatia si modalitatea in care se poate interactiona cu acesta.

Dupa crearea si instalarea unui serviciu XML Web, orice aplicatie va avea, teoretic,permisiunea de a accesa si consuma servicul respectiv. Aplicatia care consuma unserviciu Web este cunoscuta sub numele de client al serviciului Web. Un client poate fio componenta, serviciu sau o aplicatie desktop.

Crearea unui serviciu web in Visual Studio .NET

Crearea unu serviciu web este foarte usoara. De fapt, folosind Visual Studio se poatecrea un serviciu web fara sa fie necesara scrierea de cod. Exemplul urmator va crea unserviciu web numit MyService, in directorul WebServices.

La crearea proiectului, se alege ca optiune Web Service. Va fi creat un nounamespace, numit MyService, si cateva clase care vor oferi functionalitatea serviciului

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 183 of 203

Page 184: Aplicatii in Visual.net

web.

Implicit sunt create urmatoarele clase:

- Global (in fisierul Global.asax) - derivata din HttpApplication (acest fisier esteechivalent cu fisierul Global.asa din ASP)

- WebService1 (in fisierul WebService1.cs) - clasa derivata dinSystem.Web.Services.WebService; aceasta este clasa care implementeaza logicaserviciului web care urmeaza a fi realizat. Metodele din aceasta clasa vor fi apelateulterior. Componenta webservice va fi creata in directorul bin si se va numiMyService.dll. Initial, clasa creata de Visual Studio .Net arata astfel:

namespace MyService

{

...

/// <summary>

/// Summary description for WebService1

/// </summary>

[WebService(Namespace="http://tempuri.org",

Description="This is a demonstration WebService.")]

public class WebService1 : System.Web.Services.WebService

{

public WebService1()

{

//CODEGEN: This call is required by the ASP+ Web ServicesDesigner

InitializeComponent();

}

...

[WebMethod]

public string HelloWorld()

{

return "Hello World";

}

}

}

Implicit este creata si o metoda HelloWorld (comentata). Daca se decomenteazaaceasta metoda avem un prim serviciu web functional (care va afisa un simplu mesaj).

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 184 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 185: Aplicatii in Visual.net

Orice serviciu web trebuie asociat cu un namespace. Implicit namespace-ul estehttp://tempuri.org. Daca proiectul este compilat in starea actuala vom primi un mesajprin care ni se cere sa alegem un alt namespace. De obicei acest namespace estenumele site-ului/serverului unde acest serviciu web este disponibil. Pentru a testaproiectul, se executa click dreapta pe fisierul WebService1.asmx in Solution Explorer sidin meniu se alege "View in Browser". Este afisata o pagina web care are un buton"Invoke". La apasarea acestui buton, este apelata functia HelloWorld care intoarce unstring.

In continuare vom extinde acest exemplu. Vom defini o metoda care intoarce un vectorde structuri definite de cadrul aplicatiei. Intai vom defini structura:

public struct ClientData

{

public String Name;

public int ID;

}

si apoi o metoda GetClientData. De remarcat, folosirea atributului WebService pentruaceasta metoda. Acesta atribut face ca metoda sa poata fi accesibila dintr-un serviciuweb.

[WebMethod]

public ClientData[] GetClientData(int Number)

{

ClientData[] Clients = null;

if (Number > 0 and Number <= 10)

{

Clients = new ClientData[Number];

for (int i = 0 to Number)

{

Clients[i].Name = "Client " + i.ToString();

Clients[i].ID = i;

}

}

return Clients;

}

Daca deschidem fisierul .asmx dupa compilare, vom vedea un formular care permiteintroducerea unei valori pentru parametru. Introducand o valoare care nu reprezinta unnumar intreg, va fi generata o eroare. Daca se introduce o valoare care nu este in

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 185 of 203

Page 186: Aplicatii in Visual.net

intervalul 0-10, se va obtine un vector nul. Introducand o valoare intre 0-10 se va obtineun xml cu elemente de tipul:

<clientData>

<Name>Client 0</Name>

<ID>0</ID>

</clientData>

Crearea unui serviciu web folosind Visual Studio .Net este o operatie relativ facila, cuun grad mare de utilitate.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 186 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 187: Aplicatii in Visual.net

Section 13. ASP.NET - XII

1. Introducere

Odata cu aparitia Internetului si a infrastructurii World-Wide-Web nascuta in anii 90,ideea si solutia aplicatiilor distribuite a capatat o alta culoare. Aplicatiile distribuite auluat nastere in urma vizualizarii clare a lumii informatice, a imposibilitatii de a aveadispozitive informatice care sa ruleze aplicatii monopost complexe, lucru care evidentnu a condus decat la o centralizare a informatiei si a aplicatiilor in general. Bazata pemodelul client/server, platforma WWW ofera o infrastructura viabila si testata caserviciu al retelei Internet si promite la nivel de client o interfata standardizata, chiarindependenta de platforma, comuna pentru vizualizarea informatiilor Web, interfatacunoscuta sub numele de browser sau navigator Web.

Modelul de realizare a aplicatiior Web a cunoscut o intreaga evolutie a tehnologiilor deprogramare la nivel de server.

Putem enumera astfel:

* solutia CGI (Common Gateway Interface) reprezinta o serie de script-uri executate peserverul WWW. Acestea pot fi scrise in orice limbaj de programare (interpretat saucompilat) cu respectarea urmatoarelor restrictii: programul scrie datele la iesireastandard si genereaza antete care permit serverului Web sa interpreteze corect iesireascriptului, conform specificatiilor HTTP (de exemplu, se pot folosi limbaje precum bash,Perl, C/C++, Delphi). Neajunsul CGI-urilor il reprezinta faptul crearii unui nou proces peserverul Web pentru fiecare cerere si restrictionarea task/fisier executabil.

* solutia ISAPI (Internet Server API) reprezinta o alternativa CGI pe platformeWindows. Dezvoltatorii Win32 pot scrie un program care sa comunice direct cu aceastainterfata pentru a face orice lucru posibil cu CGI, pot folosi ISAPI pentru a obtine datedin formulare si pentru a trimite continut HTML la client. Codul la nivel de server poatefi scris in oricare limbaj cu suport pentru DLL-uri Windows, ca C/C++, Java, VisualBasic, rezultatul compilarii fiind un fisier .dll. Fata de CGI, ISAPI ruleaza in acelasispatiu de adrese cu serverul HTTP, are acces la toate resursele serverului HTTP, pot fiincluse mai multe task-uri intr-un .dll si nu creeaza procese aditionale pentru rezolvareacererilor clientilor Web. O alternativa la ISAPI este NSAPI-utilizabila in cadrul serveruluiWeb Netscape.

* solutia PHP (1994) sau ASP (1996) marcheaza un salt in dezvoltarea aplicatiilorWeb. Desi difera din punct de vedere al sintaxei, ambele limbaje sunt interpretate,codul lor fiind stocat in fisiere externe cu extensia .php/.asp. De fapt, ASP nu ofera unlimbaj nou, ci se bazeaza pe limbajele VBScript si JScript. Un fisier PHP/ASP poate ficombinat cu date de tip text, marcatori HTML si comenzi script. in momentul executiei,in urma cererii unui client Web, fisierul este procesat, fiecare script din cadrul lui esteinterpretat si rezultatul executiei este introdus inapoi in fisierul static HTML inainte carezultatul sa fie trimis catre browser. Mai mult, in sprijinul programatorului, limbajelepun la dispozitia acestuia o serie de metode si obiecte care usureaza lucrul cucookie-uri, cu bazele de date (Oracle, MSSQL, MySQL, etc.), care preiau elegantintrarile unui formular HTML si le proceseaza pe server, care preiau informatii despreutilizator (clientul Web), care trimit informatii la utilizator, care stocheaza informatiidespre sesiunea unui utilizator (Session), care partajeaza informatii intre utilizatorii unei

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 187 of 203

Page 188: Aplicatii in Visual.net

aplicatii (Application) s.a.m.d.. Mai nou, din partea PHP-ului, incepand cu versiunea4.0, acesta ofera suport pentru programarea obiectuala: incapsularea datelor,mostenirea si polimorfismul. Aceste modele completeaza destul de bine suportuldezvoltarii aplicatiilor Web, insa aduc unele limitari: sunt lente deoarece la fiecareaccesare fisierele sunt procesate si interpretate (in loc sa fie compilate), nu suntcapabile sa construiasca controale reutilizabile care sa incapsuleze functionalitaticomplexe pentru interactiunea cu utilizatorul.

* JSP (JavaServer Pages) face parte din familia Java si reprezinta o tehnologie carepermite crearea de aplicatii Web independente de platforma. JSP separa interfatautilizator de continutul generat dinamic permitand schimbarea intregului sablon alsite-ului WEB fara a altera informatiile afisate. Tehnologia utilizeaza marcatori XML siscripturi scrise in limbajul de programare Java pentru a incapsula logica aplicatiei caregenereaza continutul paginilor WEB. JSP-urile sunt o extensie a tehnologiei JavaServlet. Servlet-urile sunt independente de platforma 100% si reprezinta module lanivel de server care se integreaza in cadrul unei aplicatii Web si care pot fi utilizatepentru a extinde capabilitatile unui server WEB. Tehnologia JSP si servlet-urile ofera oalternativa pentru crearea aplicatiilor WEB fata de alte limbaje de scripting/programarea aplicatiilor WEB, oferind independenta de platforma, performanta, separarea logiciiaplicatiei de partea de interfata utilizator, administrare usoara si extensibilitate.

Astfel, odata cu aparitia noii platforme .NET, Microsoft a adus o noua tehnologie inprogramarea si dezvoltarea aplicatiilor dinamice pentru Web, si anume, ASP.NET. Desinu putem spune clar ca ASP.NET este o versiune urmatoare a ASP-ului, acestapastreaza compatibilitatea cu aplicatiile scrise in ASP.

2. Aplicatii ASP.NET. WebForms

Anatomia unei aplicatii ASP.NET

O aplicatie Web in ASP.NET include un numar diferit de fisiere si directoare, acesteaincluzand la randul lor pagini ASP.NET, controale utilizator, fisiere ale serviciilor WebXML, fisiere de configurare si assembly-uri. Un assembly este formula atomica princare o aplicatie este reprezentata la runtime.

Paginile ASP.NET, numite si WebForms-formulare Web, permit crearea de interfeteutilizator pentru aplicatiile Web, prezentand informatia catre orice browser saudispozitiv client. Ele reprezinta un model scalabil de programare la nivelul serveruluipentru a genera dinamic pagini Web.

WebForms-modelul formularelor Web in ASP.NET

Pentru a prezenta informatii in navigatorul clientului folosim formularele Web ASP.NETcare ofera o abstractizare in modelul de programare, un model orientat obiect si bazatpe evenimente. Acest mediu de lucru beneficiaza de toate facilitatile oferite deplatforma .NET (siguranta tipurilor, mediu de executie controlat, mostenire) sireprezinta o inlocuire a clasicelor formulare HTML.

Asemanator modelului de programare WinForms (oferit de aplicatiile clasice in VisualC++ sau Visual Basic) o pagina WebForms este formata din doua parti: componenta

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 188 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 189: Aplicatii in Visual.net

vizuala (furnizand interfata cu utilizatorul) si logica aplicatiei (oferind implementareaefectiva).

Componenta vizuala este reprezentata de un fisier cu extensia .aspx-actionand ca uncontainer pentru HTML, text static si controale server care pot fi afisate in browser, iarlogica aplicatiei este reprezentata de un fisier cu extensia .cs (pentru limbajul VisualC#) sau .vb (pentru Visual Basic.NET). Fisierele .aspx mai sunt referite ca paginiASP.NET. Aceasta tehnica de separare a codului de partea de prezentare este numita"code-behind programming", metoda care elimina anumite disfunctionalitati deprogramare aducand robustete si dezvoltare usoara a paginilor. Solutia oferita permitedetectarea erorilor de programare in timpul compilarii si nu in timpul primei accesari alepaginii Web si elimina codul "spagetti" dintr-un fisier HTML imbricat cu script-uri careera greu de scris si de intretinut.

Logica aplicatiei reprezinta in fapt o clasa care extinde functionalitatea claseiSystem.Web.UI.Page. Aceasta clasa contine metode care trateaza diferite evenimentece apar in timpul executiei formularului Web la server (de exemplu, daca metodaPage_Load este conectata la evenimentul Load al clasei de baza Page, atunci aceastaeste apelata la fiecare acces al unui formular Web), proprietati (de exemplu, prinproprietatea IsPostBack putem afla daca o pagina Web este la primul acces sau laaccesari ulterioare), atribute corespunzatoare unor controale din pagina WebForms sialte date membre necesare implementarii aplicatiei.

In ASP.NET, cu putine modificari, oricare pagina Web Forms poate fi reutilizata in altapagina ca un control server, numit prin extensie user controls. Controalele utilizatorofera la randul lor acelasi model abstract de programare, orientat pe obiecte si bazatpe evenimente, insa nu este posibila accesarea lor independenta, fiind necesare a fiincluse intr-o pagina WebForms. Clasa pe care o extinde un control utilizator esteSystem.Web.UI.UserControls, iar fisierul care implementeaza un astfel de control areextensia .ascx. Asemanator WebForm-urilor, controalele utilizator sunt compilate laprimul acces si stocate in memoria serverului pentru a reduce timpul de raspunscererilor succesive. Toate fisierele care fac parte din logica aplicatiei din cadrulpaginilor Web- codul din spate-sunt compilate intr-o biblioteca dinamica .dll, fiecarepagina Web fiind reprezentata de o clasa derivata din clasa System.Web.UI.Page.Pentru fisierele .aspx, la prima cerere a browser-ului, runtime-ul ASP.NET genereaza oa doua bilblioteca dinamica .dll, temporara, care contine o clasa ce mosteneste clasacorespunzatoare din primul assembly (.dll), iar in momentul rularii (executiei), cand unutilizator face o cerere a unei pagini, se executa .dll-urile asociate si rezultatul executieieste trimis la client intr-unul din limbajele HTML, XML, WML si ECMAScript (Jscript,JavaScript). Acest rezultat este influentat de capabilitatile navigatorului client, carepoate fi chiar un dispozitiv mobil, astfel paginile WebForms transmit cod HTMLcompatibil browser-ului. De altfel, in functie de browser, pentru Internet Explorer 5 sauulterior paginile WebForms pot fi programate pentru a beneficia de toate facilitatileacestuia.

Arhitectura ASP.NET suporta si un model asemanator ASP-ului, in care elementele deinterfata si codul se afla in acelasi fisier, functionalitatea fiind aceeasi cu cea oferita demodelul cu doua fisiere. Totusi, exista mici diferente, la compilare codul din pagina numai este compilat intr-un fisier separat, clasa din .dll-ul asociat paginii .aspx derivadirect din clasa System.Web.UI.Page. Acest model are avantajul ca poate fi usor deutilizat in dezvoltarea paginilor Web.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 189 of 203

Page 190: Aplicatii in Visual.net

Modelul de executie

Modelul de executie al paginilor .aspx este format din mai multe etape, pornind de lacererea clientului pana la procesul executat de server. Vom observa ca viteza deraspuns a unei cereri este optimizata dupa prima accesare.

La prima accesare a unei pagini .aspx, procesul de raspuns al serverului ASP.NETeste alcatuit din mai multi pasi. Acestia sunt:

- procesarea si interpretarea codului sursa

- trimiterea acestuia compilatorului

- ASP.NET invoca compilatorul in urma caruia rezulta unul sau mai multe assembly-uri(cod intermediar-IL), plasat apoi in assembly cache

- mediul de executie incarca in memorie si executa codul intermediar, iar rezultatul estetrimis la client

Elementele constitutive ale unui WebForm

O pagina WebForms contine un numar de comenzi denumite directive la nivel depagina care pot fi stocate in fisierele .aspx. Aceste directive au sintaxa @ <numedirectiva> si sunt incadrate de simbolurile <% si %> (reminiscenta ASP), pozitia lorfiind la inceputul paginii .aspx. Rolul lor este de a specifica anumite configuratii candeste procesata o pagina WebForms.

Paginile WebForms suporta urmatoarele directive:

@ Page - defineste atribute specifice paginii WebForms care sunt utilizate de analizorsi compilator (doar pentru fisiere .aspx).

@ Control - defineste atribute specifice controalelor utilizator care sunt utilizate deanalizor si compilator (doar pentru fisiere .ascx).

@ Import - importa un spatiu de nume explicit intr-o pagina sau control utilizator.

@ Implements - indica unei pagini sau control utilizator ca implementeaza o interfataspecifica .NET Framework.

@ Register - inregistreaza controale utilizator si controale obisnuite pentru a fi utilizateintr-un WebForms.

@ Assembly - creeaza legaturi catre assembly-uri in timpul compilarii, facanddisponibile clasele si interfetele din assembly-uri pentru a fi folosite in pagina.

@ OutputCache - declara politici de caching pentru controale dintr-o pagina sau usercontrol.

@ Reference - adauga referinte catre un fisier .aspx sau .ascx extern.

Ciclul de viata al unei pagini WebForms

Intr-o aplicatie Web, datorita naturii protocolului HTTP, procesul in care un browseracceseaza o resursa Web se rezuma la urmatorii pasi:

* se stabileste o legatura cu serverul Web care primeste cererea resursei;

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 190 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 191: Aplicatii in Visual.net

* resursa este procesata de server in functie de caracteristicile ei (e.g. script-uri ASP);

* rezultatul executiei este trimis la client;

* resursele ocupate de serverul Web la procesarea cererii sunt eliberate din memorie;conexiunea de la primul pas poate fi eliberata.

Datorita acestui model, paginile Web pot fi considerate lipsite de stari (stateless). Deobicei, un navigator prezinta informatii unui client intr-un formular electronic. Acesta(clientul) interactioneaza cu elementele din formular modificand anumite stari alecontroalelor, lucru care cauzeaza in final o trimitere a paginii pe server pentru a fiprocesate informatiile curente. Serverul proceseaza pagina conform modificarilor, apoireturneaza formularul browser-ului. Aceasta secventa este cunoscuta si sub numele deround trip.

Singurul eveniment provocat de utilizator pentru trimiterea formularului la server esterezultatul selectarii unui buton care cauzeaza un round trip. Din acest motiv,evenimentele in ASP.NET sunt limitate la evenimente de tip click, multe dintrecontroalele ASP.NET implementandu-le pentru diferite actiuni ale utilizatorului.

O pagina WebForms, la procesarea pe serverul Web, poate fi privita ca un programexecutabil pentru care iesirea standard o reprezinta browserul sau dispozitivul client. Inacest model, pagina trece printr-o serie de stagii de procesare: initializare, procesare sieliberare. In ordinea aparitiei, acestea sunt:

* Init, eveniment care initializeaza pagina si in care proprietatile controalelor suntactualizate. Aici este corect sa initializam controale care se adauga dinamic la paginasau variabile necesare inainte de initializarea paginii;

* Load poate fi numit locul in care utilizatorul isi initializeaza codul. Evenimentul estegenerat de fiecare data cand pagina este incarcata dupa ce controalele au fostinitializate la pasul anterior;

* Tratarea evenimentelor utilizator, reprezinta stagiul in care sunt tratate evenimentelegenerate de client cum ar fi: schimbarea unui text intr-un control, apasarea unui butonetc. Trebuie retinut ca aceste evenimente nu sunt tratate intr-o anumita ordine peserver, iar tratarea lor are loc dupa aparitia unui eveniment Click care trimite formularulla server (a unui submit);

* PreRender, eveniment care poate fi folosit pentru a face ultimile actualizari asuprapaginii Web inainte ca aceasta sa fie generata la client;

* Render, eveniment care genereaza la client reprezentarea HTML a paginii WebASP.NET incarcata la server;

* Unload este ultimul eveniment care se executa inainte ca pagina sa fie eliberata.Evenimentul este util de folosit atunci cand dorim sa efectuam ultimele operatii deeliberare a resurselor: inchiderea fisierelor, a conexiunilor la baza de date si eliberareaobiectelor din memorie.

3. Controale

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 191 of 203

Page 192: Aplicatii in Visual.net

Controale server

Unul din aspectele care vor duce la o dezvoltare rapida a interfetelor utilizator pentrupaginile WebForms il reprezinta controalele server. Putem prognoza un viitorasemanator evolutiei componentelor COM. Controalele server sunt folosite pentru acrea interfata-utilizator in paginile WebForms. Caracteristicile acestora pot fi rezumateastfel: expun un model orientat obiect, incapsuleaza un mecanism de persistenta astarilor intre round-trip-uri, genereaza evenimente client care sunt tratate la server, laexecutie genereza cod compatibil browser-ului sau dispozitivului destinat (detectat inmod automat).

Exista doua tipuri de baza in care pot fi impartite controalele:

* HTML Controls, reprezinta elemente HTML care pot fi programate la nivelul serveruluisi expun un model obiectual restrictionat la capabilitatile elementelor HTML pe care leafiseaza;

* Web Controls, aduc facilitati superioare controalelor HTML incluzand controale multmai complexe, cum ar fi controlul calendar, iar modelul obiect nu reflecta neaparatsintaxa HTML.

Prin extensie, se definesc alte doua tipuri de controale, si anume:

- controale de validare incapsuleaza functionalitati care permit validarea intrarilorutilizatorului. Acestea se ataseaza controalelor de intrare ale utilizatorului si furnizeazamai multe tipuri de verificari ale datelor. Functionalitatea controalelor de validare poatefi dedusa usor din numele claselor de care sunt reprezentate: CompareValidator,CustomValidator, RangeValidator, RegularExpressionValidator,RequiredFieldValidator. - controale utilizator sunt similare paginilor WebForms, diferindde acestea prin faptul ca fisierele au extensia .ascx si nu contin tagurile <HTML>,<BODY>, <FORM>, aceste elemente aflandu-se in pagina gazda.

Controale HTML

Primul set de controale, HTML Controls, reprezinta elemente HTML care continatribute facand posibila programarea lor pe server. Fiecare element HTML poate fiprogramat pe server prin adaugarea atributului runat="server" si asignarea unui atributID pentru a putea fi referit controlul ca membru de clasa in codul de pe server (aceastaabordare este posibila si la ASP). Acest ID trebuie sa fie unic in cadrul paginii Webpentru a nu aparea conflicte de nume in tratarea lor pe server. Controalele HTML suntinstante ale claselor definite in spatiul de nume System.Web.UI.HtmlControls si suntderivate direct/indirect din clasa de baza HtmlControl.

De exemplu, urmatorul cod creeaza un control de editare text care este reprezentat laruntime de clasa System.Web.UI.HtmlControls.HtmlInputText:

ASP.NET furnizeaza controale HTML predefinite, de la formulare pana la controalepentru introducerea de informatii text pe una sau mai multe linii, de la checkbox-uripana la controale de selectie, butoane de tip submit, list box-uri, tabele, imagini si altecontroale corespunzatoare elementelor HTML.

Cand un WebForms continand controale HTML este procesat pe server, se creeazacate o instanta pentru fiecare control, iar atributele acestora devin proprietati aleclaselor corespunzatoare. Atributele nerecunoscute sunt ignorate, dar sunt accesibile

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 192 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 193: Aplicatii in Visual.net

pe server folosind colectia Attributes a clasei controlului.

Controalele HTML ASP.NET sunt utile atunci cand dorim sa convertim o aplicatieclasica HTML sau ASP la ASP.NET pentru a putea programa controalele la nivel deserver. Mai mult, ele sunt o alegere buna atunci cand dorim sa programam controlulatat la client cat si la server deoarece sintaxa lor, in ambele parti, este identica (sunttratate ca text simplu). In schimb, acestea prezinta si dezavantaje, cum ar fi faptul catoate valorile controalelor sunt siruri de caractere, deci nu se aplica siguranta tipuriloroferita de platforma .NET, iar suportul pentru detectarea tipului navigatorului clientlipseste.

Tabel: corespondenta dintre elementele HTML si controalele HTML ASP.NET

Tag Control HTMLcorespunzator

<a runat="server"> HtmlAnchor

<button runat="server"> HtmlButton

<form runat="server"> HtmlForm

<img runat="server"> HtmlImage

<input type="button" runat="server"> HtmlInputButton

<input type="reset" runat="server"> HtmlInputButton

<input type="submit" runat="server"> HtmlInputButton

<input type="checkbox" runat="server"> HtmlInputCheckBox

<input type="file" runat="server"> HtmlInputFile

<input type="hidden" runat="server"> HtmlInputHidden

<input type="image" runat="server"> HtmlInputImage

<input type="radio" runat="server"> HtmlInputRadioButton

<input type="password" runat="server"> HtmlInputText

<input type="text" runat="server"> HtmlInputText

<select runat="server"> HtmlSelect

<table runat="server"> HtmlTable

<td runat="server"> HtmlTableCell

<th runat="server"> HtmlTableCell

<tr runat="server"> HtmlTableRow

<textarea runat="server"> HtmlTextArea

Orice alt tag cu atributul runat="server" HtmlGenericControl

Controale Web avansate

Pentru a abstractiza mai mult modelul de programare al paginilor WebForms,

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 193 of 203

Page 194: Aplicatii in Visual.net

ASP.NET defineste un al doilea tip de controale - Web Controls. Numite si controaleinteligente, ele pot fi caracterizate prin:

* ofera un bogat si consistent model obiectual de programare;

* detecteaza automat tipul navigatorului, iar afisarea la client va fi optimizata in functiede capabilitatile acestuia;

* pentru unele controale se pot defini sabloane (template-uri) de afisare;

* posibilitatea de a controla generarea evenimentelor pe server;

* posibilitatea de a trimite evenimente unui container din interiorul acestuia (deexemplu, un control de tip buton in interiorul unui tabel);

* legarea la surse de date a tuturor proprietatilor controalelor pentru a influenta afisareala executie.

Sunt definite in spatiul de nume System.Web.UI.WebControls si mostenesc, direct sauindirect, clasa de baza WebControl.

Adaugarea controalelor Web Controls in paginile WebForms se face in acelasi mod incare se adauga un element HTML. Totusi, sintaxa de reprezentare a unui controlintr-un fisier .aspx (.ascx) respecta urmatoarele criterii:

* conform sintaxei XML sunt declarate elemente care refera spatiul de nume asp;

* toate elementele trebuie sa aiba marcaj de sfarsit;

* includ atributul runat= "server";

* au definit atributul ID care permite programarea controlului la nivel de server;

* proprietatile controalelor sunt declarate ca atribute.

Label

Folosita pentru a afisa text static sau text conectat la o sursa de date in pagina:

<asp:Label runat="server" Text="un text" Font-Italic="true"Font-Name="Arial" Font-Size="12"></asp:Label>

TextBox

Permite editarea textului folosind mai multe moduri de utilizare prin proprietateaTextMode (implicit SingleLine): editare pe o singura linie, pe linii multiple si pentruintroducerea unei parole:

<asp:TextBox runat="server" id="email" Text="exemplu:[email protected]" Font-Name="Tahoma" Width="200px"/>

<asp:TextBox runat="server" id="adresa" Font-Name="Tahoma"TextMode="Multiline" Rows="3">str., bl., apt...</asp:TextBox>

<asp:TextBox runat="server" id="parola" TextMode="Password"

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 194 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 195: Aplicatii in Visual.net

Width="200px"/>

CheckBox

Creeaza o caseta de marcare care permite selectarea unei stari true sau false. Pentruutilizarea mai multor controale CheckBox exista alternativa controlului CheckBoxList cuposibilitati de legare la o sursa de date. Se pot specifica formate de afisare folosindproprietatile RepeatLayout si RepeatDirection.

<asp:CheckBox id="asigurat" runat="server" AutoPostBack="True"Text="Asigurat medical" TextAlign="Right" />

Proprietatea AutoPostBack="True" este folosita pentru a trimite starea controlului peserver imediat ce acesta a fost selectat/deselectat.

<asp:CheckBoxList id="checkboxlist1" CellPadding="5"CellSpacing="5" RepeatColumns="2" RepeatDirection="Vertical"RepeatLayout="Flow" TextAlign="Right" runat="server">

<asp:ListItem>Optiunea 1</asp:ListItem>

<asp:ListItem>Optiunea 2</asp:ListItem>

<asp:ListItem>Optiunea 3</asp:ListItem>

<asp:ListItem>Optiunea 4</asp:ListItem>

</asp:CheckBoxList>

RadioButton

Ca si controlul CheckBox, acesta permite selectarea unui singur buton dintr-un grupdefinit (excludere mutuala):

<asp:RadioButton runat="server" Text="Casatorit"GroupName="StareCivila" />

<asp:RadioButton runat="server" Text="Necasatorit"GroupName="StareCivila" Checked="true" />

RadioButtonList

Furnizeaza dezvoltatorului o singura selectie a unui buton radio dintr-un grup carepoate fi generat dinamic dintr-o sursa externa de date (de exemplu,. o baza de date).

<asp:RadioButtonList id=RadioButtonList1 runat="server"RepeatLayout="Flow" RepeatColumns="2"RepeatDirection="Horizontal">

<asp:ListItem>Optiunea 1</asp:ListItem>

<asp:ListItem>Optiunea 2</asp:ListItem>

<asp:ListItem>Optiunea 3</asp:ListItem>

<asp:ListItem> Optiunea 4</asp:ListItem>

</asp:RadioButtonList>

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 195 of 203

Page 196: Aplicatii in Visual.net

DropDownList Este utilizata pentru selectarea unei optiuni dintr-un numar de optiuniafisate ca o lista drop-down . Aceasta lista poate fi conectata la o sursa de dateexterna.

<asp:DropDownList runat="server">

<asp:ListItem>Selecteaza 1</asp:ListItem>

<asp:ListItem>Selecteaza 2</asp:ListItem>

<asp:ListItem>Selecteaza 3</asp:ListItem>

</asp:DropDownList>

ListBox

Este folosit pentru a genera o lista cu bara de derulare din care se pot selecta una saumai multe optiuni.

<asp:ListBox runat="server" SelectionMode="Multiple">

<asp:ListItem>Optiunea 1</asp:ListItem>

<asp:ListItem>Optiunea 2</asp:ListItem>

<asp:ListItem>Optiunea 3</asp:ListItem>

<asp:ListItem>Optiunea 4</asp:ListItem>

<asp:ListItem>Optiunea 5</asp:ListItem>

<asp:ListItem>Optiunea 6</asp:ListItem>

</asp:ListBox>

Urmatoarele controale sunt utilizate pentru trimiterea informatiilor introduse in formular.Atunci cand sunt apasate, continutul intregii pagini WebForms este trimis la serverulWeb. Acestea genereaza evenimentul Click la server care poate fi tratat in codulprogramatorului.

Button

Creeaza un buton 3-D de submisie a unei pagini WebForms.

<asp:Button runat="server" Text="OK"></asp:Button>

LinkButton

Are aceeasi functionalitate ca a unui control Button, doar ca este afisat ca un hiperlinkin pagina.

<asp:LinkButton runat="server"Text="Inregistrare"></asp:LinkButton>

HyperLink

Folosit pentru crearea unei legaturi catre un alt URL.

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 196 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 197: Aplicatii in Visual.net

<asp:HyperLink runat="server" Text="Viziteaza site-ul Facultatiide Informatica, Iasi"NavigateUrl="http://www.infoiasi.ro"></asp:HyperLink>

Controlul poate fi afisat ca text folosind proprietatea Text sau ca imagine utilizandproprietatea ImageUrl.

Image

Permite afisarea unei imagini in cadrul paginii Web. Daca navigatorul nu poate afisaimagini, se poate specifica un text in locul imaginii prin atributul AlternateText.

<asp:Image runat="server" ImageUrl="10.jpg"AlternateText="Facultatea de Informatica"></asp:Image>

Panel

Reprezinta un container pentru alte controale si este util de folosit in situatia in caretrebuie adaugate dinamic controale in pagina Web sau trebuie ascunse/afisate un grupde controale. De retinut ca acest control nu este vizual, doar grupeaza logic un grup decontroale din interiorul acestuia.

<asp:Panel id="partea1" runat="server"> Ai asiguraremedicala?<asp:CheckBox id="asigurat1" runat="server"AutoPostBack="True" Text="Da" TextAlign="Right" />

Selecteaza starea civila:

<asp:RadioButton runat="server" Text="Casatorit"GroupName="StareCivila" />

<asp:RadioButton runat="server" Text="Necasatorit"GroupName="StareCivila" Checked="true" />

</asp:Panel>

Table, TableRow, TableCell

Aceste controale permit construirea unui tabel HTML dinamic folosind acelasi modelabstract orientat obiect pentru construirea altor controale Web.

<asp:Table id="Table1" runat="server" CellPadding=10GridLines="Both" HorizontalAlign="Center">

<asp:TableRow>

<asp:TableCell>Linia 0, Coloana 0</asp:TableCell>

<asp:TableCell>Linia 0, Coloana 1</asp:TableCell>

</asp:TableRow>

<asp:TableRow>

<asp:TableCell>Linia 1, Coloana 0</asp:TableCell>

<asp:TableCell>Linia 1, Coloana 1</asp:TableCell>

</asp:TableRow>

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 197 of 203

Page 198: Aplicatii in Visual.net

</asp:Table>

Calendar

Selectarea datei poate fi facuta acum mult mai elegant, solutie oferita de controlulCalendar. Acesta permite afisarea unei singure luni, selectarea datei, trecerea de la oluna la alta. Pune la dispozitia programatorului diferite proprietati pentru specificareastilului de afisare si a modului de selectare a datei. Folosind proprietateaSelectionMode se poate specifica selectarea unei singure zile, a unei saptamani sau aintregii luni. Controlul suporta toate tipurile de calendar definite in spatiul de numeSystem.Globalization (Gregorian, Japonez, Korean, Hijri, Hebrew, Julian).

<asp:Calendar id="datai" runat="server" BackColor="LightGreen"Font-Name="Verdana" Font-Size="10pt" />

La ora actuala, majoritatea aplicatiilor Web folosesc un sistem de gestiune al bazelorde date in spatele aplicatiei. In sprijinul unei bune prezentari a acestor surse de date,platforma .NET include un set de trei controale ce fac posibila afisarea unor maricantitati de date foarte usor. Sursa de date reprezinta o multime specifica de date carepoate fi reprezentata de un server de baze de date (MS SQL Server), un fisier XMLsau o colectie de date care implementeaza interfata System.Collections.IEnumerable.

Repeater

Reprezinta o simpla lista conectata la o sursa de date care foloseste sabloane pentruafisarea informatiilor. Fara un sablon predefinit, programatorul este nevoit sa-sidefineasca propriul model de afisare folosind elemente HTML. In schimb, controlul estesingurul care ofera libertate maxima in definirea modului de afisare, a stilului siformatarii.

<asp:Repeater runat="server" id="list1">

<HeaderTemplate> <ol> </HeaderTemplate>

<ItemTemplate>

<li><a href='mailto:<%# DataBinder.Eval(Container.DataItem,"Email") %>'><%# DataBinder.Eval(Container.DataItem, "Nume")%></a>

</li>

</ItemTemplate>

<FooterTemplate> </ol> </FooterTemplate>

</asp:Repeater>

DataList

In completarea unor functionalitati predefinite, controlul DataList afiseaza inregistrarileunei surse de date folosind sabloane existente, dand posibilitatea totodata sa nedefinim propriile modele de afisare, sa selectam si sa editam articolele.

<asp:DataList id="list2" runat="server" BorderColor="black"CellPadding="3" Font-Name="Verdana" Font-Size="8pt">

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 198 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 199: Aplicatii in Visual.net

<HeaderStyle BackColor="#aaaadd" />

<AlternatingItemStyle BackColor="Gainsboro" />

<HeaderTemplate>Studenti:</HeaderTemplate>

<ItemTemplate>

<%# DataBinder.Eval(Container.DataItem, "Nume") %>

</ItemTemplate>

</asp:DataList>

DataGrid

Controlul afiseaza inregistrari conectate la o sursa de date in format tabular, oferindoptiuni pentru selectarea, sortarea, paginarea si editarea datelor. Fiecare camp dinbaza de date este afisat in coloane separate in ordinea aparitiei in baza de date.Implicit, proprietatea AutoGenerateColumn este setata pe true, ceea ce inseamnacrearea unui obiect BoundColumn pentru fiecare inregistrare din sursa de date. Se potcontrola ordinea, functionarea si afisarea fiecarei coloane. DataGrid-ul suporta maimulte tipuri de coloane oferind diferite functionalitati de baza in prelucrarea datelor:

* BoundColumn, afiseaza fiecare articol dintr-o inregistrare ca text simplu;

* ButtonColumn, afiseaza un buton de comanda pentru fiecare articol dintr-o coloana.Acesta permite crearea unei coloane de controale Button cu functionalitati genAdaugare si stergere;

* EditCommandColumn, afiseaza o coloana care contine comenzi de editare pentrufiecare articol dintr-o coloana;

* HyperLinkColumn, afiseaza fiecare articol dintr-o coloana ca un hyperlink;

* TemplateColumn, afiseaza fiecare articol dintr-o coloana folosind un sablonspecificat. Acesta permite sa folosim controale specializate in coloane.

<asp:DataGrid id="list3" runat="server"

BorderColor="black"

BorderWidth="1"

GridLines="Both"

CellPadding="3" CellSpacing="0"

Font-Name="Verdana"

Font-Size="8pt"

HeaderStyle-BackColor="#aaaadd">

</asp:DataGrid>

4. Evenimente

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 199 of 203

Page 200: Aplicatii in Visual.net

Tratarea evenimentelor in paginile WebForms

Capturarea evenimentelor in paginile WebForms reprezinta o operatie facila, similaratratarii evenimentelor in WinForms. In acest sens, ASP.NET furnizeaza un mecanismvirtual pentru capturarea, transmiterea si interpretarea evenimentelor fara sa fim nevoitisa cunoastem modul in care evenimentele sunt capturate la client si trimise la serverpentru a fi procesate in codul corespunzator.

Evenimentele tratate in controalele server pot fi in general de tipul Click, dar existaaltele speciale, mult mai abstracte, ca onchange si SelectionChanged (pentru controlulCalendar). De regula, evenimentele de tip Click genereaza o postare a paginii laserverul Web, iar cele de tipul onchange sunt capturate, dar nu sunt trimise imediat laserver (sunt mentinute intr-o coada de mesaje si procesate intr-o ordine aleatoare).Pentru acele controale in care se genereaza evenimentul onchange exista proprietateaAutoPostBack care daca are valoarea true atunci trimite automat formularul la server.

Metoda care trateaza evenimentele in ASP.NET respecta acelasi tipar cu cele folositein platforma .NET Framework. Astfel, toate evenimentele paseaza metodei douaargumente: un obiect care identifica obiectul care a aruncat evenimentul si un alt obiectcontinand informatii specifice evenimentului. Acesta din urma, este de obicei de tipulSystem.EventArgs, dar exista si alte tipuri cum ar fi ImageClickEvensArgs pentrucontrolul Web ImageButton care ofera informatii exacte despre pozitia unde s-a facutclick pe imagine.

Adaugarea unei metode care sa trateze mesajul generat se poate specifica astfel: dacaevenimentul este generat de un control HTML, acesta poate fi capturat atat la client catsi la server. Aceasta se specifica prin adaugarea atributelor OnClick, respectivOnServerClick care vor indica metoda care va fi apelata la generarea evenimentului.

Exemplu:

<input type="submit" value="Enter"OnServerClick="SubmitBtn_Click" runat="server">

unde metoda void SubmitBtn_Click (object sender, EventArgs e) este cea caretrateaza evenimentul pe server.

Daca evenimentul este generat de un control Web, nu se poate specifica tratarea unuieveniment la client in sintaxa HTML, dar se poate adauga dinamic un nou atributcontrolului astfel: Button1.Attributes.Add ("onclick", "clientfunction();"); Putem specificao metoda dinamica care sa trateze mesajul evenimentului pe server astfel:

this.Button1Web.Click += new System.EventHandler(this.Button1_Click);

this.Button2HTML.ServerClick += new System.EventHandler(this.Button2_ServerClick);

5. Concluzii

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 200 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 201: Aplicatii in Visual.net

ASP.NET a fost dezvoltat pentru a lucra asemenea editoarelor WYSIWYG (What YouSee Is What You Get) HTML, astfel mediul de dezvoltare Microsoft Visual Studio.NETpe langa un GUI pe care dezvoltatorii il pot utiliza pentru a adauga controale server inpaginile WebForms, ofera suport integrat complet pentru depanarea aplicatiilor Web.

Tehnologia pe care platforma .NET o ofera prin ASP.NET, alaturi de limbajul C#, unlimbaj elegant si totodata performant, robust si productiv, va conduce la dezvoltareaaplicatiilor Web complexe pentru organizatii mari, intreprinderi care vor puteainteropera folosindu-se de serviciile Web. ASP.NET, prin WebForms, imprumuta stilulde programare Visual Basic folosind form-uri si evenimente si il transpune pe Weboferind productivitate maxima in construirea aplicatiilor Web. Mai mult, modelul abstractorientat pe obiecte al mediului ASP.NET va conduce la o dezvoltare rapida acomponentelor unei aplicatii Web, deci la aplicatii cu interfete utilizator bogate inposibilitati de prezentare a informatiilor.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 201 of 203

Page 202: Aplicatii in Visual.net

Section 14. Appendix

Lista cuvintelor cheie

va urma...

ibm.com/developerWorks Presented by developerWorks, your source for great tutorials

Page 202 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Page 203: Aplicatii in Visual.net

Section 15. Bibliografie, referinte

Lista materialelor didactice

Nr. Descriere

1. Alexandru PRUTEANU, Dezvoltare de aplicatii in Visual Studio .NET Iasi,2002

2. Training Kit MCAD/MCSD 70-316, Developing Windows-BasedApplications with Microsoft Visual C# .NET

3. Microsoft Academic resource Kit for .NET Technology, MicosoftCorporation 2003

4. Tom ARCHER, Andrew WHITECHAPEL, Inside C#, Second Edition,Micosoft Corporation 2002

5. Gabriel ENEA, WebForms, o tehnologie ASP.NET 2002

Colophon

This tutorial was written entirely in XML, using the developerWorks Toot-O-Matic tutorialgenerator. The open source Toot-O-Matic tool is an XSLT style sheet and several XSLTextension functions that convert an XML file into a number of HTML pages, a zip file, JPEGheading graphics, and two PDF files. Our ability to generate multiple text and binary formatsfrom a single source file illustrates the power and flexibility of XML. (It also saves ourproduction team a great deal of time and effort.)

You can get the source code for the Toot-O-Matic atwww6.software.ibm.com/dl/devworks/dw-tootomatic-p. The tutorial Building tutorials with theToot-O-Matic demonstrates how to use the Toot-O-Matic to create your own tutorials.developerWorks also hosts a forum devoted to the Toot-O-Matic; it's available atwww-105.ibm.com/developerworks/xml_df.nsf/AllViewTemplate?OpenForm&RestrictToCategory=11.We'd love to know what you think about the tool.

Presented by developerWorks, your source for great tutorials ibm.com/developerWorks

Dezvoltare de aplicatii in Visual Studio .NET Page 203 of 203