manual c#

Upload: zicu-suzana-vasilica

Post on 16-Jul-2015

737 views

Category:

Documents


3 download

TRANSCRIPT

Dezvoltare de aplicatii in Visual Studio .NETPresented 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............................... 2. Introducere in .NET Framework - I .................................. 3. Tipuri de date si membri- II ........................................... 4. Gestionarea interfetelor utilizator - III ............................... 5. Concepte POO in Visual Studio .NET - IV ......................... 6. Testarea si debugging-ul aplicatiilor - V ............................ 7. Accesarea bazelor de date. ADO.NET - VI ........................ 8. GDI+. Controale utilizator. Atribute - VII............................ 9. Programare folosind fire de executie - VIII......................... 10. .NET Framework Advanced - IX ................................... 11. Assemblies. Aplicatii - configurare, securizare, instalare, rulare - X .................................................................... 12. XML, Web Services - XI ............................................. 13. ASP.NET - XII ......................................................... 14. Appendix ............................................................... 15. Bibliografie, referinte .................................................

2 3 12 35 61 80 98 122 140 142 158 177 187 202 203

Dezvoltare de aplicatii in Visual Studio .NET

Page 1 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Section 1. Despre manual si despre autorul sau Despre manual...Manualul contine tematica cursului "Dezvoltare de aplicatii in Visual Studio .NET" si se adreseaza, in primul rand, studentilor Facultatii de Informatica care au optat sa urmeze acest curs. Cititorii acestui manual trebuie sa posede cunostinte medii de programare orientata obiect si sa fie familiarizati cu medii de programare vizuala. In plus, o doza de ambitie este suficienta pentru a garanta o buna asimilare a cunostintelor de Visual Studio .NET si, in particular, de C# pe care autorul intentioneaza sa 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

Page 2 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 mondiale prin: -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 un mecanism eficient de alocare de memorie pentru stocarea datelor si instructiunilor, permitand executia unei aplicatii utilizator numai dupa verificarea unui set de permisiuni; daca sunt indeplinite conditiile de lansare in executie a aplicatiei, mediul de dezvoltare initiaza si gestioneaza executia aplicatiei, gestionand, de asemenea, mecanismul de realocare zonelor de memorie provenite de la resurse care nu mai sunt 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, care faciliteaza dezvoltarea de programe. Common Language Specification (CLS) defineste un set minim de standarde pe care toate limbajele care folosesc .NET Framework trebuie sa le suporte. Common Type System(CTS) stabileste compatibilitatea de tipuri intre componente implementate in diverse limbaje. Unitatea de baza, elementara a unei aplicatii .NET este assembly-ul, care include un manifest al assembly-ului. Acest manifest descrie assembly-ul si unul sau mai multe module, iar modulele contin codul sursa al aplicatiei. Un executabil .NET este stocat ca un fisier IL (MSIL - Microsoft Intermediate Language). La incarcare, compilatorul transforma codul sursa in code managed (compilat si administrat de CLR), se verifica daca assembly-ul verifica conditiile de securitate impuse de sistemul local. Daca se permite rularea, se creaza un fisier .exe sau .dll numit PE - Executabil Portabil. Acesta este incarcat de motorul de executie care 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 practic o interoperabilitate fara compromisuri.Dezvoltare de aplicatii in Visual Studio .NET Page 3 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

CLR - interoperabilitate multi-limbaj Integrare compilatorul limbajului L in care se programeaza trebuie sa stie sa furnizeze cod intermediar 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. Spre exemplu, o clasa scrisa in L poate fi mostenita in C#, etc. In plus, in .NET, nu se mai pune problema vulnerabilitatii legate de versiunea modulului scris in L (in care se regaseste signatura si implementarea clasei de mai sus). Introducerea metadatei rezolva aceasta problema importanta.

Figura 1 - structura .NET Framework. Interoperabilitate

Page 4 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 System Descriere Reprezinta spatiul de nume radacina pentru tipurile low-level din .NET Framework si, de asemenea, pentru tipurile primitive de data, si este baza tuturor celorlalte spatii de nume din .NET BCL. Contine clase care reprezinta o varietate de tipuri container, cum ar fi ArrayList, SortedList, Queue si Stack. Contine, de asemenea, clase abstracte, cum ar fi CollectionBase, foarte utile pentru implementarea propriilor clase cu functionalitate de container. Contine clase utile pentru implementarea comportamentelor componentelor si controalelor la run-time si design-time convertori de tipuri si atribute, legare la surse de date (binding), componente care asigura managamentul licentelor. Contine clase necesare accesarii si manipularii bazelor dePage 5 of 203

System.Collections

System.ComponentModel

System.Data

Dezvoltare de aplicatii in Visual Studio .NET

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

date, precum si spatii de nume aditionale utilizate pentru accesul la date. System.Data.Common System.Data.OleDb System.Data.SQLClient System.Drawing System.IO System.Math System.Reflection System.Security Contine un set de clase distribuite pentru provideri de date .NET. Contine clase care pot efectua operatii cu provideri de date de tip managed, pentru acces OLE DB la surse de date. Contine clase optimizate pentru interactiunea cu Microsoft SQL Server. Expune functionalitati GDI+, continand clase care faciliteaza randarea grafica. inglobeaza tipuri pentru efectuarea operatiilor de I/O in sistemul de fisiere. Contine un set de functii matematice. Furnizeaza suport pentru obtinerea de informatii si generarea dinamica de tipuri la runtime. Tipuri cu ajutorul carora se pot crea si manipula permisiuni, aspectele legate de criptografie si securitatea accesarii codului constituie, de asemenea, subiecte strans legate de acest spatiu de nume. Contine clase care faciliteaza implementarea de aplicatii cu fire de executie multiple. Contine tipuri implicate in crearea aplicatiilor Windows standard. Clasele care reprezinta forme si controale sunt, de asemenea, incluse aici.

System.Threading System.Windows.Forms

Numele spatiilor de nume sunt auto-descriptive prin design. Aceasta modalitate de utilizare a numelor face ca .NET Framework sa fie usor de folosit si permite utilizatorului o familiarizare rapida cu mediul de lucru. Libraria de clase de baza .NET Framework este o librarie de cod care furnizeaza functionalitati folositoare pentru construirea aplicatiilor. BCL este organizata in spatii de nume, care contin tipuri si spatii de nume aditionale, legate prin functionalitate comuna. Se poate folosi cuvantul rezervat using pentru a permite referentierea unor membri ai unui spatiu de nume fara a folosi un nume specificat prin calea comnpleta catre membrul respectiv. Daca se doreste folosirea unei librarii externe, trebuie creata mai intai o referinta catre aceasta. Tipuri valoare si tipuri referinta Tipurile pot fi: tipuri valoare sau tipuri referinta. O variabila de tip valoare contine toate datele asociate cu tipul respectiv. O variabila de tip referinta contine un pointer la o instanta a unui obiect de tipul respectiv. Tipurile valoare predefinite sunt create la declarare si ramin vide pana in momentul in care li se asigneaza o valoare. Tipurile referinta trebuie instantiate dupa declarare pentru a crea efectiv un obiect de acel tip. Declararea si instantierea pot fi combinatePage 6 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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, datele continute in prima variabila sunt copiate in cea de-a doua. Atunci cand o variabila de tip referinta este asignata unei alte variabile de acelasi tip, numai referinta catre obiect este copiata, si ambele variabile vor face referire catre acelasi obiect.

3. Clase si structuriClase versus Structuri La prima vedere, clasele si structurile par foarte asemanatoare. Ambele pot contine membri, cum ar fi campuri si metode, ambele necesita un constructor pentru a se crea o noua instanta si, ca toate tipurile din .NET Framework, ambele sunt derivate din Object. 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 de instantiere pentru clase sunt alocate pe heap, in timp ce pentru structuri acestea sunt alocate pe stack. Acesul la stack a fost proiectat in asa fel incat sa fie facil si rapid, dar stocarea unor date de dimensiuni mari pe stack pot conduce la diminuari ale performantei aplicatiei. in termeni practici, structurile reprezinta varianta optima pentru obiecte de dimensiuni mici si pentru care se definesc putine instante, persistente pentru perioade relativ mici in memorie. Clasele sunt optim folosite pentru obiecte de dimensiuni mai mari si pentru care de definesc un numar mai mare de instante, cu posibilitatea mentinerii lor in memorie 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 iar structurile sunt tipuri valoare. Cuvantul rezervat class este folosit in Visual C# pentru a defini clase. Structurile sunt create utilizand cuvantul cheie struct. Atat clasele, cat si structurile pot contine tipuri imbricate. Tipurile definite de utilizator sunt instantiate in acceasi maniera ca tipurile predefite, exceptand faptul ca atat tipurile caloare cat si tipurile referinta trebuie sa foloseasca cuvantul cheie new pentru instantiere.

4. Cum folosim metodele? Metodele executa manipulari ale datelor care imprima claselor si structurilor un anumit comportament. Metodele pot returna o valoare, dar acest lucru nu este necesar. in Visual C#, daca o metoda nu returneaza o valoare, se specifica void drept tip returnat. Metodele sunt apelate prin plasarea numelui metodei in cod, specificandu-se eventualii parametrii necesari.Dezvoltare de aplicatii in Visual Studio .NET Page 7 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Metodele pot avea parametri, care reprezinta valori solicitate de metoda. Parametrii sunt transmisi, implicit, prin valoare. Transmiterea parametrilor prin referinta se face in Visual C# folosind cuvantul rezervat ref. Visual C# permite specificarea parametrilor de iesire pentru o anumita metoda. Constructorul este prima metoda apelata la instantierea unui tip. Constructorul furnizeaza o modalitate de a seta valori implicite ale datelor sau de a executa alte operatii 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 pentru a executa cod de clean-up, de dealocare de memorie. Pentru ca dealocarea memoriei 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 public private internal protected protected-internal Efect asupra membrilor poate fi accesat de oriunde poate fi accesat doar de membrii din cadrul tipului care il defineste poate fi accesat de toate tipurile din cadrul assembly-ului parinte, dar nu dinafara acestuia poate fi accesat numai de membrii din cadrul tipului care il defineste sau de tipuri care mostenesc acest tip poate fi accessed de toate tipurile din assembly sau de tipuri 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 a membrilor unui tip de date. Exista 5 modificatori de acces: public, internal, private,protected si protected internal. Fiecare dintre acestea determina un anumit nivel de acces. Daca pentru o metoda nu se specifica nici un modificator de acces, nivelul de acces asociat implicit este private pentru clasele si structurile din Visual C#. Daca nu este specificat nici un modificator de acces pentru o variabila membru, acesta este considerata private intr-o clasa si publicintr-o structura. Modificatorii de acces pot fi, de asemenea, folositi pentru a controla modul in care este instantiat un tip. Nivelele de acces pentru tipuri sunt urmatoarele: tipurile public pot fi instantiate de oriunde. Tipurile internal pot fi instantiate numai de membrii assembly-ului, tipurile private pot fi instantiate numai de ele insele sau dintr-un tip care le contine. Daca nu se specifica un modificator de acces pentru o clasa sau structura, este considerata public. Tipurile imbricate se supun acelorasi reguli ca si tipurile ne-imbricate dar, in practica,Page 8 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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. Ei pot 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 ca atunci cand un obiect nu mai este folosit, .NET Framework elibereaza automat memoria 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, iar obiectul la care face referire nu mai este referentiat de nici o variabila din cadrul aplicatiei. Garbage collector-ul gestioneaza in background arborele de referinte si identifica obiectele catre care nu se mai face referinta. Cand gaseste un astfel de obiect, cum ar fi TipObiect din exemplul anterior, il sterge si solicita eliberarea zonei de memorie 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 in program de la un anumit moment. Garbage collector-ul reprezinta, de fapt, un fir de executie de prioritate scazuta, in conditii normale. El intervine in executia programului cand timpul procesor nu este consumat de sarcini mai importante. Totusi, atunci cand zonele de memorie libera se imputineaza semnificativ, firul de executie asociat garbage collector-ului creste in prioritate. Memoria utilizata de obiecte care nu mai sunt referentiate in program este solicitata intr-o maniera mai insistenta, pana cand se elibereaza o zona suficienta de memoria, caz in care firul de executie al garbage collector-ului trece la o prioritate scazuta. Aceasta abordare non-deterministica de eliberare a memoriei are ca scop maximizarea performantei aplicatiei si furnizeaza un mediu de aplicatii mai putin predispus la actiunea bug-urilor (less bug-prone ). Exista, insa, un cost. Datorita mecanismului prin care opereza garbage collector-ul, utilizatorul nu poate sti momentul in care un obiect va fi dealocat. Deci, nu exista control asupra momentului apelarii destructorului clasei Visual C# in cauza. Aceste metode ar trebui sa nu contina cod care se proiecteaza a fi executat la un anumit moment. in schimb, pot fi scrise clase care utlizeaza o cantitate importanta de resurse si care contin o metoda Dispose() pentru eliberarea explicita a acestor resurse, atunci cand o instanta a acestei clase nu mai este necesara in program. Referinte circulare

Dezvoltare de aplicatii in Visual Studio .NET

Page 9 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Procesul de garbage collection are in vedere, de asemenea, si referintele circulare, o forma foarte comuna de utilizare ineficienta a memoriei in medii de dezvoltare anterioare. 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 - referinta circulara } } Desi referintele circulare pot crea probeleme in ceea ce priveste detectarea zonelor de memorie ocupate inutil in alte platforme de dezvoltare, garbage collector-ul din .NET Framework este capabil sa detecteze si sa faca disponibile aceste zone. Deci, daca o pereche de obiecte se autoreferentiaza, vor fi supuse procesului de garbage collection. .NET Framework gestioneaza procesul de eliberare automata a memoriei prin intermediul garbage collector-ului. Garbage collector-ul este un fir de executie de prioritate scazuta care ruleaza intotdeauna im background-ul aplicatiei. Cand memoria disponibila s-a diminuat, prioritatea garbage collector-ului creste pana cand se vor elibera destule resurse.

Page 10 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Pentru ca nu se poate stabili momentul in care un anumit obiect va fi eliminat de garbage collector, utilizatorul nu trebuie sa mizeze de codul scris in interiorul destructorilor. in schimb, pentru eliberarea resurselor, se poate folosi o metoda Dispose() care va fi apelata explicit. Garbage collector-ul analizeaza in mod continuu arborele de referinte si elimina obiectele la care nu se mai face referinta, precum si obiectele cu referinte circulare. Detalii - MSDN Library, criteriu de cautare circular reference

Dezvoltare de aplicatii in Visual Studio .NET

Page 11 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Section 3. Tipuri de date si membri- II 1. Tipuri de date. Utilizare.Microsoft .NET Framework furnizeaza un sistem foarte robust de tipuri primitive care pot fi folosite pentru stocarea si reprezentarea datelor din cadrul aplicatiei. Datele primitive reprezinta numere intregi, flotante, valori booleene, caractere si string-uri. Sistemul de tipuri de date .NET Framework este type-safe, adica conversiile implicite intre diferitele tipuri de date au loc numai daca acest lucru nu conduce la pierderi de date. 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 de conversii 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 care permit stocarea, manipularea si transmiterea valorilor intre diferitele entitati din cadrul aplicatiei. Limbajele .NET sunt puternic tipizate (strongly typed). Aceasta inseamna ca obiectele de un anumit tip nu pot fi schimbate cu obiecte de un alt tip. Apelul unei metode va esua daca nu se specifica parametri avand tipurile corespunzatoarte. Conversiile implicite si explicite permit transformari asupra datelor atunci cand este nevoie. Acest lucru este posibil deoarece toate tipurile din .NET Framework sunt derivate 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.

Page 12 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Tip System.Byte System.Int16 System.Int32 System.Int64

Reprezentare C# byte short int long

Descriere intreg fara semn pe 8 biti intreg cu semn pe 16 biti intreg cu semn pe 32 biti intreg cu semn pe 64 biti intreg cu semn pe 8 biti intreg fara semn pe 16 biti intreg fara semn pe 32 biti intreg fara semn pe 64 biti

Domeniu de la 0 la 255 de la -32768 la 32767 de la -2 la 31 la 2 la 31 - 1 de la -2 la 63 la 2 la 63 - 1 de la -128 la 127 de la 0 la 65535 de la 0 to 2 la 32 -1 de la 0 to 2 la 64 -1

System.SByte sbyte System.UInt16 ushort System.UInt32 uint System.UInt64 ulong

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 cu 0x 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 numere cu parte fractionara. Tabelul urmator sintetizeaza aceste tipuri: Tip System.Single System.Double System.Decimal Tabel 2 - Tipuri flotante Observatii: System.Single - util pentru calcule in virgula mobila care necesita un grad scazut de precizie System.Double - pentru calcule cu un grad mai mare de precizie, operand cu numere dintr-un interval foarte vast System.Decimal - grad foarte mare de precizie, folosind insa numere dintr-un interval mai restrans Tipuri non-numericeDezvoltare de aplicatii in Visual Studio .NET Page 13 of 203

Reprezentare C# float double decimal

Descriere variabila flotanta pe 32 biti, precizie - 7 cifre semnificative pe 64 biti semnificativi, precizie 15-16 pe 128 biti, precizie - 28 semnificativa

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

System.Boolean System.Char System.String System.Object

System.Boolean Tipul System.Boolean este folosit pentru a reprezenta o valoare care este fie true, fie false. In C#, o variabila booleana este desemnata prin intermediul tipului bool, cu valorile posibile true si false. System.Char Tipul System.Char reprezinta un caracter Unicode pe 16 biti. In C#, o variabila de tip char (tipul C# asociat) poate fi definita prin specificarea explicita a unui caracter intre apostroafe: 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 tip Char. Cu alte cuvinte, un string poate desemna un cuvant, un paragraf, un cod sau orice alta succesiune de caractere. Tipul C# asociat este desemnat de cuvantul rezervat 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 variabile object 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 reconvertit explicit la acel tip pentru a accesa intreaga sa functionalitate.

Page 14 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Tipuri de conversii Datele pot convertite in doua feluri: implicit, caz in care conversia este executata automat, si explicit - conversie executata de utilizator. Conversii implicite Sunt conversii care se executa atunci cand nu exista riscul pierderilor de date. De exemplu: 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 utilizat oriunde 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 byte short int long float char sbyte ushort uint ulong Conversii explicite In cazul unei conversii in care tipurile nu pot fi convertite implicit, trebuie aplicata o conversie explicita. Aceasta conversie se mai numeste cast. In C#, conversiile explicite necesita folosirea unei sintaxe speciale. Exemplu: int un_int = 100; La short, ushort, int, uint, long, ulong, float, double, decimal int, long, float, double, decimal long, float, double, decimal float, double, decimal double int, uint, long, ulong, float, double, decimal short, int, long, float, double, decimal int, uint, long, ulong, float, double, decimal long, ulong, float, double, decimal float, double, decimal

Dezvoltare de aplicatii in Visual Studio .NET

Page 15 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

short un_short; un_short = (short)un_int; ! Conversiile explicite pot fi riscante. In exemplul anterior, conversia s-a efectuat fara nici un fel de problema pentru ca atat o variabila int, cat si una de tip short poate retine valoarea 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 a domeniului tipului short este mai mica decat valoarea la care se incearca conversia. ! Deoarece conversiile explicite sunt adesea riscante, este indicata folosirea lor numai in cazuri absolut necesare, implementand un sistem adecvat de tratare a conversiilor nereusite si a tuturor exceptiilor care ar putea fi aruncate. (vezi cursul 5). Functionalitati asociate tipurilor de date Toate tipurile de date au o functionalitate implicita (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 de memorie. 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. Toate clasele si tipurile sunt derivate din Object, fiecare din cele patru metode amintite fiind membre ale clasei Object. Deoarece toate clasele sunt derivate din Object, fiecare clasa poate fi convertita implicit la acest tip. La apelul uneia dintre cele patru metode, Common Language Runtime creaza o referinta temporara variabila de tip valoare declarata de utilizator si se permite tratarea acesteia ca fiind de tip referinta. Boxing explicit(manual) - prin atribuirea variabilei detip valoare unei variabile de tip Object. Exemplu: short s = 10; object O; O = s; Unboxing reprezinta conversia unei variabile boxed la un tip valoare. Se realizeaza prin conversia explicita a obiectului la tipul dorit. Se poate executa unboxing numai pentru obiectele care au fost supuse operatiei de boxing. Metoda ParsePage 16 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Parse - metoda statica, asociata tuturor tipurilor de date. Efectueaza conversia string-ului primit ca parametru la tipul din care face parte. Daca string-ul nu are un continut 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 String.Insert String.PadLeft, String.PadRight String.Remove String.Replace String.Insert String.Split String.Substring String.ToCharArray String.ToLower, String.ToUpper String.TrimEnd, String.TrimStart, String.Trim Descriere Insereaza un string specificat in instanta curenta Adauga caractere la stanga, respectiv la dreapta sirului Elimina un numar specificat de caractere din string, incepand de la un caracter precizat Inlocuieste toate aparitiile unui caracter specificat din string cu un alt caracter Insereaza un string specificat in instanta curenta Returneaza un array de substringuri, obtinut prin separarea token-urilor din stringul initial, dupa un separator specificat Returneaza un substring al stringului initial Returneaza caracterele compunente ale sirului, sub forma de array de caractere Transforma stringul, convertind caracterele la litere mici, respectiv mari Elimina spatiile de la sfarsitul, inceputul stringului sau, respectiv toate spatiile din cadrul sirului

Metode statice cu siruri de caractere Metoda String.Compare String.Concat String.Format String.Join Descriere compara doua stringuri returneaza un string obtinut prin concatenarea a doua sau mai multe siruri de caractere returneaza stringul formatat returneaza un string obtinut prin concatenarea unui array de stringuri, specificand un separator si inserandu-l intre componentele array-ului

Dezvoltare de aplicatii in Visual Studio .NET

Page 17 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

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 nu exista riscul pierderii de date si explicite, efectuate explicit prin scriere de cod, programatorul trebuind sa analizeze ci atentie cazurile care ar putea conduce la erori. Boxing - macanismul care permite tratarea tipurilor valoare ca tipuri referinta. Unboxing - converteste un tip referinta asupra caruia s-a efectuat anterior boxing catre un tip valoare. Tipurile .NET contin functionalitate built-in specifica tipului. Metoda Parse este implementata de toate tipurile valoare, fiind utila pentru conversia string-uriloe la tipuri valoare. Clasa String contine un set de functii care faciliteaza manipularea string-urilor.

2. Constante, enumerari, tablouri, colectiiUtilizatorul simte adesea necesitatea organizarii grupurilor de obiecte intr-un anumit tip de structura. De exemplu, anumite obiecte, de acelasi tip sau de tipuri diferite trebuie accesate secvential si este necesara o sintaxa pentru gestionarea organizarii obiectelor. Tablourile (array) permit organizarea grupurilor de obiecte similare si referirea lor printr-un index, adesea in defavoarea accesarii prin nume. Colectiile sunt similare tablourilor, dar implementeaza o functionalitate mai complexa, fiind utilizate, in special, pentru organizarea grupurilor de obiecte de tipuri diferite. Constantele pot primi nume familiare si contin valori utilizate frecvent in program. Enumerarile (enum) permit organizarea unor multimi de constante, facilitand executia anumitor operatii din cadrul programului. Constante si enumerari Constantele permit asignarea unor nume familiare anumitor valori utilizate frecvent in cod. Enumerarile sunt multimi definite de utilizatori continand constante asociate unei multimi 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 de utilizator sau array. Constantele au o valoare fixata care odata stabilita nu mai poate fi schimbata sau redefinita. Dupa definire, o constanta poate fi folosita in cod, prin specificarea numelui asociat. De exemplu: public const int MAX = 25000;

Page 18 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

public int half_max() { return MAX/2; } Ca si variabilele, constantele pot avea orice nivel de acces. Pentru a defini o constanta care va putea fi accesata de toti utilizatorii aplicatiei sau componentei, trebuie declarata public. O constanta declarata private va putea fi accesata doar in cadrul domeniului clasei care o defineste. internal permite accesarea constantei din cadrul assembly-ului care o contine, iar o constanta protected permite accesul la constanta si tipurilor mostenite din clasa care contine constanta. Enumerari Enumerarile permit lucrul cu multimi de constante, prin asocierea acestora cu nume familiare 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 tip numeric integral de date (byte, short, int si long). Modalitatea de definirea explicita a tipului elementelor se poate observa in exemplul urmator: public enum LunileAnului : short // cod ... NU este obligatorie asocierea de valori membrilor enumerarii. Implicit, membrii vor primi 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#, trebuie efectuata o conversie explicita a membrilor la tipul dorit pentru a putea accesa valoarea reprezentata. De exemplu:Dezvoltare de aplicatii in Visual Studio .NET Page 19 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

// 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 mai putin 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 a unei multimi de obiecte. Folosind tablouri, se pot grupa o serie de variabile, la care se poate face referire folosind un index. Se pot accesa toate sau o parte dintre variabile si examina sau modifica fiecare dintre aceste variabile. Se pot defini, de asemenea, tablouri multidimensionale. In .NET Framework, tablourile contin functionalitati intrinseci(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, pornind de 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:Page 20 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

//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 exista nici o modalitate de salvare a datelor la reinitializare (excluzand o varianta manuala). La crearea unui tablou cu elemente de tip referinta, declararea si initializarea tabloului nu conduc la umplerea tabloului cu membri de tipul respectiv. De fapt, se creaza un tablou 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 tip TipObiect 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: tablouri rectangulare si tablouri jagged. Tablouri rectangulare Sunt tablouri in care fiecare membru al fiecarei dimensiuni este extins in fiecare altaDezvoltare de aplicatii in Visual Studio .NET Page 21 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

dimensiune folosind aceeasi lungime. De exemplu, un tablou bidimensional, rectangular, poate fi gandit ca un tabel tabel, continand linii si coloane, fiecare linie avand 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 linie poate avea un numar diferit de coloane. De exemplu, sa consideram un tabel in care fiecare linie reprezinta un grad universitar, iar coloanele contin numele profesorilor care au gradul respectiv. Liniile vor putea avea, deci, un numar diferit de elemente. Pentru a gestiona 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. O colectie este o clasa specializata care organizeaza si permite manipularea unui grup de 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 de elemente la run time.Page 22 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Colectiile sunt utile pentru gestionarea grupurilor de elemente create dinamic la run time. De exemplu, ne putem imagina o colectie in care un element contine informatii despre un salariat al unei institutii. Creand o colectie de obiecte de tip Salariat, va fi posibila accesarea obiectelor, iterarea acestora, adaugarea de noi obiecte sau eliminarea obiectelor care devin irelevante. Clasa ArrayList System.Collections.ArrayList - confera functionalitati specifice de colectie utile intr-o serie intreaga de situatii. Aceasta clasa permite adaugarea si eliminarea dinamica de elemente 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 are indexul zero, elementele adaugate ulterior primind indexul imediat urmator elementului anterior. In C#, indexatorii sunt folositi pentru accesarea elementelor colectiilor, utilizand o sintaxa similara tablourilor. Exemplu: object obj; obj = lista[0]; ! Toate referintele dintr-o colectie sunt de tipul object. Se impune, deci, folosirea conversiilor explicite, pentru a obtine un element avand acelasi tip ca tipul elementului din 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 primita ca parametru Exemplu:

Dezvoltare de aplicatii in Visual Studio .NET

Page 23 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

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 se ocupa spatiile disponibile. Deci, valorile indecsilor sunt dinamice si pot returna referinte diferite la momente diferite ale executiei aplicatiei. Proprietatea Count Returneaza numarul de elemente din colectie (cu 1 mai mult decat indexul maxim). Alte tipuri de colectii Clasa BitArray Descriere tablou compact de biti

CollectionBase serveste drept clasa de baza pentru implementarea propriilor clase cu functionalitate de colectie Hashtable Queue SortedList colectie de perechi de tip cheie-valoare, organizate dupa codul hash al cheii gestioneaza un grup de obiecte dupa principiul first-in, first-out contine un grup de obiecte care pot fi accesate dupa index sau dupa valoareDezvoltare de aplicatii in Visual Studio .NET

Page 24 of 203

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 membru al 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 acelasi tip ca al variabilei desemnate ca iterator (i pentru exemplul anterior). In caz contrat, va fi aruncata o exceptie de tipul InvalidCastException. Solutie:declararea variabilei iterator de tip object si utilizarea metodei GetType pentru a inspecta tipul obiectelor din colectie. 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 folosita pentru a efectua modificari ale tabloului sau colectiei. Solutie: folosirea unei sintaxe de tip for. Exemplu: int[] tab = new int[] {1,2,3,4}; for (int i = 0; i 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-ul proprietatii

Proprietati read-only si write-only Uneori, programatorul trebuie sa implementeze a proprietate care returneaza o valoare care nu mai poate fi modificata dupa ce clasa a fost initializata. Alteori, intr-un numar mai mic de situatii, se impune crearea unei proprietati a carei valori poate fi modificata dar 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 omitand setter-ul proprietatii. Variabila private care retine valoarea proprietatii este declarata, in cele 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 constructorul clasei sau la initializarea variabilei. Proprietati write-only

Page 28 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

In anumite cazuri, pot fi implementate proprietati care pot fi scrise, dar nu citite, de catre utilizator. Exemplu: pozitionarea unei forme in functie de setari specifice localizarii(culturii) aplicatiei (localizare - concept care va fi prezentat intr-un curs viitor) forma este pozitionata la lansarea aplicatiei, nefiind necesara consultarea valorii proprietatii respective. O proprietate write-only se creaza similar unei proprietati obisnuite, omitand implementarea getter-ului. Exemplu: private short x; public short XmaxForm { set { x = value; } } Indexatori Sunt proprietati specializate care permit accesarea obiectelor dintr-un grup. Numele proprietatii 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 la obiectele componente si validarea operatiilor de atribuire. Modalitatile de implementareDezvoltare de aplicatii in Visual Studio .NET Page 29 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

a acestor proprietati depind de natura si functionalitatea colectiilor. O proprietate simpla este cea care returneaza colectia ca un singur obiect (pentru siguranta, proprietatea poate fi definita read-only, utilizatorul putand modifica obiectele din colectie folosind metodele 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 la colectie (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 posibilitatea folosirii sintaxei foreach pentru parcurgerea elementelor colectiei. ! Pentru implementarea unor proprietati care implica functionalitati avansate se pot defini colectii derivate din System.Collections.CollectionBase. Sinteza:

Page 30 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

proprietati - expun variabile sau obiecte membre, furnizand cod pentru validarea valorilor proprietatilor sau pentru efectuarea altor operatii; proprietatile read-only si write-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.EvenimenteEvenimentele reprezinta o notificare determinata de o actiune survenita intr-o sectiune a a aplicatiei. La aparitia unui eveniment, altor parti ale aplicatiei li se ofera oportunitatea 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 permite transmiterea unei referinte catre inceputul unei metode si apelarea metodei fara a folosi un apel explicit al acesteia. La declararea unui delegat, se specifica signatura metodei 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:Dezvoltare de aplicatii in Visual Studio .NET Page 31 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

se declara delegatul, specificand o signatura identica cu cea a metodelor care vor fi invocate se creaza o instanta a delegatului care pointeaza catre o metoda care are signatura adecvata 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 delegatului care 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 fi notificate de eveniment au loc. De exemplu, o componenta BankAccount lanseaza un eveniment 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 handlere inainte de a putea fi lansat raised. Un event handler este o metoda apelata prin intermediul unui delegat atunci cand un eveniment este lansat. Lansarea unui eveniment 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 fel ca in cazul unui apel de functie. Asocierea unei metode cu un eveniment se realizeaza prin crearea unei instante a unui delegat adecvat evenimentului care specifica, la randul sau, metoda pe care o invoca; se utilizeaza operatorul += pentru realizarea asocierii. Se pot crea, de aemenea, asocieri intre un evenimentt si o instanta a unui delegat existent. De exemplu: // metoda DisplayResults are signatura adecvata // delegatului CalculationDelegate // se creaza un nou delegat pentru a crea asocierea Account.CalculationComplete += new calculationDelegate(DisplayResults); // asociere cu un delegat existent

Page 32 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

calculationDelegate calc = new calculationDelegate(DisplayResults); Account.CalculationComplete += calc; Pentru evenimentele asociate controalelor si claselor .NET Framework exista delegati impliciti; acestia nu mai trebuie declarati ci doar instantiati. Exemplu: clasa System.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 asociat evenimentului care va fi tratat si se foloseste operatorul += pentru a realiza asocierea eveniment - 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 ordinea asocierii (operatorul +=), valoarea returnata de eveniment avand tipul returnat de ultimul 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 din program. O instanta a unei clase poate lansa un eveniment membru pentru a transmite notificarea. Evenimentul poate fi trata de metode desemnate drept event handlere. Aceste metode sunt executate la lansarea evenimentului. delegatii implementeaza functionalitatea de la baza evenimentelor. Un delegat este pointer la o functie, puternic tipizat. Poate invoca o metoda fara apelul explicit al acesteia. Asocierile dintre evenimente si event handlere implica utilizarea explicita a delegatilor. Evenimentele sunt declarate ca membri ai clasei; pot fi apelati prin nume si pot returna o valoare.Dezvoltare de aplicatii in Visual Studio .NET Page 33 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Metodele care trateaza evenimentele se numesc event handlere. Un event handler se creaza prin utilizarea operatorului += pentru a asocia un delegat evenimentului. Evenimentele pot avea mai multe event handlere asociat, si evenimente multiple pot fi tratate de acceasi metoda. Event handlerele pot fi eliminate dinamic (folosind operatorul -=).

Page 34 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 folosita drept clasa de baza controalele fac informatiile accesibile utilizatorilor meniurile si tool box-urile furnizeaza o modalitate structurata de a expune comenzile disponibile 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 de inteles 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 - semnificatii culturale, consistenta, simplitate

2. FormeFormele reprezinta unitatea fundamentala a unei interfete utilizator. Ele furnizeaza o platforma pe care se plaseaza controalele si permit prezentarea aplicatiei intr-o maniera consistenta si atractiva. Formele afiseaza date si primesc input-ul utilizatorilor. De obicei, aplicatiile contin una sau mai multe forme, organizate astfel incat sa urmeze logica fireasca a aplicatiei. stabilirea rolului unei forme intr-o aplicatieDezvoltare de aplicatii in Visual Studio .NET Page 35 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

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 o forma initiala, denumita Form1. Form1 nu reprezinta, efectiv, o instanta a unei forme, ci mai degraba o clasa care contine codul asociat unei instante a formei. Designer-ul este o reprezentare grafica a componentei(de obicei o forma) supuse design-ului, conferind posibilitatea adaugarii de controale, meniuri sau alte elemente vizuale formei respective. Odata cu cresterea in dimensiuni a aplicatiei, se creaza noi forme sau alte componente 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 New Item. 2. Se selecteaza Windows Form, apoi Open. Este adaugata o noua forma mediului de lucru. Adaugarea unei forme la o aplicatie la run time: Se declara si se instantiaza o variabila reprezentand forma in aceeasi maniera ca in cazul 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 de la forme existente, in ideea de a pastra caracteristicile vizuale si functionalitatea claselor de baza. Aceasta tehnica permite crearea unei forme care incorporeaza toti membrii, controalele, meniurile si codul asociat unei forme existente, folosind aceasta forma ca baza pentru implementarea unei functionalitati aditionale. Pentru a crea relatii de 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. Se introduce un nume si se deschide Inheritance Picker-ul. 3. Acesta afiseaza formele existente in proiect, dintre acestea selectandu-se forma dePage 36 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

baza care va fi asociata noii forme create. ! se poate alege drept clasa de baza si o forma dinafara proiectului, aceasta trebuie sa fie 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 sa includa 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 se desemneze o forma de start. Forma de start va fi prima forma incarcata la executia aplicatiei. public static void Main() { Application.Run(new myForm()); } Setarea formei de start in Visual C# se face utilizand meniul Projects, optiunea Properties, apoi la StartupObject se alege forma dorita. Setarea pozitiei de start Proprietatea StartPosition se poate utiliza pentru a determina pozitia pe ecran la care se va afisa prima data o forma. Aceasta poate fi setata la oricare dintre valorile enumerarii FormStartPosition. Valori FormStartPosition Valoare Manual Efect Forma se deschide la pozitia determinata de proprietatea Location.

Dezvoltare de aplicatii in Visual Studio .NET

Page 37 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

CenterScreen

Forma se deschide centrat pe ecran.

WindowsDefaultLocation Forma se deschide la locatia implicita determinata de setarile Windows. WindowsDefaultBounds CenterParent Forma se deschide la pozitia Windows implicita, avand marimea stabilita prin setari Windows implicite. Forma se deschide centrat, peste forma parinte.

Modificarea aspectului unei forme Aspectul unei interfete este o parte importanta a unei aplicatii. Utilizarea proprietatilor atasate 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 Font Cursor BackGroundImage Opacity

Efect specifica fontul folosit in cadrul formei specifica icon-ul care apare atunci cand sageata mouse-uluise afla deasupra formei permite setarea unei imagini de background

- variaza gradul de transparenta al formei - valori posibile: in intervalul [0, 1]. Valoarea 1 indica faptul ca forma este complet opaca, iar valoarea 0 creaza o forma complet transparenta. Valorile intermediare imprima formei o transparenta partiala. Valoarea implicita este 1 (opacitate totala). // o forma semi-transparentaPage 38 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 clasa System.Windows.Forms.Form. Printre acestea, se gasesc metodele responsabile de modul de afisare si de posibilitatile de accesare a formei in mediul de lucru. Cele mai importante 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 langa instantele formelor create in cod, aplicatia creaza o instanta a formei de start-up in lansarii in executie a programului. Show si ShowDialog - Form.Show - face forma vizibila (se incarca in memorie o instanta a formei, se afiseaza forma pe ecran si primeste focus-ul aplicatiei). Proprietatea Visible este setata la true dupa apelul lui Form.Show. Pentru o forma incarcata in memorie dar care este invizibila (de exemplu, daca proprietatea Visible a fost setata la valoarea false), apelul Form.Show are acelasi efect ca setarea proprietatii Visible la valoarea true. - Form.ShowDialog - in plus, afiseaza forma modal, adica forma trebuie inchisa inainte ca 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 metoda Form.Activate apelata in cadrul aplicatiei active, metoda Form.Activate aduce forma in prim-planul aplicatiei si ii transmite focus-ul apelarea metodei pentru o aplicatie inactiva in interfata utilizator, determina clipirea titlului aplicatiei din taskbar forma pentru care se apeleaza metoda Activate trebuie sa fie vizibila pentru a obtineDezvoltare de aplicatii in Visual Studio .NET Page 39 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

efectul scontat. //apelarea metodei Activate myForm.Activate(); Hide face forma invizibila. Desi forma persista in memorie, nu va mai fi vizibila pana la apelarea metodei Form.Show sau la setarea proprietatii Visible la valoarea true in cod 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 ca resursele 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 lanseaza evenimentul, iar o alta componenta a aplicatiei are oportunitatea de a trata evenimentul respectiv. Fiecare dintre metodele prezentate anterior lanseaza unul sau mai multe evenimente; utilizatorul are oportunitatea de a trata prin cod aceste evenimente. Exemple: apelul metodei Form.Hide determina lansarea evenimentelor Deactivate si VisibleChanged. Un event handler este o metoda care se executa ca raspuns la lansarea 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 event handler-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:Page 40 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 cazul in care se cunoaste acest tip, printr-o conversie explicita a argumentului sender la tipul respectiv. De exemplu: Form1 myForm; myForm = (Form1)sender; In multe cazuri, parametrul EventArgs nu contine informatii folositoare din punct de vedere programatic. Exista insa situatii in care acest parametru furnizeaza informatii utile. 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 program la 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 formaDezvoltare de aplicatii in Visual Studio .NET Page 41 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

myForm.Show(); // exceptie, forma nu mai este disponibila ! evenimentul Load este lansat o singura data pe parcursul duratei de viata a unei instante 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 evenimentul numai daca forma este activa) ! Activated si Deactivate sunt lansate numai cand focus-ul este modificat prin intermediul 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 inca inchisa complet - prin apelul Form.Close sau prin apasarea butonului Close al formei - signatura event handler-ului asociat evenimentului Closing include o instansa a clasei CancelEventArgs //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 inchiderea manuala a formei; apare dupa lansarea evenimentului Closing si dupa executia tuturor handler-elor asociate acestuia Sinteza:Page 42 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Formele reprezinta elementul de baza al interfetei utilizator pentru un program de tip Windows Forms. Formele trebuie sa contina o interfata consistenta, completa si atractiva 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 diverse evenimente. Printre acestea: Load Activated/Deactivate VisibleChanged Closing Closed

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

3. Controale si componenteControalele 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 accepte input-ul utilizatorului si sa execute operatii bazate pe interactiunea utilizatorului - o alta parte constituie componente specializate, proiectate sa execute interactiuni complexe cu alte parti ale aplicatiei.

Dezvoltare de aplicatii in Visual Studio .NET

Page 43 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Asemanari si deosebiri intre controale si componente: ambele reprezinta unitati de cod care incapsuleaza functionalitati specifice; controalele au o reprezentare vizuala, in timp 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 mai frecvent, folosind fereastra Properties Adaugarea de componente la o forma se face in acelasi mod, la fel si setarea proprietatilor. Diferenta principala fata de controale este aceea ca nu exista o reprezentare 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-o anumita ordine - tab order. Aceasta ordine este specificata de proprietatea TabIndex. Pentru a stabili ordinea de primire a focus-ului, se seteaza proprietatea TabIndex a fiecarui control la o anumita valoare. Focus-ul va fi transmis controalelor in ordinea crescatoare a valorilor proprietatii TabIndex. Visual Studio ofera a alta modalitate de setare a ordinii de primire a focus-ului. Din meniul View, se alege Tab Order. In designer, apare o casuta in interiorul fiecarui control care, prin clic ofera posibilitatea setarii unui numar. Ordinea de primire a focus-ului este ordinea data de valorile numerelor 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 interiorul lor. Exemple de astfel de controale - Panel, GroupBox si TabControl. Pot fi folosite pentru organizarea logica a grupurilor de controale pe o forma. De exemplu, se pot grupa un set de butoane radio intr-un control GroupBox. ! - Un control container se comporta ca o gazda pentru alte controale, dar este independent de aceste controale. In contrast, exista controale utilizator care pot lega controale multiple intr-o singura unitate interdependenta. - Modificarea proprietatilor unui control container poate afecta proprietatile controalelor continute. De exemplu, daca proprietatea Enabled a unui GroupBox este setata la false, toate controalele continute devin disabled. La fel se intampla in cazul proprietatilor BackColor, ForeColor, Visible si Font. Acesta confera un aspectPage 44 of 203 Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

consistent interfetei utilizator. GroupBox si Panel Sunt doua controale container similare. Amandoua furnizeaza posibilitatea gruparii logice si fizice a controalelor. Pot fi proiectate ca subdiviziuni ale formei. Modificarea proprietatilor 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 (modificand proprietatea Text). Panel - un container cu scroll, nu contine o proprietate text. Setand proprietatea AutoScroll la true, se ataseaza bare de defilare panel-ului respectiv. TabControl - grupeaza controalele intr-o multime de tabele (similar diviziunilor dintr-o carte de adrese) - un TabControl este un suport pentru un anumit numar de TabPages, care gazduiesc alte controale - exemplu de TabControl: pagini de proprietati pentru o aplicatie, fiecare tab continand proprietati referitoare la o componenta specifica aplicatiei. Proprietatea TabPages reprezinta o colectie de controale TabPage, fiecare cu setul sau 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 cadrul formei sau controlului parinte. - Anchor permite definirea unei distante constante intre un control si una sau mai multe margini ale formei - redimensionarea unei forme la run time implica pastrarea unei distante specifice fata de marginile indicate - valori posibile : o enumerare care poate contine, separate prin virgule una sau mai multe dintre valorile Top, Left, Right, Bottom - Dock permite atasarea controlului la una din marginile formei sau ocuparea completa a formei de catre control - redimensionarea formei atrage dupa sine redimensionarea controlului - setarea valorii se face prin folosirea micro-interfetei grafice puse la dispozitie in fereastra 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 deDezvoltare de aplicatii in Visual Studio .NET Page 45 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

elemente continute si o proprietate Item care returneaza un element specific. Exista, de asemene, metode care pot fi folosite pentru a adauga si elimina controale in cadrul colectiei. // 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 a localiza un control inca neinregistrat. ! un control care se doreste adaugat trebuie recunoscut ca ActiveX Control, componenta COM sau assembly .NET Event Handlere pentru controale Fiecare control poate lansa o varietate de evenimente care corespund interactiunii cu utilizatorul. Un exemplu este apasarea unui buton care determina lansarea unui eveniment, cautandu-se apoi eventualele handlere; handlerele gasite sunt lansate in executie. Fiecare control are un eveniment implicit asociat, care reprezinta evenimentul lansat cel mai frecvent. De exemplu, evenimentul implicit pentru Button este Click, iar

Page 46 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

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 asociata event 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 evenimentelor disponibile pentru controlul respectiv. 3. Se alege evenimentul dorit, apoi se scrie codul. 4. Daca exista deja event handler-e implementate pentru controlul respectiv, se poate alege una din metodele existente, din drop-down-ul asociat evenimentului respectiv. Interactiunea cu mouse-ul Tabel - Evenimente determinate de interactiunea cu mouse-ul Eveniment MouseEnter MouseMove MouseHover MouseDown MouseWheel MouseUp MouseLeave Descriere mouse-ul intra in zona controlului mouse-ul se misca pe suprafata controlului mouse-ul se afla pe suprafata controlului mouse-ul se afla pe suprafata controlului si se apasa un buton miscarea rotitei de scroll a mouse-ului atunci cand controlul are focus-ul mouse-ul se afla pe suprafata controlului si se elibereaza un buton mouse-ul paraseste suprafata controlului Tip EventArgs System.EventArgs System.MouseEventArgs System.EventArgs System.MouseEventArgs System.MouseEventArgs System.MouseEventArgs System.EventArgs

MouseEnter, MouseHover si MouseLeave semnaleaza faptul ca mouse-ul se afla in regiunea unui control, transmitand putine informatii event handler-elor. MouseMove, MouseDown, MouseWheel si MouseUp, din contra, pot fi folosite pentru a implementa interactiuni substantiale intre utilizator si interfata. Un obiect de tip MouseEventArgs contine informatii despre starea si locatia mouse-ului. Tabel - proprietati MouseEventArgs Proprietate DescrierePage 47 of 203

Dezvoltare de aplicatii in Visual Studio .NET

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

Button Clicks Delta

specifica daca s-a apasat un buton al mouse-ului returneaza numarul de click-uri efectuate Returneaza numarul de actionari asupra rotitei mouse-ului; acesta poate fi pozitiv sau negativ - deplasare inainte sau inapoi; fiecare astfel de deplasare adauga sau scade 120 din valoarea anterioara returneaza coordonta x a mouse-ului in momentul executiei unui click returneaza coordonta y a mouse-ului in momentul executiei unui click

x y

Componente de tip Extender Provider Furnizeaza proprietati aditionale controalelor. Exemplu: ToolTipProvider. La adaugarea unei instante a unui ToolTipProvider pe o forma, fiecare control de pe forma capata o noua propritate - ToolTip on n, unde n este numele ToolTipProvider-ului. La run-time, valoara acestei proprietati este afisata intr-o casuta 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 numele proprietatii. Exemple: GetToolTip si SetToolTip, care pot fi folosite dinamic in cod pentru a modifica mesajele 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 sau selectand Tab Order din meniul View si executand click pe controale in ordinea dorita. Controale container: - Panel - GroupBox

Page 48 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

- TabPage Proprietatile Dock si Anchor implementeaza redimensionarea automata controalelor pe o forma. Colectia de controale asociate unei forme permite adaugarea dinamica de controale la run time. Adaugarea de noi controale la un ToolBox se face prin selectarea din lista controalelor inregistrate in sistem a controlului dorit sau prin selectarea fisierului .dll sau .exe asociat, din file system. Event handlere - metode care trateaza evenimentele Componente de tip Extender Provider - furnizeaza informatii aditionale pentru controalele de pe o forma.

4. MeniuriMeniurile 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 parcursul logic al aplicatiei, elementele componente ale meniului trebuie grupate in concordanta cu o anumita functionalitate. Crearea meniurilor folosind Design View Se foloseste componenta MainMenu. Aceasta contine si gestioneaza o colectie de controale MenuItem care reprezinta elementele vizuale ale unui meniu la run time. Componenta MainMenu

Dezvoltare de aplicatii in Visual Studio .NET

Page 49 of 203

ibm.com/developerWorks

Presented by developerWorks, your source for great tutorials

* Crearea de noi meniuri si bare de meniu * Adaugarea de menu items la meniuri existente * Modificarea proprietatilor meniurilor si a elementelor meniurilor prin intermediul ferestrei Properties * Crearea de event handlere La adaugarea unei optiuni intr-un meniu, designer-ul creaza o instanta a unui obiect MenuItem. Fiecare obiect MenuItem are proprietatile si membrii sai care pot fi modificati in fereastra Properties. Doua proprietati importante: Text - contine textul afisat la run time si Name - numele asociat instantei MenuItem, prin care se va face referire 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 elemente ale meniului, folosta de obicei pentru a face o separarea logica a functionalitatilor din cadrul unui meniu. Se realizeaza prin tastatea caracterului - in spatiul rezervat numelui elementului 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 taste formate din Alt si o litera. Atunci cand meniul este deschis, se poate selecta o anumita comanda folosind combinatia de taste Alt + litera de acces corecta. Exemplu : Alt + F deschide 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 optiunea respectiva Taste de shortcut Permit accesul instant la comenzi de meniu, furnizand un shortcut pentru comenzi frecvente din meniu. Combinatia de taste asociata unei comenzi poate fi formata dintr-o singura tasta, cum ar fi Delete, F2 sau Insert, sau din mai multe, de exemplu Ctrl+B, Ctrl+F3 sau Alt+Shift+S. In cazul in care proprietatea ShowShortcut a unui element 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

Page 50 of 203

Dezvoltare de aplicatii in Visual Studio .NET

Presented by developerWorks, your source for great tutorials

ibm.com/developerWorks

Evenimente asociate elementelor meniurilor Metodele care trateaza evenimentele lansate de elementele meniurilor se creeaza similar altor controale. - Cel mai frecvent folosit eveniment este Click - Evenimentul Select este lansat la vizualizarea unui meniu prin click sau folosind tastele de acces. Poate fi utilizat pentru crearea unui help privitor la modul de utilizare a unei anumite comenzi. - Evenimentul Popup este lansat inainte ca un element al meniului sa fie afisat. O aplicatie utila poate fi activarea sau dezactivarea anumitor elemente de meniu la run time. Meniuri contextuale Un meniu contextual este vizualizat la apasarea butonului dreapta al mouse-ului pe forma sau controlul caruia ii este asociat. Se creaza folosind componenta ContextMenu. Se editeaza similar componentei MainMenu. Meniurile contextuale gestioneaza o colectie de controale de tip menu-item, permite folosirea tastelor shortcut, dar nu se pot defini taste de acces. Pentru a asocia un meniu contextual unei forme sau unui control, se seteaza proprietatea ContextMenu a formei sau controlului respectiv la numele meniului contextual dorit. ! un meniu contextual poate fi asociat mai multor controale, insa un singur meniu contextual 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