Professional Documents
Culture Documents
Gojdu, Oradea Nicolae Olroiu profesor, Colegiul Naional B.P. Hadeu, Buzu Rodica Pintea profesor, Liceul Grigore Moisil, Bucureti (capitolul 1) Cristina Sichim profesor, Colegiul Naional Ferdinand I, Bacu Daniela Taras Inspector Informatic, ISJ Bacu Coordonatori: Mihai Ttran cadru didactic asociat, Universitatea Politehnic Timioara Nua Dumitriu-Lupan inspector General MECT Petru Jucovschi Developer Community Lead, Microsoft Romnia
.Net Framework
Ediia 2008
Introducere n
Cerine de sistem
Arhitectura suportat: x86 x64 (WOW) Sistem de operare suportat: Microsoft Windows XP Microsoft Windows Server 2003 Windows Vista Cerine Hardware: Minimum: CPU 1.6 GHz, RAM 192 MB, Rezoluie Monitor 1024x768, Disc 5400 RPM Recomandat: CPU 2.2 GHz sau mai puternic, RAM 384 MB sau mai mult, rezoluie monitor 1280x1024, Disc 7200 RPM sau mai mult. Windows Vista: CPU 2.4 GHz, RAM 768 MB, Spaiu liber disc 1.3 GB pentru instalare complet Resurse i Instrumente: www.microsoft.ro/ark - Academic Resource Kit, educaionale. colecie de instrumente software i resurse
Cuvnt nainte
Dragi elevi, Introducere n .NET Framework este un curs dezvoltat n cadrul programului Microsoft Parteneri pentru Educaie, n colaborare cu un grup de profesori de informatic din Romnia. Pn la sfritul anului colar 2007-2008 va fi disponibil n pe situl Microsoft Romnia, n pagina Seciuni pentru educaie. Cursul v propune s explorai tehnologia .NET, cea mai rspndit platform de aplicaii software. Avei posibilitatea s studiai soluii software i s dezvoltai aplicaii ce pot fi trimise la concursuri sau pot fi integrate n proiecte educaionale. Suportul de curs este publicat n dou versiuni. Cea pentru elevi cuprinde doar componenta de specialitate. Versiunea pentru profesori cuprinde pe lng componenta de specialitate i pe cea metodic de predare. Suportul de curs poate fi descrcat gratuit i folosit exclusiv n procesul educaional. Scopul acestei iniiative a programului Parteneri pentru Educaie este de a ncuraja dezvoltarea profesional a profesorilor i de a da un suflu nou experienei educaionale la materia Informatic. mpreun cu partenerii, echipa Microsoft Romnia v mulumete pentru interesul pentru studiul tehnologiei .Net. Sperm dragi elevi, s v dezvoltai potenialul tehnic i creativ pentru a deveni competitivi dup absolvirea liceului.
Adrian Ni, profesor, Colegiul Naional Emanuil Gojdu, Oradea Maria Ni, profesor, Colegiul Naional Emanuil Gojdu, Oradea Nicolae Olroiu, profesor Colegiul Naional B.P. Hadeu, Buzu Rodica Pintea, profesor, Liceul Grigore Moisil, Bucureti (capitolul 1) Cristina Sichim, profesor, Colegiul Naional Ferdinand I, Bacu Daniela Taras, Inspector Informatic, ISJ Bacu
Coordonatori:
Mihai Ttran, cadru didactic asociat, Universitatea Politehnica din Timioara Nua Dumitriu-Lupan, Inspector General MECT Petru Jucovschi, Developer Community Lead, Microsoft Romnia
Formatul electronic al textului digital: PDF Editat de BYBLOS SRL sub coordonarea Agora Media SA, pentru Microsoft Romnia. Ediia 2008. ISBN: 973-86699-5-2
Not: Acest suport de curs este destinat elevilor de la clasele matematic-informatic i matematic-informatic intensiv, care au optat n programa colar, pentru variantele: Programare orientat obiect, Progamare vizual cu C# i Programare web cu Asp.Net. Suportul de curs poate fi utilizat gratuit exclusiv n procesul de predare-nvare. Este interzis utilizarea suportului de curs Introducere n .Net Framework pentru scopuri comerciale sau n alte scopuri n afara celui descris mai sus. Drepturile de autor asupra suportului de curs Introducere n .Net Framework aparin Microsoft.
CUPRINS
1 Programarea Orientat Obiect (POO) cu C# . . . . . . . . . . . . . . . . . . . . . . . . . . . .7
1.1. Evoluia tehnicilor de programare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7 1.2. Tipuri de date obiectuale. ncapsulare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 1.3. Suprancrcare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9 1.4. Motenire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10 1.5. Polimorfism. Metode virtuale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10 1.6. Programare orientat obiect n C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 1.7. Declararea unei clase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11 1.8. Constructori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12 1.9. Destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14 1.10. Metode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14 1.11. Proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16 1.12. Evenimente i delegri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17 1.13. Interfee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
2.
3.
Limbajul C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25
3.1. Caracterizare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25 3.2. Compilarea la linia de comand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25 3.3. Crearea aplicaiilor consol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26 3.4. Structura unui program C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27 3.5. Sintaxa limbajului . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28 3.6. Tipuri de date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30 3.7. Conversii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34 3.7.1. Conversii numerice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .34 3.7.2. Conversii ntre numere i iruri de caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36 3.7.3. Conversii boxing i unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38 3.8. Constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39 3.9. Variabile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39 3.10. Expresii i operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39 3.11. Instruciuni condiionale, de iteraie i de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40 3.11.1. Instruciunea if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
3.11.2. Instruciunea while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40 3.11.3. Instruciunea do while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41 3.11.4. Instruciunea for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42 3.11.5. Instruciunea switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42 3.11.6. Instruciunea foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43 3.11.7. Instruciunea break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43 3.11.8. Instruciunea continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43 3.11.9. Instruciunea goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44 3.12. Instruciunile try-catch-finally i throw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
4.
5.
6.
ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89
6.1. Arhitectura ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90 6.2. Furnizori de date (Data Providers) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90 6.3. Connection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90 6.3.1. Exemple de conectare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91 6.3.2. Proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91 6.3.3. Metode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .92 6.3.4. Evenimente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .92 6.4. Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .92 6.4.1. Proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93 6.4.2. Metode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93 6.4.3. Interogarea datelor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .95 6.4.4. Inserarea datelor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .95 6.4.5. Actualizarea datelor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .95 6.4.6. tergerea datelor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96 6.5. DataReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99 6.5.1. Proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99 6.5.2. Metode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99 6.6. DataAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101 6.6.1. Proprieti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102 6.6.2. Metode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102 6.7. DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102 6.8. SqlParameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .104 6.9. Proceduri Stocate (Stored Procedures) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105 6.10. Proiectarea vizual a seturilor de date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
CAPITOLUL
Se observ c modulele sunt centrate pe proceduri, acestea gestionnd i setul de date pe care le prelucreaz (date+date1 din figur). Daca, de exemplu, dorim s avem mai multe seturi diferite de date, toate nzestrate comportamental cu procedurile din modulul module1, aceast arhitectur de aplicaie nu este avantajoas. Programarea orientat obiect (programe cu noi tipuri ce integreaz att datele, ct i metodele asociate crerii, prelucrrii i distrugerii acestor date); se obin avantaje prin abstractizarea programrii (programul nu mai este o succesiune de prelucrri, ci un ansamblu de obiecte care prind via, au diverse proprieti, sunt
capabile de aciuni specifice i care interacioneaz n cadrul programului); intervin tehnici noi privind instanierea, derivarea i polimorfismul tipurilor obiectuale.
aferent datelor sale, se aplic o metod specific numit destructor1. O aplicaie ce utilizeaz tipul obiectual STIVA, va putea construi dou sau mai multe stive (de cri de joc, de exemplu), le va umple cu valori distincte, va muta valori dintr-o stiv n alta dup o anumit regul desfiinnd orice stiv golit, pn ce rmne o singur stiv. De observat c toate aceste prelucrri recurg la datele, constructorul, destructorul i la metodele din interfaa tipului STIVA descris mai sus. Principalul tip obiectual ntlnit n majoritatea mediilor de dezvoltare (Viisual Basic, Delphi, C++, Java, C#) poart numele de clas (class). Exist i alte tipuri obiectuale (struct, object). O instan a unui tip obiectual poart numele de obiect. La implementare, datele i metodele asociate trebuie s fie complet i corect definite, astfel nct utilizatorul s nu fie nevoit s in cont de detalii ale acestei implementri. El va accesa datele, prin intermediul proprietilor i va efectua operaiile, prin intermediul metodelor puse la dispoziie de tipul obiectual definit. Spunem c tipurile de date obiectuale respect principiul ncapsulrii. Astfel, programatorul ce utilizeaz un tip obiectual CONT (n banc) nu trebuie s poarte grija modului cum sunt reprezentate n memorie datele referitoare la un cont sau a algoritmului prin care se realizeaz actualizarea soldului conform operaiilor de depunere, extragere i aplicare a dobnzilor. EL va utiliza unul sau mai multe conturi (instane ale tipului CONT), accesnd proprietile i metodele din interfa, realizatorul tipului obiectual asumndu-i acele griji n momentul definirii tipului CONT. Permind extensia tipurilor de date abstracte, clasele pot avea la implementare: date i metode caracterisitice fiecrui obiect din clas (membri de tip instan), date i metode specifice clasei (membri de tip clas). Astfel, clasa STIVA poate beneficia, n plus, i de date ale clasei cum ar fi: numrul de stive generate, numrul maxim sau numrul minim de componente ale stivelor existente etc. Modificatorul static plasat la definirea unui membru al clasei face ca acela s fie un membru de clas, nu unul de tip instan. Dac n cazul membrilor nestatici, exist cte un exemplar al membrului respectiv pentru fiecare instan a clasei, membrii statici sunt unici, fiind accesai n comun de toate instanele clasei. Mai mult, membrii statici pot fi referii chiar i fr a crea vreo instan a clasei respective.
1.3. Suprancrcare
Dei nu este o tehnic specific programrii orientat obiect, ea creeaz un anumit context pentru metodele ce formeaz o clas i modul n care acestea pot fi (ca orice subprogram) apelate. Prin suprancarcare se nelege posibilitatea de a defini n acelai domeniu de vizibilitate2 mai multe funcii cu acelai nume, dar cu parametri diferiti ca tip i/sau ca numr. Astfel ansamblul format din numele funciei i lista sa de parametri reprezint o modalitate unic de identificare numit semntur sau amprent. Supra-
1 Datorit tehnicii de suprancrcare C++, Java i C# permit existena mai multor constructori 2 Noiunile generale legate de vizibilitate se consider cunoscute din programarea procedural. Aspectele specifice
10
ncrcarea permite obinerea unor efecte diferite ale apelului n contexte diferite3. Apelul unei funcii care beneficiaz, prin suprancrcare, de dou sau mai multe semnturi se realizeaz prin selecia funciei a crei semntur se potrivete cel mai bine cu lista de parametri efectivi (de la apel). Astfel, poate fi definit metoda comand on-line cu trei semnturi diferite: comanda_online(cod_prod) cu un parametru ntreg (desemnnd comanda unui singur produs identificat prin cod_prod. comanda_online(cod_prod,cantitate) cu primul parametru ntreg i celalalt real comanda_online(cod_prod,calitate) cu primul parametru ntreg i al-II-lea caracter.
1.4. Motenire
Pentru tipurile de date obiectuale class este posibil o operaie de extindere sau specializare a comportamentului unei clase existente prin definirea unei clase noi ce motenete datele i metodele clasei de baz, cu aceast ocazie putnd fi redefinii unii membri existeni sau adugai unii membri noi. Operaia mai poart numele de derivare. Clasa din care se motenetea se mai numete clas de baz sau superclas. Clasa care motenete se numete subclas, clas derivat sau clas descendent. Ca i n Java, n C# o subclas poate moteni de la o singur superclas, adic avem de-a face cu motenire simpl; aceeai superclas ns poate fi derivat n mai multe subclase distincte. O subclas, la randul ei, poate fi superclas pentru o alt clas derivat. O clas de baz impreun cu toate clasele descendente (direct sau indirect) formeaza o ierarhie de clase. n C#, toate clasele motenesc de la clasa de baz Object. n contextul mecanismelor de motenire trebuie amintii modificatorii abstract i sealed aplicai unei clase, modificatori ce oblig la i respectiv se opun procesului de derivare. Astfel, o clas abstract trebuie obligatoriu derivat, deoarece direct din ea nu se pot obine obiecte prin operaia de instaniere, n timp ce o clas sigilat (sealed) nu mai poate fi derivat (e un fel de terminal n ierarhia claselor). O metod abstract este o metod pentru care nu este definit o implementare, aceasta urmnd a fi realizat n clasele derivate din clasa curent4. O metod sigilat nu mai poate fi redefinit n clasele derivate din clasa curent.
zint suprancrcarea operatorilor. Aceasta este o facilitate care "reduce" diferenele dintre operarea la nivel abstract (cu DTA) i apelul metodei ce realizeaz acest operaie la nivel de implementare obiectual. Dei ajut la sporirea expresivitii codului, prin suprancrcarea operatorilor i metodelor se pot crea i confuzii. 4 care trebuie s fie i ea abstract (virtual pur, conform terminologiei din C++) 5 deoarece tot aspecte polimorfice mbrac i unele tehnici din programarea clasic sau tehnica suprancrcrcrii funciilor i operatorilor.
11
rii avnd ns acelai nume. Astfel, n cazul unei referiri obiectuale, se pune problema stabilirii datei sau metodei referite. Comportamentul polimorfic este un element de flexibilitate care permite stabilirea contextual, n mod dinamic6, a membrului referit. De exemplu, dac este definit clasa numit PIESA (de ah), cu metoda nestatic muta(pozitie_initiala,pozitie_finala), atunci subclasele TURN i PION trebuie s aib metoda muta definit n mod diferit (pentru a implementa maniera specific a pionului de a captura o pies en passant7). Atunci, pentru un obiect T, aparinnd claselor derivate din PIESA, referirea la metoda muta pare nedefinit. Totui mecanismele POO permit stabilirea, n momentul apelului, a clasei proxime creia i aparine obiectul T i apelarea metodei corespunztore (mutare de pion sau tur sau alt pies). Pentru a permite acest mecanism, metodele care necesit o decizie contextual (n momentul apelului), se declar ca metode virtuale (cu modificatorul virtual). n mod curent, n C# modificatorului virtual al funciei din clasa de baz, i corespunde un specificator override al funciei din clasa derivat ce redefinete funcia din clasa de baz. O metod ne-virtual nu este polimorfic i, indiferent de clasa creia i aparine obiectul, va fi invocat metoda din clasa de baz.
6 Este posibil doar n cazul limbajelor ce permit "legarea ntrziat". La limbajele cu "legare timpurie", adresa la care
se face un apel al unui subprogram se stabilete la compilare. La limbajele cu legare ntrziat, aceast adresa se stabileste doar in momentul rulrii, putndu-se calcula distinct, n funcie de contextul n care apare apelul. 7 ntr-o alt concepie, metoda muta poate fi implementat la nivelul clasei PIESA i redefinit la nivelul subclasei PION, pentru a particulariza acest tip de deplasare care captureaz piesa peste care trece pionul n diagonal. 8 echivalentrul claselor template din C++ 9 [] din definiia schematic semnific un neterminal, iar o semnific o component opional
12
utilizator, metode (subprograme), constructori, un destructor, proprieti (caracteristici ce pot fi consultate sau setate), evenimente (instrumente de semnalizare), indexatori (ce permit indexarea instanelor din cadrul clasei respective) i operatori. constructorii i destructorul au ca nume numele clasei proxime din care fac parte10 metodele au nume care nu coincid cu numele clasei sau al altor membri (cu excepia metodelor, conform mecanismului de suprancrcare) metodele sau constructorii care au acelai nume trebuie s difere prin semntur11 se pot defini date i metode statice (caracteristice clasei) i un constructor static care se execut la iniializarea clasei propriu-zise; ele formeaz un fel de context al clasei se pot defini date i metode nestatice (de instan) care se multiplic pentru fiecare instan n parte n cadrul operaiei de instaniere; ele formeaz contextele tuturor instanelor clasei respective Exemplul urmtor definete o ierarhie de clase (conform figurii alturate)
public abstract class Copil { } public class Fetita: Copil { } public sealed class Baiat: Copil { }
Modificatorul abstract este folosit pentru a desemna faptul c nu se pot obine obiecte din clasa Copil, ci numai din derivatele acesteia (Fetita, Baiat), iar modificatorul sealed a fost folosit pentru a desemna faptul c nu se mai pot obtine clase derivate din clasa Baiat (de exemplu, subclasele Baiat_cuminte i Baiat_rau)
1.8. Constructori
Sintaxa: [atrib]o [modificatori]o [nume_clas]([list_param_formali]o)[:iniializator]o [corp_constr]o Modificatori: public protected internal private extern Iniializator: base([list_param]o), this([list_param]o) ce permite invocarea unui constructor anume12 nainte de executarea instruciunilor ce formeaz corpul constructorului curent. Dac nu este precizat niciun iniializator, se asociaz implicit iniializatorul base(). Corpul constructorului este format din instruciuni care se execut la crearea unui
10 avnd n vedere c ele pot s fac parte dintr-o clas interioar altei clase 11 din semntur nefcnd parte specificatorii ref i out asociai parametrilor 12 Din clasa de baz (base) sau din clasa insi (this)
13
nou obiect al clasei respective (sau la crearea clasei, n cazul constructorilor cu modificatorul static). pot exista mai muli constructori care se pot diferenia prin lista lor de parametri constructorii nu pot fi motenii dac o clas nu are definit niciun constructor, se va asigna automat constructorul fr parametri al clasei de baz (clasa object, dac nu este precizat clasa de baz) Instanierea presupune declararea unei variabile de tipul clasei respective i iniializarea acesteia prin apelul constructorului clasei (unul dintre ei, dac sunt definii mai muli) precedat de operatorul new. Acestea se pot realiza i simultan ntr-o instruciune de felul: [Nume_clas] [nume_obiect]=new [Nume_clas] ([list_param]o) Utilizarea unui constructor fr parametri i a constructorului implicit n clas derivat
public abstract class Copil { protected string nume; public Copil() {nume = Console.ReadLine();} //la iniializarea obiectului se
claselor derivate
public Copil() {nume = Console.ReadLine();} public Copil(string s) {nume=s;} } class Fetita:Copil { public Fetita(string s):base(s) {nume=Fetita +nume}13 public Fetita(){} //preia constructorul fr parametri din clasa de baz14 //public Fetita(string s):base() {nume=s} } ... Copil c1= new Copil(); //se citeste numele de la tastatur Copil c2= new Copil(Codrina); Fetita f1=new Fetita();Fetita f2=new Fetita(Ioana);
13 Preia i specializeaz constructorul al doilea din clasa de baz 14 Este echivalent cu public Fetita():base(){}
14
Exist dou motive pentru care definiia constructorului al treilea din clasa Fetita este greit i de aceea este comentat. Care sunt aceste motive?
1.9. Destructor
Sintaxa: [atrib]o [extern]o ~[nume_clas] () [corp_destructor]o Corpul destructorului este format din instruciuni care se execut la distrugerea unui obiect al clasei respective. Pentru orice clas poate fi definit un singur constructor. Destructorii nu pot fi motenii. n mod normal, destructorul nu este apelat n mod explicit, deoarece procesul de distrugere a unui obiect este invocat i gestionat automat de Garbagge Collector.
1.10. Metode
Sintaxa:[atrib]o[modificatori]o[tip_returnat][nume]([list_param_formali]o) [corp_metoda]o Modificatori: new public protected internal private static virtual abstract sealed override extern15 Tipul rezultat poate fi un tip definit sau void. Numele poate fi un simplu identificator sau, n cazul n care definete n mod explicit un membru al unei interfee, numele este de forma [nume_interfata].[nume_metoda] Lista de parametri formali este o succesiune de declarri desprite prin virgule, declararea unui parametru avnd sintaxa: [atrib]o [modificator]o [tip] [nume] Modificatorul unui parametru poate fi ref (parametru de intrare i ieire) sau out (parametru care este numai de ieire). Parametrii care nu au niciun modificator sunt parametri de intrare. Un parametru formal special este parametrul tablou cu sintaxa: [atrib]o params [tip][] [nume]. Pentru metodele abstracte i externe, corpul metodei se poate reduce la un semn ; Semntura fiecrei metode este format din numele metodei, modificatorii acesteia, numrul i tipul parametrilor16 Numele metodei trebuie s difere de numele oricrui alt membru care nu este metod. La apelul metodei, orice parametru trebuie s aib acelai modificator ca la definire Invocarea unei metode se realizeaz prin sintagma [nume_obiect].[nume_metoda] (pentru metodele nestatice) i respectiv [nume_clas].[nume_metoda] (pentru metodele statice). Definirea datelor i metodelor statice corespunztoare unei clase
15 Poate fi folosit cel mult unul dintre modificatorii static, virtual I override ; nu pot aprea mpreun new i over-
ride, abstract nu poate s apar cu niciunul dintre static, virtual, sealed, extern; private nu poate s apar cu niciunul dintre virtual, override i abstract; seald oblig i la override 16 Din semntur (amprent) nu fac parte tipul returnat, numele parametrilor formali i nici specificatorii ref i out.
15
public class Copil { public const int nr_max = 5; //constant public static int nr_copii=0; //cmp simplu (variabil) static Copil[] copii=new Copil[nr_max]; //cmp de tip tablou (variabil) public static void adaug_copil(Copil c) //metod { copii[nr_copii++] = c; if (nr_copii==nr_max) throw new Exception(Prea multi copii); } public static void afisare() //metod { Console.WriteLine(Sunt {0} copii:, nr_copii); for (int i = 0; i<nr_copii; i++) Console.WriteLine(Nr.{0}. {1}, i+1, copii[i].nume); } ...17 } ... Fetita c = new Fetita();Copil.adaug_copil(c);
referina noului obiect se memoreaz n tabloul static copii (caracteristic clasei) i se incrementeaz data static nr_copii
Baiat c = new Baiat(); Copil.adaug_copil(c); Copil c = new Copil(); Copil.adaug_copil(c); Copil.afisare(); //se afieaz o list cu numele celor 3 copii
derivare
{Console.WriteLine({0} se joaca., this.nume);} public void se_joaca(string jucaria) //nu permite redefinire18 {Console.WriteLine({0} se joaca cu {1}., this.nume, jucaria);} } //suprancrcarea metodei se_joaca class Fetita:Copil { public override void se_joaca() //redefinire comportament polimorfic {Console.WriteLine({0} leagana papusa.,this.nume);} } class Baiat:Copil { public override void se_joaca() {Console.WriteLine({0} chinuie pisica.,this.nume);} } ...
17 Se are n vedere i constructorul fr parametri definit i preluat implicit n subclasele din cadrul primului exem-
16
Fetita c = new Fetita();c.se_joaca(pisica);c.se_joaca(); //polimorfism Baiat c = new Baiat();c.se_joaca(calculatorul);c.se_joaca(); //polimorfism Copil c = new Copil();c.se_joaca(); //polimorfism
Pentru a evidenia mai bine comportamentul polimorfic, propunem secvena urmtoare n care nu se tie exact ce este obiectul copii[i] (de tip Copil, Fetita sau Baiat):
for (int i=0; i<nr_copii; i++) copii[i].se_joaca();
1.11. Proprieti
Proprietatea este un membru ce permite accesul controlat la datele-membru ale clasei. Sintaxa: [atrib]o [modificatori]o [tip] [nume_proprietate] {[metode_de_acces]o} Observaiile privind modificatorii i numele metodelor sunt valabile i n cazul proprietilor. Metodele de acces sunt dou: set i get. Dac proprietatea nu este abstract sau extern, poate s apar una singur dintre cele dou metode de acces sau amndou, n orice ordine. Este o manier de lucru recomandabil aceea de a proteja datele membru (cmpuri) ale clasei, definind instrumente de acces la acestea: pentru a obine valoarea cmpului respectiv (get) sau de a memora o anumit valoare n cmpul respectiv (set). Dac metoda de acces get este perfect asimilabil cu o metod ce retuneaz o valoare (valoarea datei pe care vrem s-o obinem sau valoarea ei modificat conform unei prelucrri suplimentare specifice problemei n cauz), metoda set este asimilabil cu o metod care un parametru de tip valoare (de intrare) i care atribuie (sau nu, n funcie de context) valoarea respectiv cmpului. Cum parametrul corespunztor valorii transmise nu apare n structura sintactic a metodei, este de stiut c el este implicit identificat prin cuvntul value. Dac se supune unor condiii specifice problemei, se face o atribuire de felul cmp=value. Definirea n clasa Copil a proprietii Nume, corespunztoare cmpului protejat ce reine, sub forma unui ir de caractere, numele copilului respctiv. Se va observ c proprietatea este motenit i de clasele derivate Fetita i Biat19.
public class Copil {... string nume; // este implicit protected public string Nume //proprietatea Nume { get { if(char.IsUpper(nume[0]))return nume; else return nume.ToUpper();} set { nume = value; } }
19 Desigur c proprietatea care controleaz accesul la cmpul identificat prin nume se poate numi cu totul altfel (proprietatea Nume fiind uor de confundat cu cmpul de date nume).
17
public Copil() {Nume = Console.ReadLine();} //metoda set } class Fetita:Copil { public override void se_joaca() {Console.WriteLine({0} leagana papusa.,this.Nume);} //metoda get }20
18
} public bool aranj(pereche_ok ok)//ok e o delegare ctre o funcie necunoscut { for (int i = 0; i < nmax-1; i++) if (!ok(v[i], v[i + 1])) return false; return true; } }
Revenind la evenimente, descriem pe scurt un exemplu teoretic de declarare i tratare a unui eveniment. n clasa Vector se consider c interschimbarea valorilor a dou componente ale unui vector e un eveniment de interes pentru alte obiecte sau clase ale aplicaiei. Se definete un tip delegat TD (s zicem) cu nite parametri de interes22 i un eveniment care are ca asociat un delegat E (de tip TD)23. Orice obiect x din clasa Vector are un membru E (iniial null). O clas C interesat s fie ntiinat cnd se face vreo interschimbare ntr-un vector pentru a genera o animaie, de exemplu, va implementa o metod M ce realizeaz animaia i va aduga pe M (prin intermediul unui delegat) la x.E24. Cumulnd mai multe astfel de referine, x.E ajunge un fel de list de metode (handlere). n clasa Vector, n metoda sort, la interschimbarea valorilor a dou componente se invoc delegatul E. Invocarea lui E realizeaz de fapt activarea tuturor metodelor adugate la E. Care credei c sunt motivele pentru care apelm la evenimente n acest caz, cnd pare mult mai simplu s apelm direct metoda M la orice interschimbare?
21 22 23 24
Independent de definiia clasei Vector De exmplu indicii componentelor interschimbate A se observa c evenimentul n sine este anonim, doar delegatul asociat are nume ntr-o atribuire de felul x.E+=new [tip_delegat](M)
19
1.13. Interfee
Interfeele sunt foarte importante n programarea orientat pe obiecte, deoarece permit utilizarea polimorfismului ntr-un sens mai extins.O interfa este o component a aplicaiei, asemntoare unei clase, ce declar prin membrii si (metode, proprieti, evenimente i indexatori) un comportament unitar aplicabil mai multor clase, comportament care nu se poate defini prin ierarhia de clase a aplicaiei. De exemplu, dac vom considera arborele din figura urmtoare, n care AVERE este o clas abstract, iar derivarea claselor a fost conceput urmrind proprietile comune ale componentelor unei averi, atunci o clas VENIT nu este posibil, deoarece ea ar moteni de la toate clasele evideniate, iar motenirea multipl nu este admis n C#.
Pentru metodele din cadrul unei interfee nu se d nici o implementare, ci sunt pur i simplu specificate, implementarea lor fiind furnizat de unele dintre clasele aplicaiei25. Nu exist instaniere n cazul interfeelor, dar se admit derivri, inclusiv moteniri multiple. n exemplul nostru, se poate defini o interfa VENIT care s conin antetul unei metode calc (s zicem) pentru calculul venitului obinut, fiecare dintre clasele care implementeaz interfaa VENIT fiind obligat s furnizeze o implementare (dup o formul de calcul specific) pentru metoda calc din interfa. Orice clas care dorete s adere la interfa trebuie s implementeze toate metodele din interfa. Toate clasele care motenesc dintr-o clas care implementeaz o interfa motenesc, evident, metodele respective, dar le pot i redefini (de exemplu, clasa Credit_acordat redefinete metoda calc din clasa Investiie, deoarece formula de calcul implementat acolo nu i se potrivete i ei26). De exemplu, dac presupunem c toate clasele subliniate implementeaz interfaa VENIT, atunci pentru o avere cu aciuni la dou firme, un imobil nchiriat i o
25 Acele clase care "ader" la o interfa spunem c "implementeaz" interfaa respectiv 26 Dac n sens polimorfic spunem c Investiie este i de tip Bani i de tip Avere, tot aa putem spune c o clas care
20
Gsii dou motive pentru care interfaa VENIT i rezovarea de mai sus ofer o soluie mai bun dect: t=act1.calc()+act2.calc()+casa.calc()+dep.calc().
21
CAPITOLUL
Platforma .NET
2.1 Prezentare
.NET este un cadru (Framework) de dezvoltare software unitar care permite realizarea, distribuirea i rularea aplicaiilor-desktop Windows i aplicaiilor WEB. Tehnologia .NET pune laolalt mai multe tehnologii (ASP, XML, OOP, SOAP, WDSL, UDDI) i limbaje de programare (VB, C++, C#, J#) asigurnd totodat att portabilitatea codului compilat ntre diferite calculatoare cu sistem Windows, ct i reutilizarea codului n programe, indiferent de limbajul de programare utilizat. .NET Framework este o component livrat mpreun cu sistemul de operare Windows. De fapt, .NET 2.0 vine cu Windows Server 2003, se poate instala pe versiunile anterioare, pn la Windows 98 inclusiv; .NET 3.0 vine instalat pe Windows Vista i poate fi instalat pe versiunile Windows XP cu SP2 i Windows Server 2003 cu minimum SP1. Pentru a dezvolta aplicaii pe platforma .NET este bine sa avem 3 componente eseniale: un set de limbaje (C#, Visual Basic .NET, J#, Managed C++, Smalltalk, Perl, Fortran, Cobol, Lisp, Pascal etc), un set de medii de dezvoltare (Visual Studio .NET, Visio), i o bibliotec de clase pentru crearea serviciilor Web, aplicaiilor Web i aplicaiilor desktop Windows. Cnd dezvoltm aplicaii .NET, putem utiliza: Servere specializate - un set de servere Enterprise .NET (din familia SQL Server 2000, Exchange 2000 etc), care pun la dispoziie funcii de stocare a bazelor de date, email, aplicaii B2B (Bussiness to Bussiness comer electronic ntre partenerii unei afaceri). Servicii Web (n special comerciale), utile n aplicaii care necesit identificarea utilizatorilor (de exemplu, .NET Passport - un mod de autentificare folosind un singur nume i o parol pentru toate ste-urile vizitate) Servicii incluse pentru dispozitive non-PC (Pocket PC Phone Edition, Smartphone, Tablet PC, Smart Display, XBox, set-top boxes, etc.) .NET Framework Componenta .NET Framework st la baza tehnologiei .NET, este ultima interfa
22
ntre aplicaiile .NET i sistemul de operare i actualmente conine: Limbajele C#, VB.NET, C++ i J#. Pentru a fi integrate n platforma .NET toate aceste limbaje respect nite specificaii OOP numite Common Type System (CTS). Ele au ca elemente de baz: clase, interfee, delegri, tipuri valoare i referin, iar ca mecanisme: motenire, polimorfism i tratarea excepiilor. Platforma comun de executare a programelor numit Common Language Runtime (CLR), utilizat de toate cele 4 limbaje. CTS face parte din CLR. Ansamblul de biblioteci necesare n realizarea aplicaiilor desktop sau Web numit Framework Class Library (FCL). Arhitectura .NET Framework
Componenta .NET Framework este format din compilatoare, biblioteci i alte executabile utile n rularea aplicaiilor .NET. Fiierele corespunztoare se afl, n general, n directorul C:\WINDOWS\Microsoft. NET\Framework\V2.0. (corespunztor versiunii instalate)
23
n plus, CLR se ocup de gestionarea automat a memoriei (un mecanism implementat n platforma .NET fiind acela de eliberare automat a zonelor de memorie asociate unor date devenite inutile Garbage Collection). Ca un element de portabilitate, trebuie spus c .NET Framework este implementarea unui standard numit Common Language Infrastructure (http://www.ecmainternational.org/publications/standards/Ecma-335.htm), ceea ce permite rularea aplicaiilor .NET, n afar de Windows, i pe unele tipuri de Unix, Linux, Solaris, Mac OS X i alte sisteme de operare (http://www.mono-project.com/Main_Page ).
25
CAPITOLUL
Limbajul C#
3.1. Caracterizare
Limbajul C# fost dezvoltat de o echip restrns de ingineri de la Microsoft, echip din care s-a evideniat Anders Hejlsberg (autorul limbajului Turbo Pascal i membru al echipei care a proiectat Borland Delphi). C# este un limbaj simplu, cu circa 80 de cuvinte cheie, i 12 tipuri de date predefinite. El permite programarea structurat, modular i orientat obiectual, conform perceptelor moderne ale programrii profesioniste. Principiile de baz ale programrii pe obiecte (NCAPSULARE, MOTENIRE, POLIMORFISM) sunt elemente fundamentale ale programrii C#. n mare, limbajul motenete sintaxa i principiile de programare din C++. Sunt o serie de tipuri noi de date sau funciuni diferite ale datelor din C++, iar n spiritul realizrii unor secvene de cod sigure (safe), unele funciuni au fost adugate (de exemplu, interfee i delegri), diversificate (tipul struct), modificate (tipul string) sau chiar eliminate (motenirea multipl i pointerii ctre funcii). Unele funciuni (cum ar fi accesul direct la memorie folosind pointeri) au fost pstrate, dar secvenele de cod corespunztoare se consider nesigure.
26
salveaz fiierul primul.cs, n directorul WINDOWS\Microsoft.NET\ Framework\V2.0, atunci scriind la linia de comand: csc primul.cs se va obine fiierul primul.exe direct executabil pe o platform .NET. Dac se
Fereastra n care scriem programul se numete implicit Programs.cs i se poate modifica prin salvare explicit (Save As). Extensia cs provine de la C Sharp. n scrierea programului suntem asistai de IntelliSense, ajutorul contextual.
Compilarea programului se realizeaz cu ajutorul opiunii Build Solution (F6) din meniul Build. Posibilele erori de compilare sunt listate n fereastra Error List. Efectund dublu clic pe fiecare eroare n parte, cursorul din program se poziioneaz pe linia coninnd eroarea.
CAPITOLUL 3. Limbajul C#
27
Rularea programului se poate realiza n mai multe moduri: rapid fr asisten de depanare (Start Without Debugging Shift+F5) , rapid cu asisten de depanare (Start Debugging F5 sau cu butonul din bara de instrumente), rulare pas cu pas (Step Into F11 i Step Over F12) sau rulare rapid pn la linia marcat ca punct de ntrerupere (Toggle Breakpoint F9 pe linia respectiv i apoi Start Debugging F5). ncetarea urmririi pas cu pas (Stop Debugging Shift+F5) permite ieirea din modul depanare i revenirea la modul normal de lucru. Toate opiunile de rulare i depanare se gsesc n meniul Debug al mediului.
Fereastra de cod i ferestrele auxiliare ce ne ajut n etapa de editare pot fi vizualizate alegnd opiunea corespunztoare din meniul View. Ferestrele auxiliare utile n etapa de depanare se pot vizualiza alegnd opiunea corespunztoare din meniul Debug/Windows.
O aplicatie C# este format din una sau mai multe clase, grupate n spaii de nume (namespaces). Un spaiu de nume cuprinde mai multe clase cu nume diferite avnd funcionaliti nrudite. Dou clase pot avea acelai nume cu condiia ca ele s fie definite n spaii de nume diferite. n cadrul aceluiai spaiu de nume poate aprea definiia unui alt spaiu de nume, caz n care avem de-a face cu spaii de nume imbri-
28
cate. O clas poate fi identificat prin numele complet (nume precedat de numele spaiului sau spaiilor de nume din care face parte clasa respectiv, cu separatorul punct). n exemplul nostru, HelloWorld.Program este numele cu specificaie complet al clasei Program. O clas este format din date i metode (funcii). Apelarea unei metode n cadrul clasei n care a fost definit aceasta presupune specificarea numelui metodei. Apelul unei metode definite n interiorul unei clase poate fi invocat i din interiorul altei clase, caz n care este necesar specificarea clasei i apoi a metodei separate prin punct. Dac n plus, clasa aparine unui spaiu de nume neinclus n fiierul curent, atunci este necesar precizarea tuturor componentelor numelui: spaiu.clas.metod sau spaiu.spaiu.clas.metod etc. n fiierul nostru se afl dou spaii de nume: unul definit (HelloWorld) i unul extern inclus prin directiva using (System). Console.WriteLine reprezint apelul metodei WriteLine definit n clasa Console. Cum n spaiul de nume curent este definit doar clasa Program, deducem c definiia clasei Console trebuie s se gseasc n spaiul System. Pentru a facilita cooperarea mai multor programatori la realizarea unei aplicaii complexe, exist posibilitatea de a segmenta aplicaia n mai multe fiiere numite assemblies. ntr-un assembly se pot implementa mai multe spaii de nume, iar pri ale unui aceeai spaiu de nume se pot regsi n mai multe assembly-uri. Pentru o aplicaie consol, ca i pentru o aplicaie Windows de altfel, este obligatoriu ca una (i numai una) dintre clasele aplicaiei s conin un punct de intrare (entry point), i anume metoda (funcia) Main. S comentm programul de mai sus: linia 1: este o directiv care specific faptul c se vor folosi clase incluse n spaiul de nume System. n cazul nostru se va folosi clasa Console. linia 3: spaiul nostru de nume linia 5: orice program C# este alctuit din una sau mai multe clase linia 7: metoda Main, punctul de intrare n program linia 9: clasa Console, amintit mai sus, este folosit pentru operaiile de intrare/ieire. Aici se apeleaz metoda WriteLine din acest clas, pentru afiarea mesajului dorit pe ecran.
27 Este un termen folosit un pic echivoc i provenit din traduceriea cuvntului "token"
CAPITOLUL 3. Limbajul C#
29
comentariu pe mai multe rnduri prin folosirea /* i */ Orice text cuprins ntre simbolurile menionate mai sus se consider a fi comentariu. Simbolurile /* reprezint nceputul comentariului, iar */ sfritul respectivului comentariu.
/* Acesta este un comentariu care se intinde pe mai multe randuri */
Nume Prin nume dat unei variabile, clase, metode etc. nelegem o succesiune de caractere care ndeplinete urmtoarele reguli: numele trebuie s nceap cu o liter sau cu unul dintre caracterele _ i @; primul caracter poate fi urmat numai de litere, cifre sau un caracter de subliniere; numele care reprezint cuvinte cheie nu pot fi folosite n alt scop dect acela pentru care au fost definite cuvintele cheie pot fi folosite n alt scop numai dac sunt precedate de @ dou nume sunt distincte dac difer prin cel puin un caracter (fie el i liter mic ce difer de aceeai liter majuscul) Convenii pentru nume: n cazul numelor claselor, metodelor, a proprietilor, enumerrilor, interfeelor, spaiilor de nume, fiecare cuvnt care compune numele ncepe cu majuscul n cazul numelor variabilelor dac numele este compus din mai multe cuvinte, primul ncepe cu minuscul, celelalte cu majuscul Cuvinte cheie n C#
abstract byte class delegate event fixed if internal new override readonly short struct try unsafe volatile as case const do explicit float implicit is null params ref sizeof switch typeof ushort while base catch continue double extern for in lock object private return stackalloc this uint using bool char decimal else false foreach int long operator protected sbyte static throw ulong virtual break checked default enum finally goto interface namespace out public sealed string true unchecked void
Simbolurile lexicale reprezentnd constante, regulile de formare a expresiilor, separatorii de liste, delimitatorii de instruciuni, de blocuri de instruciuni, de iruri de caractere etc. sunt n mare aceiai ca i n cazul limbajului C++.
30
tip cu virgul mobil, simpl precizie, pe 32 bii -3.402823E+38; 3.402823E+38 (8 pentru exponent, 24 pentru mantis) tip cu virgul mobil, dubl precizie, pe 64 bii (11 pentru exponent, 53 -mantisa) tip boolean tip caracter din setul Unicode, pe 16 bii tip zecimal, pe 128 bii (96 pentru mantis), 28 de cifre semnificative -1.79769313486232E+308; 1.79769313486232E+308 -79228162514264337593543950335; 79228162514264337593543950335
CAPITOLUL 3. Limbajul C#
31
Tipul enumerare Tipul enumerare este un tip definit de utilizator. Acest tip permite utilizarea numelor care, sunt asociate unor valori numerice. Toate componentele enumerate au un acelai tip de baz ntreg. n cazul n care, la declarare, nu se specific tipul de baz al enumerrii, atunci acesta este considerat implicit int. Declararea unui tip enumerare este de forma:
enum [Nume_tip] [: Tip]o { [identificator1][=valoare]o, ... [identificatorn][=valoare]o }
Observaii: n mod implicit valoarea primului membru al enumerrii este 0, iar fiecare variabil care urmeaz are valoarea (implicit) mai mare cu o unitate dect precedenta. Valorile folosite pentru iniializri trebuie s fac parte din domeniul de valori declarat al tipului Nu se admit referine circulare:
enum ValoriCirculare { a = b, b }
32
Exemplu:
using System; namespace tipulEnum { class Program { enum lunaAnului { Ianuarie = 1, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie } static void Main(string[] args) { Console.WriteLine(Luna Mai este a {0}, (int)lunaAnului.Mai + -a luna din an.); Console.ReadLine(); } } }
n urma rulrii programului se afieaz mesajul: Luna Mai este a 5-a luna din an. Tablouri Declararea unui tablou unidimensional:
Tip[] nume;
Prin aceasta, nu se aloc spaiu pentru memorare. Pentru a putea reine date n structura de tip tablou, este necesar o operaie de instaniere:
nume = new Tip[NumarElemente];
Declararea, instanierea i chiar iniializarea tabloului se pot face n aceeai instruciune: Exemplu: int[] v = new int[] {1,2,3}; sau
int[] v = {1,2,3}; //new este implicit
n cazul tablourilor cu mai multe dimensiuni facem distincie ntre tablouri regulate i tablouri neregulate (tablouri de tablouri) Declarare n cazul tablourilor regulate bidimensionale:
Tip[,] nume;
Intaniere:
nume = new Tip[Linii,Coloane];
Acces:
nume[indice1,indice2]
CAPITOLUL 3. Limbajul C#
33
Exemple:
int[,] mat = new int[,] {{1,2,3},{4,5,6},{7,8,9}}; sau int[,] mat = {{1,2,3},{4,5,6},{7,8,9}};
Intaniere:
nume = new Tip[Linii],[]; nume[0]=new Tip[Coloane1] ... nume[Linii-1]=new Tip[ColoaneLinii-1]
Acces:
nume[indice1][indice2]
Exemple:
int[][] mat = new int[][] { new int[3] {1,2,3}, new int[2] {4,5}, new int[4] {7,8,9,1} }; sau int[][] mat={new int[3] {1,2,3},new int[2] {4,5},new int[4] {7,8,9,1}};
iruri de caractere Se definesc dou tipuri de iruri: regulate de tip verbatim Tipul regulat conine ntre ghilimele zero sau mai multe caractere, inclusiv secvene escape. Secvenele escape permit reprezentarea caracterelor care nu au reprezentare grafic precum i reprezentarea unor caractere speciale: backslash, caracterul apostrof, etc. Secven escape \' \" \\ \0 \a \b \f \n \r \t \u \v \x Efect apostrof ghilimele backslash null alarm backspace form feed - pagin nou new line - linie nou carriage return - nceput de rnd horizontal tab - tab orizontal caracter unicode vertical tab - tab vertical caracter hexazecimal
34
n cazul n care folosim multe secvene escape, putem utiliza irurile verbatim. Aceste iruri pot s conin orice fel de caractere, inclusiv caracterul EOLN. Ele se folosesc n special n cazul n care dorim s facem referiri la fiiere i la regitri. Un astfel de ir ncepe ntotdeauna cu simbolul@ naintea ghilimelelor de nceput. Exemplu:
using System; namespace SiruriDeCaractere { class Program { static void Main(string[] args) { string a = un sir de caractere; string b = linia unu \nlinia doi; string c = @linia unu linia doi; string d=c:\\exemple\\unu.cs; string e = @c:\exemple\unu.cs; Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); Console.WriteLine(d); Console.WriteLine(e); Console.ReadLine(); } } }
3.7. Conversii
3.7.1. Conversii numerice
n C# exist dou tipuri de conversii numerice: implicite explicite. Conversia implicit se efectueaz (automat) doar dac nu este afectat valoarea convertit.
CAPITOLUL 3. Limbajul C#
35
Exemplu:
using System; using System.Collections.Generic; using System.Text; namespace Conversii { class Program { static void Main(string[] args) { byte a = 13; // byte intreg fara semn // pe 8 biti byte b = 20; long c; //intreg cu semn pe 64 biti c = a + b; Console.WriteLine(c); Console.ReadLine(); } } }
Conversia explicit se realizeaz prin intermediul unei expresii cast, atunci cnd nu exist posibilitatea unei conversii implicite. Exemplu: n urma rulrii programului
using System; using System.Collections.Generic; using System.Text; namespace Conversii1 {
36
class Program { static void Main(string[] args) { int a = 5; int b = 2; float c; c = (float)a / b; //operatorul cast Console.WriteLine({0}/{1}={2}, a, b, c); Console.ReadLine(); } } }
se obine: 5/2 = 2,5 n cazul n care nu s-ar fi folosit operatorul cast rezultatul, evident eronat, ar fi fost: 5/2=2 Regulile de conversie explicit sunt descrise de tabelul urmtor:
din sbyte byte short ushort int uint long ulong char float double n byte, ushort, uint, ulong, char sbyte, char sbyte, byte, ushort, uint, ulong, char sbyte, byte, short, char sbyte, byte, short, ushort, uint, ulong, char sbyte,byte, short, ushort, int, char sbyte, byte, short, ushort, int, uint, ulong, char sbyte, byte, short, ushort, int, uint, long, char sbyte, byte, short sbyte, byte, short, ushort, int, uint, long, ulong, char, decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float, decimal
decimal sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double
CAPITOLUL 3. Limbajul C#
37
Pentru conversia invers, adic din ir de caractere n numr, sintaxa este: ir ir ir ir int long double float int.Parse(ir) sau long.Parse(ir sau double.Parse(ir) float.Parse(ir) sau Int32.Parse(ir) Int64.Parse(ir) sau Double.Parse(ir) Float.Parse(ir)
Observaie: n cazul n care irul de caractere nu reprezint un numr valid, conversia acesui ir la numr va eua. Exemplu:
using System; namespace Conversii { class Program { static void Main(string[] args) { string s; const int a = 13; const long b = 100000; const float c = 2.15F; double d = 3.1415; Console.WriteLine(CONVERSII\n); Console.WriteLine(TIP\tVAL. \tSTRING); Console.WriteLine(); s = + a; Console.WriteLine(int\t{0} \t{1},a,s); s = + b; Console.WriteLine(long\t{0} \t{1},b,s); s = + c; Console.WriteLine(float\t{0} \t{1},c,s); s = + d; Console.WriteLine(double\t{0} \t{1},d,s); Console.WriteLine(\nSTRING\tVAL \tTIP); Console.WriteLine(); int a1; a1 = int.Parse(13); Console.WriteLine({0}\t{1}\tint,13,a1); long b2; b2 = long.Parse(1000); Console.WriteLine({0}\t{1}\tlong,1000,b2); float c2; c2 = float.Parse(2,15); Console.WriteLine({0}\t{1}\tfloat,2,15,c2);
38
n urma rulrii se obine: CONVERSII TIP VAL. int 13 long 100000 float 2,15 double 3,1415 STRING VAL. 13 13 1000 1000 2,15 2,15 3.1415 3,1415
sau
int i = 13; object ob = i; //boxing implicit
CAPITOLUL 3. Limbajul C#
39
3.8. Constante
n C# exist dou modaliti de declarare a constantelor: folosind const sau folosind modificatorul readonly. Constantele declarate cu const trebuie s fie iniializate la declararea lor. Exemple:
const int x; const int x = 13; //gresit, constanta nu a fost initializata //corect
3.9. Variabile
O variabil n C# poate s conin fie o valoare a unui tip elementar, fie o referin la un obiect. Exemple: int Salut; int Azi_si _maine; char caracter;
40
3.11.1 Instruciunea if
Instruciunea if are sintaxa:
if (conditie) Instructiuni_A; else Instructiuni_B;
Exemplu:
using System; namespace Test { class Program { static void Main(string[] args) { int n; Console.WriteLine(Introduceti un nr intreg ); n = Convert.ToInt32(Console.ReadLine()); if (n >= 0) Console.WriteLine(Nr. introdus este > 0); else Console.WriteLine(Nr. introdus este < 0); Console.ReadLine(); } } }
Ct timp conditie este indeplinit se execut Instructiuni. Exemplu: S se afieze numerele ntregi pozitive <= 10
using System;
CAPITOLUL 3. Limbajul C#
41
namespace Test { class Program { static void Main(string[] args) { int n = 0; while (n <= 10) { Console.WriteLine(n este {0}, n); n++; } Console.ReadLine(); } } }
42
Instruciunea switch admite n C# variabil de tip ir de caractere care s fie comparat cu irurile de caractere din case-uri.
CAPITOLUL 3. Limbajul C#
43
Exemplu:
switch(strAnimal) { case Pisica : break; case Catel : break; default: break; }
44
Exemplu:
using System; namespace Salt { class Program { static void Main(string[] args) { int i = 0; while(true) { Console.Write({0} ,i); i++; if(i<10) continue; else break; } Console.ReadLine(); } } }
Se va afia: 0 1 2 3 4 5 6 7 8 9
CAPITOLUL 3. Limbajul C#
45
y=0; break; }
46
Alteori putem simula prin program o stare de eroare aruncnd o excepie (instruciunea throw) sau putem profita de mecanismul de tratare a erorilor pentru a implementa un sistem de validare a datelor prin generarea unei excepii proprii pe care, de asemenea, o aruncm n momentul nendeplinirii unor condiii puse asupra datelor. Clasa System.Exception i derivate ale acesteia servesc la tratarea adecvat i diversificat a excepiilor. Exemplu: Considerm clasele Copil, Fetita, Baiat definite fragmentat n capitolul 1. O posibilitate de validare la adugara unui copil este aceea care genereaz o excepie proprie la depirea dimensiunii vectorului static copii:
public static void adaug_copil(Copil c) { if (nr_copii < nr_max) copii[nr_copii++] = c; else throw new Exception(Prea muli copii); }
47
CAPITOLUL
48
Exemplu: GET /getPerson.aspx?Id=1&city=Cluj HTTP/1.1 Folosind POST, datele sunt plasate n corpul mesajului trimis serverului: Exemplu: POST /getCustomer.aspx HTTP/1.1 Id=123&color=blue Prin Get nu se pot trimite date de dimensiuni mari, iar datorit faptului c datele sunt scrise n URL-ul browser-ului, pot aprea probleme de securitate. De aceea, de preferat este s se foloseasc metoda POST pentru trimiterea de date. Trimiterea datelor napoi ctre server este numit deseori PostBack. Aciunea de PostBack poate fi folosit att cu metoda GET ct i cu metoda POST. Pentru a ti dac se trimit date (POST) sau pagina este doar cerut de browser (GET), cu alte cuvinte pentru a ti dac pagina curent se ncarc pentru prim dat sau nu, n ASP.NET se folosete o proprietate a clasei Page numit IsPostBack.
Seciunea de cod, conine codul C# asociat paginii sau obiectelor din pagin. Codul poate fi plasat direct n pagina sau ntr-un fiier cu extensia .cs, cu acelai nume ca al paginii (de ex. Default.aspx.cs). n cazul n care se gsete direct n pagin, codul este cuprins ntre tag-urile <script> </script>:
<script runat=server> protected void Button1_Click(object sender, EventArgs e) { Page.Title = First Web Application; } </script>
De obicei blocurile <script> conin cod care se execut pe partea de client, ns dac se folosete atributul runat = server, codul se va executa pe serverul web. n cazul exemplului de mai sus, la apsarea butonului se schimb titlul paginii Web n browser.
49
n cazul n care n fereastra pentru adugarea unei pagini noi n proiect, se bifeaz opiunea Place code in separate file, codul este plasat ntr-un fiier separat, iar n seciunea de directive este precizat numele acestui fiier. Exemplu: CodeFile=Default.aspx.cs. Seciunea de layout conine codul HTML din seciunea Body:
<body> <form id=form1 runat=server> <div> <asp:Button ID=Button1 runat=server OnClick=Button1_Click Text=Button /></div> </form> </body>
Atributul runat=server pentru un anumit control, specific faptul c pentru obiectul respectiv, ASP.NET Runtime Engine care ruleaz pe serverul web (IIS) va face transformarea ntr-un obiect HTML standard. Aceast conversie se realizeaz n funcie de tipul browserului, de varianta de javascript instalat pe browser i de codul C# asociat obiectului respectiv (numit code behind). De exemplu pagina aspx de mai sus este transformat n urmtorul fiier html:
<form name=form1 method=post action=Default.aspx id=form1> <div> <input type=hidden name=__VIEWSTATE id=__VIEWSTATE value=/wEPDwUKMTQ2OTkzNDMyMWRkIftHHP/CS/zQf/D4XczzogN1M1w= /> </div> <div> <br /> <input type=submit name=Button1 value=Button id=Button1 style=zindex: 102;left: 349px; position: absolute; top: 156px /> </div> <div> <input type=hidden name=__EVENTVALIDATION = __EVENTVALIDATION value = /wEWAgKlr8nLBAKM54rGBh7DPY7SctG1t7rMEnJSrO+1hHyP /> </div> </form>
Exemple complete de aplicaii web putei gsi pe DVD-ul Academic Resource Kit (ARK), instalnd Resurse\Visual Studio 2005\101 Samples CS101SamplesAll.msi sau descrcnd cele 101 exemple de utilizare a Visual Studio 2005 de la adresa http://msdn2. microsoft.com/en-us/vstudio/aa718334.aspx. Dup instalare, din aplicaia Microsoft Visual Web Developer 2005 alegei din meniul File opiunea Open Web Site i selectai, din directorul ..\CS101SamplesAll\CS101SamplesWebDevelopment\, aplicaia dorit. n fereastra Solution Explorer selectai Start.aspx i apoi butonul View in Browser".
50
Cnd vom rula pagina, vom constata c totui nu se ntmpl nimic. Pentru a se executa metoda CheckBox1_CheckedCanged, pagina trebuie retrimis serverului n momentul bifrii checkbox-ului. Serverul trebuie s execute codul i apoi s retrimit ctre browser pagina n care textbox-ul este vizibil sau nu. De aceea controlul checkbox trebuie s genereze aciunea de PostBack, lucru care se ntmpl dac este setat valoarea true proprietii AutoPostBack. Unele controale genereaz ntotdeauna Postback atunci cnd apare un anumit eveniment. De exemplu evenimentul click al controlului button. Exemplu de folosire a controalelor web putei gsi pe DVDul ARK, instalnd Resurse\Visual Studio 2005\101 Samples CS101SamplesAll.msi sau descrcnd cele 101 exemple de utilizare a Visual Studio 2005 de la adresa http://msdn2. microsoft.com/en-us/vstudio/aa718334.aspx, aplicaia MenuAndSiteMapPath. Pentru a nelege mai bine fenomenul de PostBack, ne propunem s realizm urmtoarea aplicaie. ntr-o pagin avem un textbox i un buton. Dorim ca n textbox s avem iniial (la ncrcarea paginii) valoarea 0, i de fiecare dat cnd se apas
51
butonul, valoarea din textbox s fie incrementat cu 1. Codul evenimentului Click al butonului i al evenimentului Load al paginii ar putea fi urmtorul:
protected void Page_Load(object sender, EventArgs e) { TextBox1.Text = 0; } protected void Button1_Click(object sender, EventArgs e) { TextBox1.Text = Convert.ToString(Convert.ToInt32(TextBox1.Text) + 1) ; }
Vom observa, ns, c dup prima incrementare valoarea n textbox rmne 1. Acest lucru se ntampl deoarece evenimentul Load se execut la fiecare ncrcare a paginii (indiferent c este vorba de request-ul iniial al browserului su de apelul de postback generat automat de evenimentul clic al butonului). Pentru a remedia aceast situaie, obiectul Page n ASP are proprietarea isPostBack, a.. putem s rescriem codul metodei Load:
protected void Page_Load(object sender, EventArgs e) { if (Page.IsPostBack == false) // nu este postback deci e prima { // incarcare a paginii TextBox1.Text = 0; } }
52
ele nu vor disprea la urmtorul PostBack adic la urmtoarea ncrcare a paginii curente. De exemplu, dac scriem un text ntr-o csu de text i apoi apsm un buton care genereaz un PostBack iar pagina se rencarc, ea va conine csua de text respectiv cu textul introdus de noi nainte de rencrcare. n momentul generrii codului Html de ctre server se genereaz un control html de tip <input type=hidden...> , a crui valoare este un ir de caractere ce codific starea controalelor din pagin:
<input type=hidden name=__VIEWSTATE id=__VIEWSTATE value=/wEPDwULLTE1OTg1NDYyNDZkZFCFstl/DwSGv81TuCB397Tk5+CJ />
Se pot aduga valori n ViewState i de ctre programator, folosind obiectul ViewState cu metoda Add (cheie, valoare_obiect): ViewState.Add(TestVariable,
Hello); protected void Page_Load(object sender, EventArgs e) { if (Page.IsPostBack == false) { ViewState.Add(ViewStateTest, Hello); } }
4.4.2.1. Profile
O posibilitate de pstrare a informaiilor specifice unui utilizator const n folosirea obiectului Profile, prin intermediul fiierului de configurare Web.Config. Acesta este un fiier XML n care se rein opiuni de configurare. Pentru a aduga o proprietate obiectului profile, n fiierul Web.Config se adaug:
53
<profile enabled=true> <properties> <add name =ProfileTest allowAnonymous =true/> </properties> </profile>
Atributul name reine numele proprietii. Dup aceste modificri, proprietatea definit n Web.config poate fi apelat pentru obiectul Profile:
Profile.ProfileTest = Hello world; Sau Label1.Text = Profile.ProfileTest;
4.4.2.2. Session
Obiectul Session este creat pe serverul web la prima accesare a sitului de ctre un utilizator i rmne n memorie n principiu att timp ct utilizatorul rmne conectat la site. Exist i excepii, dar ele nu fac obiectul acestui material. Pentru a aduga un obiect n sesiune, trebuie doar s scriem un cod de genul urmtor:
protected void Button1_Click(object sender, EventArgs e) { Session[sir] = test; }
Session este de fapt un dicionar (list de perechi cheie valoare), n care valorile sunt de tip object. Ceea ce nseamn c la citirea unor valori din sesiune va trebui s realizm o conversie de tip.
protected void Button2_Click(object sender, EventArgs e) { test = Session[sir].ToString(); TextBox1.Text = test; }
Odat introdus un obiect n Session, el poate fi accesat din toate paginile aplicaiei, att timp ct el exist acolo. Programatorul poate realiza scoaterea obiectului din sesiune atunci cnd dorete acest lucru:
Session.Remove(sir);
4.4.2.3. Application
Obiectul Application se comport n mod identic cu Session, doar c este specific ntregii aplicaii, adic tuturor utilizatorilor care acceseaza un site web la un moment
54
dat, i nu unei anumite sesiuni. Cu alte cuvinte odat introdus un obiect n Applicatio, va putea fi accesat din orice loc al sitului i de ctre toi utilizatorii acestuia.
atunci toi utilizatorii aplicaiei vor vedea valoarea modificat din acel moment nainte.
4.4.3. Concluzii
n cazul obiectului ViewState, datele sunt salvate n pagina web sub forma unui ir de caractere, iar n cazul obiectului Session respectiv Application n memoria serverului web. Dac datele salvate sunt de dimensiuni mari, n primul caz crete dimensiunea paginii web, care va fi transmis mai ncet, iar n al doilea caz rezult o folosire excesiv a memoriei serverului web, ceea ce duce la scderea vitezei de lucru. Aceast folosire excesiv a memoriei poate s apar i n cazul unei dimensiuni a datelor ceva mai redus, dar a unui numr mare de utilizatori care acceseaz simultan pagina (pentru fiecare se va creea un obiect sesiune).
55
controlul de validat nu corespund regulii alese. 3 EnableClientSideScript: este o proprietate boolean care specific locul n care se execut codul de validare (pe client sau pe server). 4 Alte proprieti, specifice tipului de validator.
4.5.2. Validatoare
1 RequiredFieldValidator. Verific dac n csua de text asociat prin proprietatea ControlToValidate s-a introdus text. Util pentru formularele n care anumite date sunt obligatorii. 2 RangeValidator. Verific dac informaia introdus n csua de text asociat face parte dintr-un anumit interval, specificat prin tipul datei introduse (prorietatea Type) i MinimumValue respectiv MaximumValue. 3 RegularExpressionValidator. Verific dac informaia din csua de text asociat este conform unei expresii regulate specificate. Este util pentru validarea unor informaii de genul adreselor de email, numerelor de telefon, etc n general informaii care trebuie s respecte un anumit format. Trebuie setat proprietatea ValidationExpression n care se pot alege cteva expresii uzuale gata definite. 4 CompareValidator. Compar datele introduse n csua de text asociat cu o valoare prestabilit (ValueToCompare), n funcie de operatorul ales (proprietatea Operator) i de tipul de date care se ateapt (proprietatea Type). Pe lng validatoarele prezentate mai sus, programatorul poate crea validatoare customizate, care s verifice datele introduse de utilizator conform unor reguli proprii. Exemplu de folosire a validrilor pentru un modul de login putei gsi pe dvd-ul ARK, instalnd Resurse\Visual Studio 2005\101 Samples CS101SamplesAll.msi sau descrcnd cele 101 exemple de utilizare a Visual Studio 2005 de la adresa http://msdn2.microsoft.com/en-us/vstudio/aa718334.aspx, aplicaia Membership.
56
57
2. Autorizarea este procesul prin care un utilizator autentificat primete acces pe resursele pe care are dreptul s le acceseze. Aceste obiective pot fi atinse foarte uor utiliznd funcionalitile i uneltele din ASP.NET respectiv Visual Studio, anume clasa Membership i unealta ASP.NET Configuration (din meniul Website al Visual Studio Web Developer Express). Configurarea autentificrii i autorizrii se poate realiza dup cum se vede n acest tutorial: http://msdn2.microsoft.com/en-us/library/879kf95c(VS.80).aspx. Un exemplu de securizare a aplicailor web putei gsi pe dvd-ul ARK, instalnd Resurse\Visual Studio 2005\101 Samples CS101SamplesAll.msi sau descrcnd cele 101 exemple de utilizare a Visual Studio 2005 de la adresa http://msdn2. microsoft.com/en-us/vstudio/aa718334.aspx, aplicatia Security.
4.8. Resurse
Dezvoltarea de aplicaii web cu Visual Web Developer Express: http://msdn.microsoft.com/vstudio/express/vwd/
59
CAPITOLUL
Programare vizual
5.1. Concepte de baz ale programrii vizuale
Programarea vizual trebuie privit ca un mod de proiectare a unui program prin operare direct asupra unui set de elemente grafice (de aici vine denumirea de programare vizual). Aceast operare are ca efect scrierea automat a unor secvene de program, secvene care, mpreun cu secvenele scrise textual28, vor forma programul. Spunem c o aplicaie este vizual dac dispune de o interfa grafic sugestiv i pune la dispoziia utilizatorului instrumente specifice de utilizare (drag, clic, hint etc.) Realizarea unei aplicaii vizuale nu const doar n desenare i aranjare de controale, ci presupune n principal stabilirea unor decizii arhitecturale29, decizii ce au la baz unul dintre modelele arhitecturale de baz: a) Modelul arhitectural orientat pe date. Acest model nu este orientat pe obiecte, timpul de dezvoltare al unei astfel de aplicaii este foarte mic, o parte a codului este generat automat de Visual Stdio.Net, codul nu este foarte uor de ntreinut i este recomandat pentru aplicaii relativ mici sau cu multe operaii de acces (in/out) la o baz de date. b)Modelul arhitectural Model-view-controller Este caracterizat de cele trei concepte de baz: Model (reprezentarea datelor se realizeaz ntr-o manier specific aplicaiei: conine obiectele de business, ncapsuleaz accesul la date), View (sunt utilizate elemente de interfa, este format din Form-uri), Controller( proceseaz i rspunde la evenimente iar SO, clasele Form i Control din .Net ruteaz evenimentul ctre un handler, eveniment tratat n codul din spatele Form-urilor). c) Modelul arhitectural Multi-nivel Nivelul de prezentare ( interfaa) Se ocup numai de afiarea informaiilor ctre utilizator i captarea celor introduse de acesta. Nu cuprinde detalii despre logica aplicaiei, i cu att mai mult despre baza de date
28 Se utilizeaz ades antonimia dintre vizual (operaii asupra unor componente grafice) i textual (scriere de linii de cod); proiectarea oricrei aplicaii "vizuale" mbin ambele tehnici. 29 Deciziile arhitecturale stabilesc n principal cum se leag interfaa de restul aplicaiei i ct de uor de ntreinut este codul rezultat.
60
sau fiierele pe care aceasta le utilizeaz. Cu alte cuvinte, n cadrul interfeei cu utilizatorul, nu se vor folosi obiecte de tipuri definite de programator, ci numai baza din .NET. Nivelul de logic a aplicaiei Se ocup de tot ceea ce este specific aplicaiei care se dezvolt. Aici se efectueaz calculele i procesrile i se lucreaz cu obiecte de tipuri definite de programator. Nivelul de acces la date Aici rezid codul care se ocup cu accesul la baza de date, la fiiere, la alte servicii.
Aceast ultim structur este foarte bun pentru a organiza aplicaiile, dar nu este uor de realizat. De exemplu, dac n interfaa cu utilizatorul prezentm date sub form ListView i la un moment dat clientul ne cere reprezentarea datelor ntr-un GridView, modificrile la nivel de cod nu se pot localiza doar n interfa deoarece cele dou controale au nevoie de modele de acces la date total diferite. Indiferent de modelul arhitectural ales, n realizarea aplicaiei mai trebuie respectate i principiile proiectrii interfeelor: Simplitatea Interfaa trebuie s fie ct mai uor de neles30 i de nvat de ctre utilizator i s permit acestuia s efectueze operaiile dorite n timp ct mai scurt. n acest sens, este vital culegerea de informaii despre utilizatorii finali ai aplicaiei i a modului n care acetia sunt obinuii s lucreze. Poziia controalelor Locaia controalelor dintr-o fereastr trebuie s reflecte importana relativ i frecvena de utilizare. Astfel, cnd un utilizator trebuie s introduc nite informaii unele obligatorii i altele opionale este indicat s organizm controalele astfel nct primele s fie cele care preiau informaii obligatorii. Consistena Ferestrele i controalele trebuie s fie afiate dup un design asemntor (tem30 ntruct mintea uman poate s perceap la un moment dat aproximativ 5-9 obiecte, o fereastr supra-ncrcat
61
plate) pe parcursul utilizrii aplicaiei. nainte de a implementa interfaa, trebuie decidem cum va arta aceasta, s definim template-ul. Estetica Intefaa trebuie s fie pe ct posibil plcut i atrgtoare.
Designer, Code, Solution Explorer i celelalte se afl grupate n meniul View. La crearea unei noi aplicaii vizuale, Visual Studio.NET genereaz un spaiu de nume ce conine clasa static Program, cu metoda static ce constituie punctul de intrare (de lansare) a aplicaiei:
static void Main() { } ... Application.Run(new Form1());
Clasa Application este responsabil cu administrarea unei aplicaii Windows, punnd la dispoziie proprieti pentru a obine informaii despre aplicaie, metode de lucru cu aplicaia i altele. Toate metodele i proprietile clasei Application sunt
62
statice. Metoda Run invocat mai sus creeaz un formular implicit, aplicaia rspunznd la mesajele utilizatorului pn cnd formularul va fi nchis. Compilarea modulelor aplicaiei i asamblarea lor ntr-un singur fiier executabil se realizeaz cu ajutorul opiunilor din meniul Build, uzual fiind Build Solution (F6). Odat implementat, aplicaia poate fi lansat, cu asisten de depanare sau nu (opiunile Start din meniul Debug). Alte faciliti de depanare pot fi folosite prin umrirea pas cu pas, urmrirea pn la puncte de ntrerupere etc. (celelalte opiuni ale meniului Debug). Ferestre auxiliare de urmrire sunt vizualizate automat n timpul procesului de depanare, sau pot fi activate din submeniul Windows al meniului Debug.
5.3. Ferestre
Spaiul Forms ne ofer clase specializate pentru: creare de ferestre sau formulare (System.Windows.Forms.Form), elemente specifice (controale) cum ar fi butoane (System.Windows.Forms.Button), casete de text (System.Windows.Forms.TextBox) etc. Proiectarea unei ferestre are la baz un cod complex, generat automat pe msur ce noi desemnm componentele i comportamentul acesteia. n fapt, acest cod realizeaz: derivarea unei clase proprii din System.Windows.Forms.Form, clas care este nzestrat cu o colecie de controale (iniial vid). Constructorul ferestrei realizeaz instanieri ale claselor Button, MenuStrip, Timer etc. (orice plasm noi n fereastr) i adaug referinele acestor obiecte la colecia de controale ale ferestrei. Dac modelul de fereastr reprezint ferestra principal a aplicaiei, atunci ea este instaniat automat n programul principal (metoda Main). Dac nu, trebuie s scriem noi codul ce realizeaz instanierea. Clasele derivate din Form motenesc o serie de proprieti care determin atributele vizuale ale ferestrei (stilul marginilor, culoare de fundal, etc.), metode care implementeaz anumite comportamente (Show, Hide, Focus etc.) i o serie de metode specifice (handlere) de tratare a evenimentelor (Load, Clic etc.). O fereastr poate fi activat cu form.Show() sau cu form.ShowDialog(), metoda a doua permind ca revenirea n fereastra din care a fost activat noul formular s se fac numai dup ce noul formular a fost inchis (spunem c formularul nou este deschis modal). Un propietar este o fereastr care contribuie la comportarea formularului deinut. Activarea propietarului unui formular deschis modal va determina activarea formularului deschis modal. Cnd un nou formular este activat folosind form.Show() nu va avea nici un deintor, acesta stabilindu-se direct:
public Form Owner { get; set; } F_nou form=new F_nou(); form.Owner = this; form.Show();
Formularul deschis modal va avea un proprietar setat pe null. Deintorul se poate stabili setnd proprietarul nainte s apelm Form.ShowDialog() sau apelnd
63
Vizibilitatea unui formular poate fi setat folosind metodele Hide sau Show. Pentru a ascunde un formular putem folosi:
this.Hide(); // setarea propietatii Visible indirect sau
Printre cele mai uzuale proprieti ale form-urilor, reamintim: StartPosition determin poziia ferestrei atunci cnd aceasta apare prima dat, poziie ce poate fi setat Manual sau poate fi centrat pe desktop (CenterScreen), stabilit de Windows, formularul avnd dimensiunile i locaia stabilite de programator (WindowsDefaultLocation) sau Windows-ul va stabili dimensiunea iniial i locaia pentru formular (WindowsDefaultBounds) sau, centrat pe formularul care l-a afiat (CenterParent) atunci cnd formularul va fi afiat modal. Location (X,Y) reprezint coordonatele colului din stnga sus al formularului relativ la colul stnga sus al containerului. (Aceast propietate e ignorat dac StartPosition = Manual). Micarea formularului ( i implicit schimbarea locaiei) poate fi tratat n evenimentele Move i LocationChanged . Locaia formularului poate fi stabilit relativ la desktop astfel:
void Form_Load(object sender, EventArgs e) { this.Location = new Point(1, 1); this.DesktopLocation = new Point(1, 1); } //formularul in desktop
Size (Width i Height) reprezint dimensiunea ferestrei. Cnd se schimb proprietile Width i Height ale unui formular, acesta se va redimensiona automat, aceast redimensionare fiind tratat n evenimentele Resize sau in SizeChanged. Chiar dac propietatea Size a formularului indic dimensiunea ferestrei, formularul nu este n totalitate responsabil pentru desenarea ntregului coninut al su. Partea care este desenat de formular mai este denumit i Client Area. Marginile, titlul i scrollbar-ul sunt desenate de Windows. MaxinumSize i MinimumSize sunt utilizate pentru a restriciona dimensiunile unui formular.
void Form_Load(object sender, EventArgs e) { this.MinimumSize = new Size(200, 100);... this.MaximumSize = new Size(int.MaxValue, 100);...}
IsMdiContainer precizeaz dac form-ul reprezint un container pentru alte form-uri. ControlBox precizeaz dac fereastra conine sau nu un icon, butonul de nchidere
64
al ferestrei i meniul System (Restore, Move, Size, Maximize, Minimize, Close). HelpButton-precizeaz dac butonul va aprea sau nu lng butonul de nchidere al formularului (doar dac MaximizeBox=false, MinimizeBox=false). Dac utilizatorul apas acest buton i apoi apas oriunde pe formular va aprea evenimentul HelpRequested (F1). Icon reprezint un obiect de tip *.ico folosit ca icon pentru formular. MaximizeBox i MinimizeBox precizeaz dac fereastra are sau nu butonul Maximize i respectiv Minimize Opacity indic procentul de opacitate31 ShowInTaskbar precizeaz dac fereastra apare in TaskBar atunci cnd formularul este minimizat. SizeGripStyle specific tipul pentru Size Grip (Auto, Show, Hide). Size grip (n colul din dreapta jos) indic faptul c aceast fereastr poate fi redimensionat. TopMost precizeaz dac fereastra este afisat n faa tuturor celorlalte ferestre. TransparencyKey identific o culoare care va deveni transparent pe form.
Definirea unei funcii de tratare a unui eveniment asociat controlului se realizeaz prin selectarea grupului Events din ferestra Properties a controlului respectiv i alegerea evenimentului dorit. Dac nu scriem nici un nume pentru funcia de tratare, ci efectum dublu clic n csua respectiv, se genereaz automat un nume pentru aceast funcie, innd cont de numele controlului i de numele evenimentului (de exemplu button1_Click). Dac n Designer efectum dublu clic pe un control, se va genera automat o funcie de tratare pentru evenimentul implicit asociat controlului (pentru un buton evenimentul implicit este Click, pentru TextBox este TextChanged, pentru un formular Load etc.). Printre evenimentele cele mai des utilizate, se numr : Load apare cnd formularul este pentru prima data ncrcat n memorie. FormClosed apare cnd formularul este nchis. FormClosing apare cnd formularul se va inchide ca rezultat al aciunii utilizatorului asupra butonului Close (Dac se seteaz CancelEventArgs.Cancel =True atunci se va opri nchiderea formularului). Activated apare pentru formularul activ. Deactivate apare atunci cnd utilizatorul va da clic pe alt formular al aplicatiei.
5.4. Controale
Unitatea de baz a unei interfee Windows o reprezint un control. Acesta poate fi gzduit de un container ce poate fi un formular sau un alt control. Un control este o instan a unei clase derivate din System.Windows.Forms i este reponsabil cu desenarea unei pri din container. Visual Studio .NET vine cu o serie de controale standard, disponibile n Toolbox. Aceste controale pot fi grupate astfel:
31 Dac va fi setat la 10% formularul i toate controalele sale vor fi aproape invizibile.
65
5.4.1. Controale form. Controlul form este un container. Scopul su este de a gzdui
alte controale. Folosind proprietile, metodele i evenimentele unui formular, putem personaliza programul nostru. n tabelul de mai jos vei gsi o list cu controalele cel mai des folosite i cu descrierea lor. Exemple de folosire a acestor controale vor urma dup explicarea proprietilor comune al controalelor i formularelor.
Funcia controlului Numele controlului Descriere Sunt folosite pentru a executa o secven de instruciuni n buton Button momentul activrii lor de ctre utilizator calendar caset de validare etichet caset cu list imagine pointer buton radio caset de text MonthCalendar CheckBox Label ListBox PictureBox Pointer RadioButton TextBox Afieaz implicit un mic calendar al lunii curente. Acesta poate fi derulat i nainte i napoi la celelalte luni calendaristice. Ofer utilizatorului opiunile : da/nu sau include/exclude Sunt folosite pentru afiarea etichetelor de text, i a pentru a eticheta controalele. Afieaz o list de articole din care utilizatorul poate alege. Este folosit pentru adugarea imaginilor sau a altor resurse de tip bitmap. Este utilizat pentru selectarea, mutarea sau redimensionarea unui control. Este folosit pentru ca utilizatorul s selecteze un singur element dint-un grup de selecii. Este utilizat pentru afiarea textului generat de o aplicaie sau pentru a primi datele introduse de la tastatur de ctre utilizator.
Proprietile ForeColor i BackColor. Prima proprietate enunat seteaz culoare textului din formular, iar cea de a doua seteaz culoarea formularului. Toate acestea le putei modifica dup preferine din fereastra Properties.
66
Proprietatea BorderStyle. Controleaz stilul bordurii unui formular. ncercai s vedei cum se modific setnd proprietatea la Fixed3D. (tot din fereastra Properties) Proprietatea FormatString v permite s setai un format comun de afiare pentru toate obiectele din cadrul unei ListBox. Aceasta se gsete disponibil n panoul Properties. Proprietatea Multiline schimb setarea implicit a controlului TextBox de la o singur linie, la mai multe linii. Pentru a realiza acest lucru tragei un TextBox ntr-un formular i modificai valoarea proprietii Multiline din panoul Properties de la False la true. Proprietatea AutoCheck cnd are valoarea true, un buton radio i va schimba starea automat la executarea unui clic. Proprietatea AutoSize folosit la controalele Label i Picture, decide dac un control este redimensionat automat, pentru a-i cuprinde ntreg coninutul. Proprietatea Enabled determin dac un control este sau nu activat ntr-un formular. Proprietatea Font determin fontul folosit ntr-un formular sau control. Proprietatea ImageAlign specific alinierea unei imagini aezate pe suprafaa controlului. Proprietatea TabIndex seteaz sau returneaz poziia controlului n cadrul aranjrii taburilor. Proprietatea Visible seteaz vizibilitatea controlului. Proprietatea Width and Height permite setarea nlimii i a limii controlului.
Numele metodei button1_Click este alctuit din numele controlului button1, urmat de numele evenimentului: Click. Acum ar trebui s revenii la Form1 i executai dublu clic pe butonul din acest formular pentru a ajunge la administratorul su de evenimente. Editai administratorul evenimentului conform exemplului de mai jos:
67
private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); form2.Show(); }
n acest moment rulai programul apsnd tasta F5 i vei observa c la executarea unui clic pe butonul din Form1 se deschide Form2 iar la executarea unui clic pe butonul din Form2 acesta se nchide.
Tot n cadrul evenimentului Click, oferim acum un exemplu de afiare ntr-un TextBox a unui mesaj, n momentul n care se execut clic pe un buton:
Deschidei o nou aplicaie Windows. Tragei un buton pe formular i o caset TextBox. Modificai textul ce apare pe buton, conform imaginii, i executai dublu clic pe el, pentru a ajunge la administratorul su de evenimente. Modificai sursa astfel nct s arate n modul urmtor.
private void button1_Click(object sender, EventArgs e) { string a = PLATFORMA .NET; textBox1.Text = a; }
Casete de mesaje: Pentru a crea o caset mesaj, apelm metoda MessageBox.Show();.ntr-o nou aplicaie Windows, tragei un buton n formular, modificai textul butonului cum dorii sau ca n imaginea alturat va apare un mesaj, executai dublu clic pe buton i
68
adugai n administratorul evenimentului Click linia de program: MessageBox.Show(tiam spus);. Apoi rulai programul.
Casete de dialog O caset de dialog este o form specializat de control de tip Form. Exemplu: Creai o nou aplicaie Windows, apoi tragei un buton n formular i setai proprietatea Text a butonului la : s avem un dialog, iar apoi executai dublu clic pe buton i folosii urmtorul cod pentru administratorul evenimentului Click.
private void button1_Click(object sender, EventArgs e) { Form2 w = new Form2(); w.ShowDialog(); }
Creai un alt formular la acest proiect(alegei Add Windows Forms din meniul Project), apoi n ordine: setai proprietatea ControlBox la valoarea false, setai proprietatea Text la caset de dialog, tragei n formular un control de tip Label i Text la introdu text, adugai un control TextBox n formular, adugai dou butoane, setai proprietatea Text a butonului din stnga la OK iar al celui din dreapta la Cancel, setai proprietatea DialogResult a butonului din stanga la OK iar al celui din dreapta la Cancel, executai clic pe formularul casetei de dialog i setai proprietatea AcceptButton la OKButton iar proprietatea CancelButton la CancelButton. Acum executai dublu clic pe butonul OK i folosii urmtorul cod pentru administratorul evenimentului Click:
private void button1_Click(object sender, EventArgs e) { textBoxText = textBox1.Text; this.Close(); }
69
Executai dublu clic pe butonul Cancel i folosii urmtorul cod pentru administratorul evenimentului Click:
private void button2_Click(object sender, EventArgs e) { Form2 v = new Form2(); v.ShowDialog(); if (v.DialogResult != DialogResult.OK) { this.textBox1.Clear(); } }
La nceputul clasei Form2 adugai declaraia: public string textBoxText; Iar la sfritul clasei Form2 adugai proprietatea:
public string TextBoxText {get{ return(textBoxText);}
Acum putei rula acest program. Crearea interfeei cu utilizatorul: Vom crea o aplicaiei numit Minicalculator, ce va conine un meniu principal. Meniul principal va avea un obiect File ce va conine cte un obiect Exit i Clear. Ieirile vor fi afiate ntr-un TextBox.
Creai o nou aplicaie Windows n care tragei 13 butoane pe care le vei poziiona i numi ca n figura alturat, apoi mai adugai un TextBox(pe acesta l putei seta s arate textul n stnga sau n dreapta). Adugai un menuStrip care s conin elementele precizate mai sus, i pe care le putei observa n figura alturat. Facei dublu clic pe fiecare buton numeric n parte pentru a ajunge la surs i modificai fiecare surs respectnd codul de mai jos:
private void button7_Click(object sender, EventArgs e) { string v = textBox1.Text; v += 7; textBox1.Text = v; }
70
Am dat exemplu pentru tasta 7, dar atenie la fiecare tast, variabila v, va primi ca valoare numrul afiat pe tasta respectiv. Acum procedai la fel, i modificai sursa pentru butoanele + i -.
private void button11_Click(object sender, EventArgs e) { op1 = textBox1.Text; operatie = +; textBox1.Text = ; }
Un alt exemplu: Se adaug pe formular dou butoane i o caset text. Apsarea primului buton va determina afiarea textului din TextBox ntr-un MessageBox iar apsarea celui de-al doilea buton va nchide nchide aplicaia.
71
Dup adugarea celor dou butoane i a casetei text, a fost schimbat textul afiat pe cele dou butoane i au fost scrise funciile de tratare a evenimentului Click pentru cele dou butoane:
private void { private void { button1_Click(object sender, System.EventArgs e) MessageBox.Show(textBox1.Text);} button2_Click(object sender, System.EventArgs e) Form1.ActiveForm.Dispose();}
Controale valoare (label, textbox, picturebox) care arat utilizatorului o informaie (text, imagine). Label este folosit pentru plasarea de text pe un formular. Textul afiat este coninut n propietatea Text i este aliniat conform propietii TextAlign. TextBox - permite utilizatorului s introduc un text. Prevede, prin intermediul ContextMenu-ului asociat, un set de funcionaliti de baz, ca de exemplu (Cut, Copy, Paste, Delete, SelectAll). PictureBox permite afiarea unei imagini. Exemplul PV2 afieaz un grup alctuit din 3 butoane, etichetate A,B respectiv C avnd iniial culoarea roie. Apsarea unui buton determin schimbarea culorii acestuia n galben. La o nou apsare butonul revine la culoare iniial. Acionarea butonului Starea butoanelor determin afiarea ntr-o caset text a etichetelor butoanelor galbene. Caseta text devine vizibil atunci cnd apsm prima oar acest buton. Culoarea butonului mare (verde/portocaliu) se schimb atunci cnd mouse-ul este poziionat pe buton.
Dup adugarea butoanelor i a casetei text pe formular, stabilim evenimentele care determin schimbarea culoriilor i completarea casetei text.
72
private void button1_Click(object sender, System.EventArgs e) {if (button1.BackColor== Color.IndianRed) button1.BackColor=Color.Yellow; else button1.BackColor= Color.IndianRed;} private void button4_MouseEnter(object sender, System.EventArgs e) {button4.BackColor=Color.YellowGreen;button4.Text=Butoane apasate;} private void button4_MouseLeave(object sender, System.EventArgs e) {textBox1.Visible=false;button4.Text=Starea butoanelor; button4.BackColor=Color.Orange;} private void button4_Click(object sender, System.EventArgs e) {textBox1.Visible=true;textBox1.Text=; if( button1.BackColor==Color.Yellow)textBox1.Text=textBox1.Text+A; if( button2.BackColor==Color.Yellow)textBox1.Text=textBox1.Text+B; if( button3.BackColor==Color.Yellow)textBox1.Text=textBox1.Text+C; }
Exerciiu Modificai aplicaia precedent astfel nct s avem un singur eveniment button_Click, diferenierea fiind fcut de parametrul sender. Exerciiu ( Password) Adugai pe un formular o caset text n care s introducei un ir de caractere i apoi verificai dac acesta coincide cu o parol dat. Textul introdus n caset nu este vizibil (fiecare caracter este nlocuit cu*). Rezultatul va fi afiat ntr-un MessageBox. Controale de selecie (CheckBox,RadioButton) au propietatea Checked care indic dac am selectat controlul. Dup schimbarea strii unui astfel de control, se declaneaz evenimentul Checked. Dac propietatea ThreeState este setat, atunci se schimb funcionalitatea acestor controale, n sensul c acestea vor permite setarea unei alte stri. n acest caz, trebuie verificat propietatea CheckState(Checked, Unchecked,Indeterminate) pentru a vedea starea controlului. Aplicaia PV3 este un exemplu de utilizare a acestor controale. Soluia unei probleme cu mai multe variante de rspuns este memorat cu ajutorul unor checkbox-uri cu proprietatea ThreeState. Apsarea butonului Verific determin afiarea unei etichete i a butoanelor radio DA i NU. Rspunsul este afiat ntr-un MessageBox.
Dup adugarea controalelor pe formular i setarea proprietilor Text i ThreeState n cazul checkbox-urilor stabilim evenimentele click pentru butonul Verifica i pentru butonul radio cu eticheta DA:
73
private void radioButton1_Click(object sender, System.EventArgs e) {if (checkBox1.CheckState==CheckState.Checked && checkBox2.CheckState==CheckState.Checked && checkBox3.CheckState==CheckState.Checked && checkBox5.CheckState==CheckState.Checked && checkBox4.CheckState==CheckState.Unchecked) MessageBox.Show(CORECT); else MessageBox.Show(Indicatie> Daca punem un sac in altul....); label2.Visible=false; radioButton1.Checked=false; radioButton2.Checked=false; radioButton1.Visible=false; radioButton2.Visible=false;} private void button1_Click(object sender, System.EventArgs e) {label2.Visible=true;radioButton1.Visible=true;radioButton2.Visible=true;}
Exerciiu (Test gril) Construii un test gril care conine 5 itemi cu cte 4 variante de rspuns (alegere simpl sau multipl), memorai rspunsurile date i afiai, dup efectuarea testului, ntr-o caset text, n dreptul fiecrui item, rspunsul corect. LinkLabel afieaz un text cu posibilitatea ca anumite pri ale textului (LinkArea) s fie desenate ca i hyperlink-uri. Pentru a face link-ul funcional trebuie tratat evenimentul LinkClicked. n exemplul PV4, prima etichet permite afiarea coninutului discului C:, a doua legtur este un link ctre pagina www.microsoft.com/romania i a treia acceseaz Notepad.
private void etichetaC_LinkClicked (object sender, LinkLabelLinkClickedEventArgs e ) { etichetaC.LinkVisited = true; System.Diagnostics.Process.Start( @C:\ );} private void etichetaI_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e ) {etichetaI.LinkVisited = true; System.Diagnostics.Process.Start(IExplore, http://www.microsoft.com/romania/ );} private void etichetaN_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e ) {etichetaN.LinkVisited = true; System.Diagnostics.Process.Start( notepad );}
74
Exerciiu (Memorator) Construii o aplicaie care s conin patru legturi ctre cele patru fiiere/ pagini care conin rezumatul capitolelor studiate. Controale pentru listare (ListBox, CheckedListBox, ComboBox, ImageList) ce pot fi legate de un DataSet, de un ArrayList sau de orice tablou (orice surs de date ce implementeaz interfaa IEnumerable). n exemplul PV5 elementele selectate din CheckedListBox se adaug n ListBox. Dup adugarea pe formular a CheckedListBox-ului, stabilim colecia de itemi (Properties-Items-Collection), butonul Selecie i ListBox-ul.
Evenimentul Click asociat butonului Setectie golete mai nti listBox-ul (listBox1.Items.Clear();) i dup aceea adaug n ordine fiecare element selectat din CheckedListBox. Suplimentar se afieaz o etichet cu itemii selectai.
void button1_Click(object source, System.EventArgs e) { String s = Am selectat si am adaugat itemii: ; listBox1.Items.Clear(); foreach ( object c in checkedListBox1.CheckedItems) {listBox1.Items.Add(c); s = s + c.ToString();s = s + ;} label1.Text = s;}
Exerciiu (Filtru) Construii o aplicaie care afieaz fiierele dintr-un folder ales care au un anumit tip (tipul fiierelor este ales de utilizator pe baza unui CheckedListBox)
Aplicaia PV6 este un exemplu de utilizare a controlului ImageList. Apsarea butonului Desene va aduga fiierele *.gif din folderul C:\Imagini n list i va afia coninutul acesteia. Butonul Animate va determina afiarea fiierelor *.gif cu ajutorul PictureBox.
75
ImageList desene_animate = new System.Windows.Forms.ImageList(); private void contruieste_lista_Click(object sender, System.EventArgs e) { // Configureaza lista desene_animate.ColorDepth =System.Windows.Forms.ColorDepth.Depth8Bit; desene_animate.ImageSize = new System.Drawing.Size(60, 60); desene_animate.Images.Clear(); string[] gif_uri = Directory.GetFiles(C:\\Imagini, *.gif); // se construieste un obiect Imagine pentru fiecare fisier si se adauga la ImageList. foreach (string fisier_gif in gif_uri) {Bitmap desen= new Bitmap (fisier_gif); desene_animate.Images.Add(desen);pictureBox2.Image=desen;} Graphics g = this.CreateGraphics(); // Deseneaza fiecare imagine utilizand metoda ImageList.Draw() for (int i = 0; i < desene_animate.Images.Count; i++) desene_animate.Draw(g, 60 + i * 60, 60, i); g.Dispose(); }
Exerciiu (Thumbnails) Afiai ntr-o ferestr coninutul folder-ului curent n mod View-Thumbnails. MonthCalendar afieaz un calendar prin care se poate selecta o dat (zi, luna, an) n mod grafic. Proprietile mai importante sunt: MinDate, MaxDate, TodayDate ce reprezint data minim/maxim selectabil i data curent (care apare afiat difereniat sau nu n funcie de valorile proprietilor ShowToday,ShowTodayCircle. Exist 2 evenimente pe care controlul le expune: DateSelected i DateChanged. n rutinele de tratare a acestor evenimente, programatorul are acces la un obiect de tipul DateRangeEventArgs care conine proprietile Start i End (reprezentnd intervalul de timp selectat).
Formularul din aplicaia PV7 conine un calendar pentru care putem selecta un interval de maximum 30 de zile, sunt afiate sptmnile i ziua curent. Intervalul selectat se afieaz prin intermediul unei etichete. Dac se selecteaz o dat atunci aceasta va fi adugat ca item ntr-un ComboBox (orice dat poate aprea cel mult o dat n list). Dup adugarea celor 3 controale pe formular, stabilim proprietile pentru monthCalendar1 (ShowWeekNumber-True, MaxSelectionCount-30, etc.) i precizm ce se execut atunci cnd selectm un interval de timp:
76
private void monthCalendar1_DateSelected(object sender, System.Windows.Forms.DateRangeEventArgs e) { this.label1.Text = Interval selectat: Start = +e.Start.ToShortDateString() + : End = + e.End.ToShortDateString(); if (e.Start.ToShortDateString()==e.End.ToShortDateString()) {String x=e.Start.ToShortDateString(); if(!(comboBox1.Items.Contains(x))) comboBox1.Items.Add(e.End.ToShortDateString());} }
DateTimePicker este un control care (ca i MonthCalendar) se poate utiliza pentru a selecta o dat. La clic se afieaz un control de tip MonthCalendar, prin care se poate selecta data dorit. Fiind foarte asemntor cu MonthCalendar, proprietile prin care se poate modifica comportamentul controlului sunt identice cu cele ale controlului MonthControl. Exerciiu (Formular) Contruii un formular de introducere a datelor necesare realizrii unei adrese de e-mail. Data naterii va fi selectat direct utiliznd MonthCalendar. ListView este folosit pentru a afia o colecie de elemente n unul din cele 4 moduri (Text, Text+Imagini mici, Imagini mari, Detalii). Acesta este similar grafic cu ferestrele n care se afieaz fiierele dintr-un anumit director din Windows Explorer. Fiind un control complex, conine foarte multe proprieti, printre care: View (selecteaz modul de afiare (LargeIcon, SmallIcon, Details, List)), LargeImageList, SmallImageList (icon-urile de afiat n modurile LargeIcon, SmallIcon), Columns(utilizat doar n modul Details, pentru a defini coloanele de afiat), Items(elementele de afiat). Aplicaia PV8 este un exemplu de utilizare ListView. Se pornete de la rdcin i se afieaz coninutul folder-ului selectat cu dublu clic. La expandare se afieaz numele complet, data ultimei accesri i, n cazul fiierelor, dimensiunea. Controlul lista_fisiere este de tip ListView. Funcia ConstruiesteHeader permite stabilirea celor trei coloane de afiat.
private void ConstruiesteHeader() {ColumnHeader colHead;colHead = new ColumnHeader(); colHead.Text = Nume fisier; this.lista_fisiere.Columns.Add(colHead); colHead = new ColumnHeader();colHead.Text = Dimensiune; his.lista_fisiere.Columns.Add(colHead); colHead = new ColumnHeader();colHead.Text = Ultima accesare; this.lista_fisiere.Columns.Add(colHead); }
77
Pentru item-ul selectat se afieaz mai nti folderele i dup aceea fiierele. Pentru aceasta trebuie s determinm coninutul acestuia:
ListViewItem lvi; ListViewItem.ListViewSubItem lvsi; this.calea_curenta.Text = radacina + (Doublu Click pe folder); System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(radacina); DirectoryInfo[] dirs = dir.GetDirectories(); FileInfo[] files = dir.GetFiles();
i s adugm fiecare nou item ( coloana a doua este vid n cazul folderelor):
foreach (System.IO.DirectoryInfo fi in dirs) { lvi = new ListViewItem();lvi.Text = fi.Name; lvi.ImageIndex = 1; lvi.Tag = fi.FullName; lvsi = new ListViewItem.ListViewSubItem(); lvsi.Text = ;lvi.SubItems.Add(lvsi); lvsi = new ListViewItem.ListViewSubItem(); lvsi.Text = fi.LastAccessTime.ToString(); lvi.SubItems.Add(lvsi); this.lista_fisiere.Items.Add(lvi); }
Exerciiu (Ordonare) Modificai aplicaia anterioar astfel nct apsarea pe numele unei coloane s determine afiarea informaiilor ordonate dup criteriul specificat (nume, dimensiune, data). Controale de control al executrii (Timer) sau de dialog (OpenFileDialog, SaveFileDialog, ColorDialog, FontDialog, ContextMenu). Utilizatorul nu are drept de control asupra tuturor controalelor. Dintre acestea vom studia n cele ce urmeaz controlul Timer asupra cruia are drept de interaciune doar cel care dezvolt aplicaia.
78
Observm c aducnd din Toolbox controlul Timer, acesta nu se afieaz pe formular, el aprnd ntr-o zon gri a suprafeei de lucru (Designer).
Explicaie Activarea controlului de timp Numrul de milisecunde dintre apelurile la metoda de tratare a evenimentului. Se stabilete, n cazul de fa numrtoarea din secund n secund
Interval
1.000
Dm clic pe icoana de la timer care are numele aplCeas, iar la Events, la Tick selectm lblCeas_Click
79
n urmtorul exemplu vom folosi ProgressBar pentru a vizualiza ceasul sistemului. Vom construi un formular ca n imaginea alturat. Pentru aceasta aducem din Toolbox trei controale ProgressBar, un control Timer, apte controale Label i un control Button. Tabelul de mai jos descrie proprietile i valorile formularului i a respectivelor controale:
Formularul:
Control Form1 Proprietate (Name) Size BorderStyle Text Valoare Form1 606;265 Fixed3D Afiare timp cu ProgressBar si Label
ProgressBar-urile:
Control ProgressBar1 Proprietate (Name) Location Maximum Size Step Style Valoare prgOre 82;64 23 431;23 1 Blocks
80
Control ProgressBar2
ProgressBar3
Proprietate (Name) Location Maximum Size Step Style (Name) Location Maximum Size Step Style
Label2
Label3
81
Label5
Label6
Label4
Pentru Timer:
Control Timer1 Proprietate (Name) Enabled Interval Valoare Timer1 True 1.000 Evenimente Timer1_Tick
pentru timer1:
private void timer1_Tick(object sender, EventArgs e) { DateTime TimpCurent = DateTime.Now; int H = TimpCurent.Hour; int M = TimpCurent.Minute; int S = TimpCurent.Second; prgOre.Value = H; prgMinute.Value = M; prgSecunde.Value = S; lblAfisOre.Text = H.ToString();
82
pentru a redimensiona proporional ProgressBar-ul Ore cu cel care reprezint Minutele, respectiv Secundele, introducem urmtorul cod:
private void Form1_Load(object sender, EventArgs e) { this.prgOre.Width = 2 * this.prgMinute.Width / 5; }
Grupuri de controale Toolbar (ToolStrip) afieaz o bar de butoane n partea de sus a unui formular. Se pot introduce vizual butoane (printr-un designer, direct din Visual Studio.NET IDE), la care se pot seta att textul afiat sau imaginea. Evenimentul cel mai util al acestui control este ButtonClick (care are ca parametru un obiect de tip ToolBarButtonClickEventArgs, prin care programatorul are acces la butonul care a fost apasat). n aplicaia urmtoare PV9 cele 3 butoane ale toolbar-ului permit modificarea proprietilor textului introdus n caset. Toolbar-ul se poate muta fr a depi spaiul ferestrei. Schimbarea fontului se realizeaz cu ajutorul unui control FontDialog(),iar schimbarea culorii utilizeaz ColorDialog()
FontDialog fd = new FontDialog(); fd.ShowColor = true;fd.Color = Color.IndianRed; fd.ShowApply = true; fd.Apply += new EventHandler(ApplyFont); if(fd.ShowDialog() != System.Windows.Forms.DialogResult.Cancel)
83
{ this.richTextBox1.Font= fd.Font; this.richTextBox1.ForeColor=fd.Color; } ColorDialog cd = new ColorDialog(); cd.AllowFullOpen = true;cd.Color = Color.DarkBlue; if(cd.ShowDialog() == System.Windows.Forms.DialogResult.OK) this.richTextBox1.ForeColor = cd.Color;
Mutarea toolbar-ul este dirijat de evenimentele produse atunci cnd apsm butonul de mouse i/sau ne deplasm pe suprafaa ferestrei.
private void toolBar1_MouseDown(object sender, MouseEventArgs e) { // am apasat butonul de mouse pe toolbar am_apasat = true; forma_deplasata = new Point(e.X, e.Y); toolBar1.Capture = true;} private void toolBar1_MouseUp(object sender, MouseEventArgs e) { am_apasat = false;toolBar1.Capture = false;} private void toolBar1_MouseMove(object sender, MouseEventArgs e) { if (am_apasat) { if(toolBar1.Dock == DockStyle.Top || toolBar1.Dock == DockStyle.Left) { // daca depaseste atunci duc in stanga sus if (forma_deplasata.X < (e.X-20) || forma_deplasata.Y < (e.Y-20)) { am_apasat = false;// Disconect toolbar toolBar1.Dock = DockStyle.None; toolBar1.Location = new Point(10, 10); toolBar1.Size = new Size(200, 45); toolBar1.BorderStyle = BorderStyle.FixedSingle; } } else if (toolBar1.Dock == DockStyle.None) {toolBar1.Left = e.X + toolBar1.Left - forma_deplasata.X; toolBar1.Top = e.Y + toolBar1.Top - forma_deplasata.Y; if (toolBar1.Top < 5 || toolBar1.Top>this.Size.Height-20) { am_apasat = false;toolBar1.Dock = DockStyle.Top; toolBar1.BorderStyle = BorderStyle.Fixed3D;} else if (toolBar1.Left < 5 || toolBar1.Left > this.Size.Width - 20) { am_apasat = false;toolBar1.Dock = DockStyle.Left;
84
Exerciiu (Editor) Realizai un editor de texte care conin un control toolBar cu butoanele uzuale. Controale container (GroupBox, Panel, TabControl) sunt controale ce pot conine alte controale. Aplicaia PV10 simuleaz lansarea unei comenzi ctre un magazin de jucrii. Se utilizeaz 4 pagini de Tab pentru a simula selectarea unor opiuni ce se pot grupa pe categorii.
Exerciiu (Magazin) Dezvoltai aplicaia precedent astfel nct pe o pagin s se afieze modelele disponibile (imagine+detalii) i s se permit selectarea mai multor obiecte. Ultima pagin reprezint coul de cumprturi. Grupuri de controale tip Meniu (MenuStrip, ContextMenuStrip etc.) Un formular poate afia un singur meniu principal la un moment dat, meniul asociat iniial fiind specificat prin propietatea Form.MainMenuStrip. Meniul care este afiat de ctre un formular poate fi schimbat dinamic la rulare:
switch(cond) { case cond1:this.MainMenuStrip = this.mainMenu1;break; case cond2:this.MainMenuStrip = this.mainMenu2; }
unde mainMenu1 i mainMenu2 sunt obiecte de tip MenuStrip. Editarea unui astfel de obiect se poate face utiliznd Menu Designer. Clasa MenuStrip are o colecie de MenuItem care conine 0 sau mai multe obiecte de tip MenuItem. Fiecare dintre aceste obiecte de tip MenuItem are 0 sau mai multe obiecte de tip MenuItem, care vor constitui noul nivel de itemi (Ex: File New,Save, Open, Close, Exit). Propietile Checked i RadioCheck indic itemul selectat, Enabled and Visible determin dac un item poate fi sau nu selectat sau vizibil, Shortcut permite asignarea unei combinaii de taste pentru selectarea unui item al meniului i Text
85
memoreaz textul care va fi afiat pentru respectivul item al meniului. Evenimentul Click are loc cnd un utilizator apas un item al meniului. Exemplul PV11 permite, prin intermediul unui meniu, scrierea unui fiier Notpad, afiarea continutului acestuia ntr-o caset text, schimbarea fontului i culorii de afiare, tergerea coninutului casetei, afiarea unor informaii teoretice precum i Help dinamic. Au fost definite chei de acces rapid pentru accesarea componentelor meniului.
File
System.Diagnostics.Process.Start( notepad );
File
OpenFileDialog of = new OpenFileDialog(); of.Filter = Text Files (*.txt)|*.txt; of.Title = Fisiere Text; if (of.ShowDialog() == DialogResult.Cancel)return; richTextBox1.Text=;richTextBox1.Visible=true; FileStream strm; try{strm = new FileStream (of.FileName, FileMode.Open, FileAccess.Read); StreamReader rdr = new StreamReader (strm); while (rdr.Peek() >= 0){string str = rdr.ReadLine (); richTextBox1.Text=richTextBox1.Text+ +str;} } catch (Exception){MessageBox.Show (Error opening file, File Error, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);}
File Close terge coninutul casetei text, File Exit nchide aplicaia Window Font i Window Color permit stabilirea fontului/culorii textului afiat. Help DinamicHelp acceseaz
System.Diagnostics.Process.Start(IExplore, http://msdn2.microsoft.com/en-us/default.aspx);
Help
86
Exerciiu (Fisiere) Contruii un menu care s permit efectuarea operaiilor uzuale cu fiiere.
5.5. System.Drawing
Spaiul System.Drawing conine tipuri care permit realizarea unor desene 2D i au rol
deosebit n proiectarea interfeelor grafice. Un obiect de tip Point este reprezentat prin coordonatele unui punct ntr-un spaiu bidimensional (exemplu: Point myPoint = new Point(1,2);) Point este utilizat frecvent nu numai pentru desene, ci i pentru a identifica n program un punct dintr-un anumit spaiu. De exemplu, pentru a modifica poziia unui buton n fereastr putem asigna un obiect de tip Point proprietii Location indicnd astfel poziia colului din stnga-sus al butonului (button.Location = new Point(100, 30)). Putem construi un obiect de tip Point pentru a redimensiona un alt obiect.
Size mySize = new Size(15, 100); Point myPoint = new Point(mySize); System.Console.WriteLine(X: + myPoint.X + , Y: + myPoint.Y);
Structura Color conine date, tipuri i metode utile n lucrul cu culori. Fiind un tip valoare (struct) i nu o clas, aceasta conine date i metode, ns nu permite instaniere, constructori, destructor, motenire.
Color myColor = Color.Brown; button1.BackColor = myColor;
Substructura FromArgb a structurii Color returneaz o culoare pe baza celor trei componente ale oricrei culori (red, green, blue). Clasa Graphics este o clas sigilat reprezentnd o arie rectangular care permite reprezentri grafice. De exemplu, o linie frnt se poate realiza astfel:
Point[] points = new Point[4]; points[0] = new Point(0, 0);points[1] = new Point(0, 120); points[2] = new Point(20, 120);points[3] = new Point(20, 0); Graphics g = this.CreateGraphics(); Pen pen = new Pen(Color.Yellow, 2); g.DrawLines(pen, points);
Aplicaia PV12 este un exerciiu care deseneaz cercuri de raze i culori aleatorii i emite sunete cu frecven aleatoare.
Random x = new Random(); Console.Beep(300 + x.Next(1000), 150); Graphics g = e.Graphics; i = 1 + x.Next(30); p=new Pen(System.Drawing.Color.FromArgb(x.Next(256),x.Next(256),x.Next(256)))
87
88
dintre handlerele asociate evenimentelor la nivel de control (Leave, Textchanged, MouseUp etc.)
private void textBox1_KeyUp(object sender, System.Windows.Forms.KeeyEventArgs e) {if(e.Alt==true) MessageBox.Show (Tasta Alt e apasata); // sau if(Char.IsDigit(e.KeyChar)==true) MessageBox.Show(Ati apasat o cifra); }
Validarea la nivel de utilizator n unele situaii (de exemplu atunci cnd valorile introduse trebuie s se afle ntr-o anumit relaie ntre ele), validarea se face la sfritul introducerii tuturor datelor la nivelul unui buton final sau la nchiderea ferestrei de date.
private void btnValidate_Click(object sender, System.EventArgs e) { foreach(System.Windows.Forms.Control a in this.Controls) { if( a is System.Windows.Forms.TextBox & a.Text==) { a.Focus();return;} } }
ErrorProvider O manier simpl de a semnala erori de validare este aceea de a seta un mesaj de eroare pentru fiecare control.
myErrorProvider.SetError(txtName, Numele nu are spatii in stanga);
Aplicatii recapitulative. Urmrii aplicaiile i precizai pentru fiecare dintre ele controalele utilizate, evenimentele tratate: Forma poloneza (PV14), Triunghi (PV15), Ordonare vector(PV16), Subsir cresctor de lungime maxim(PV17), Jocul de Nim (PV18) Exerciiu (Test grila) Realizai un generator de teste gril (ntrebrile sunt preluate dintr-un fiier text, pentru fiecare item se precizeaz tipul (alegere simpl/multipl), punctajul, enunul i distractorii, imaginea asociat (dac exist). Dup efectuarea testului se afieaz rezultatul obinut i statistica rspunsurilor.
89
CAPITOLUL
ADO.NET
ADO.NET (ActiveX Data Objects) reprezint o parte component a nucleului .NET Framework ce permite conectarea la surse de date diverse, extragerea, manipularea i actualizarea datelor. De obicei, sursa de date este o baz de date, dar ar putea de asemenea s fie un fiier text, o foaie Excel, un fiier Access sau un fiier XML. n aplicaiile tradiionale cu baze de date, clienii stabilesc o conexiune cu baza de date i menin aceast conexiune deschis pn la ncheierea executrii aplicaiei. Conexiunile deschise necesit alocarea de resurse sistem. Atunci cnd meninem mai multe conexiuni deschise server-ul de baze de date va rspunde mai lent la comenzile clienilor ntruct cele mai multe baze de date permit un numr foarte mic de conexiuni concurente. ADO.NET permite i lucrul n stil conectat dar i lucrul n stil deconectat, aplicaiile conectndu-se la server-ul de baze de date numai pentru extragerea i actualizarea datelor. Acest lucru permite reducerea numrului de conexiuni deschise simultan la sursele de date. ADO.NET ofer instrumentele de utilizare i reprezentare XML pentru transferul datelor ntre aplicaii i surse de date, furniznd o reprezentare comun a datelor, ceea ce permite accesarea datelor din diferite surse de diferite tipuri i prelucrarea lor ca entiti, fr s fie necesar s convertim explicit datele n format XML sau invers. Aceste caracteristici sunt determinate n stabilirea beneficiilor furnizate de ADO.NET: Interoperabilitate. ADO.NET poate interaciona uor cu orice component care suport XML. Durabilitate. ADO.NET permite dezvoltarea arhitecturii unei aplicaii datorit modului de transfer a datelor ntre nivelele arhitecturale. Programabilitate.ADO.NET simplific programarea pentru diferite task-uri cum ar fi comenzile SQL, ceea ce duce la o cretere a productivitii i la o scdere a numrului de erori. Performan. Nu mai este necesar conversia explicit a datelor la transferul ntre aplicaii, fapt care duce la crete performanelor acestora. Accesibilitate Utilizarea arhitecturii deconectate permite accesul simultan la acelai set de date. Reducerea numrului de conexiuni deschise simultan determin utilizarea optim a resurselor.
90
6.3.Connection.
nainte de orice operaie cu o surs de date extern, trebuie realizat o conexiune (legtur) cu acea surs. Clasele din categoria Connection (SQLConnection, OleDbConnection etc.) conin date referitoare la sursa de date (locaia, numele i parola contului de acces, etc.), metode pentru deschiderea/nchiderea conexiunii, pornirea unei tranzacii etc. Aceste clase se gsesc n subspaii (SqlClient, OleDb etc.) ale spaiului System.Data. n plus, ele implementeaz interfaa IdbConnection. Pentru deschiderea unei conexiuni prin program se poate instania un obiect de tip conexiune, precizndu-i ca parametru un ir de caractere coninnd date despre conexiune.
CAPITOLUL 6. ADO.NET
91
6.3.2. Proprieti
a) ConnectionString (String, cu accesori de tip get i set ) definete un ir care permite identificarea tipului i sursei de date la care se face conectarea i eventual contul i parola de acces. Conine lista de parametri necesarii conectrii sub forma parametru=valoare, separai prin ;.
Parametru Provider Data Source Initial Catalog Descriere Specific furnizorul de date pentru conectarea la sursa de date. Acest furnizor trebuie precizat doar dac se folosete OLE DB .NET Data Provider, i nu se specific pentru conectare la SQL Server. Identific serverul, care poate fi local, un domeniu sau o adresa IP. specific numele bazei de date. Baza de date trebuie s se gseasc pe serverul dat n Data Source
Integrated Security32 Logarea se face cu user-ul configurat pentru Windows. User ID Password Numele unui user care are acces de logare pe server Parola corespunztoare ID-ului specificat.
b) ConnectionTimeout (int, cu accesor de tip get): specific numrul de secunde pentru care un obiect de conexiune poate s atepte pentru realizarea conectrii la
32 User Id i Password pot nlocui parametrul Integrated Security
92
server nainte de a se genera o excepie. (implicit 15). Se poate specifica o valoare diferit de 15 n ConnectionString folosind parametrul Connect Timeout, Valoarea Timeout=0 specific ateptare nelimitat.
Ex.) using System.Data.SqlClient; SqlConnection cn = new SqlConnection(Data Source=serverBD; Database=scoala;User ID=elev;Password=madonna; Connect Timeout=30);
c) Database (string, read-only): returneaz numele bazei de date la care sa fcut conectarea. Este necesar pentru a arta unui utilizator care este baza de date pe care se face operarea d)Provider (de tip string, read-only): returneaz furnizorul de date e) ServerVersion (string, read-only): returneaz versiunea de server la care s-a fcut conectarea. f) State (enumerare de componente ConnectionState, read-only): returneaz starea curent a conexiunii. Valorile posibile: Broken, Closed, Connecting, Executing, Fetching, Open.
6.3.3. Metode
a) Open(): deschide o conexiune la baza de date b)Close() i Dispose(): nchid conexiunea i elibereaz toate resursele alocate pentru ea c) BeginTransaction(): pentru executarea unei tranzacii pe baza de date; la sfrit se apeleaz Commit() sau Rollback(). d)ChangeDatabase(): se modific baza de date la care se vor face conexiunile. Noua baz de date trebuie s existe pe acelai server ca i precedenta. e) CreateCommand(): creeaz o comand (un obiect de tip Command) valid asociat conexiunii curente.
6.3.4. Evenimente
a) StateChange: apare atunci cnd se schimb starea conexiunii. Handlerul corespunztor (de tipul delegat StateChangeEventHandler) spune ntre ce stri s-a fcut tranziia. b) InfoMessage: apare cnd furnizorul trimite un avertisment sau un mesaj ctre client.
6.4. Command
Clasele din categoria Command (SQLCommand, OleDbCommand etc.) conin date referitoare la o comand SQL (SELECT, INSERT, DELETE, UPDATE) i metode pentru executarea unei comenzi sau a unor proceduri stocate. Aceste clase implementeaz interfaa IDbCommand. Ca urmare a interogrii unei baze de date se obin obiecte din categoriile DataReader sau DataSet. O comand se poate executa numai dup ce s-a stabilit o conxiune cu baza de date corespunztoare.
CAPITOLUL 6. ADO.NET
93
6.4.1. Proprieti
a) CommandText (String): conine comanda SQL sau numele procedurii stocate care se execut pe sursa de date. b)CommandTimeout (int): reprezint numrul de secunde care trebuie s fie ateptat pentru executarea comenzii. Dac se depeste acest timp, atunci se genereaz o excepie. c) CommandType (enumerare de componente de tip CommandType): reprezint tipul de comand care se execut pe sursa de date. Valorile pot fi: StoredProcedure (apel de procedur stocat), Text (comand SQL obinuit), TableDirect (numai pentru OleDb) d)Connection (System. Data. [Provider].PrefixConnection): conine obiectul de tip conexiune folosit pentru legarea la sursa de date. e) Parameters (System.Data.[Provider].PrefixParameterCollection): returneaz o colecie de parametri care s-au transmis comenzii. f) Transaction (System.Data.[Provider].PrefixTransaction): permite accesul la obiectul de tip tranzacie care se cere a fi executat pe sursa de date.
6.4.2. Metode
a) Constructori: SqlCommand() SqlCommand(string CommandText) SqlCommand(string CommandText, SqlConnection con ) SqlCommand(string CommandText,SqlConnection con,SqlTransaction trans) b)Cancel() oprete o comand aflat n executare. c) Dispose() distruge obiectul comand. d)ExecuteNonQuery()execut o comand care nu returneaz un set de date din baza de date; dac comanda a fost de tip INSERT, UPDATE, DELETE, se returneaz numrul de nregistrri afectate.
Exemplu: SqlCommand cmd = new SqlCommand(); cmd.CommandText = DELETE FROM elevi WHERE nume = BARBU; cmd.Connection = con; Console.WriteLine(cmd.ExecuteNonQuery().ToString()); //cte nreg. s-au sters
94
reader.GetString(0),reader.GetString(1)); } reader.Close();
Metoda ExecuteReader() mai are un argument opional de tip enumerare, CommandBehavior, care descrie rezultatele i efectul asupra bazei de date: CloseConnection (conexiunea este nchis atunci cnd obiectul DataReader este nchis), KeyInfo (returnez informaie despre coloane i cheia primar), SchemaOnly (returnez doar informaie despre coloane), SequentialAccess (pentru manevrarea valorilor binare cu GetChars() sau GetBytes()), SingleResult (se returneaz un singur set de rezultate), SingleRow (se returneaz o singur linie). f) ExecuteScalar() execut comanda i returneaz valoarea primei coloane de pe primul rnd a setului de date rezultat; folosit pentru obinerea unor rezultate statistice.
Exemplu: SqlCommand cmd = new SqlCommand(SELECT COUNT(*) FROM elevi,con); SqlDataReader reader = cmd.ExecuteScalar(); Console.WriteLine(reader.GetString(0));
Obiectele de tip SQLCommand pot fi utilizate ntr-un scenariu ce presupune deconectarea de la sursa de date dar i n operaii elementare care presupun obinerea unor rezultate imediate. Vom exemplifica utilizarea obiectelor de tip Command n operaii ce corespund acestui caz. Presupunem c am stabilit conexiunea:
using System.Data.SqlClient; SqlConnection conn = new SqlConnection(@Data Source=serverBD;Database=MAGAZIN;User ID=adm;Password=eu); conn.Open();
CAPITOLUL 6. ADO.NET
95
i c tabela PRODUSE are cmpurile ID_PRODUS, DENUMIRE_PRODUS, DESCRIERE Instanierea unui obiect de tip SQLCommnand
SqlCommand cmd = new SqlCommand(select DENUMIRE_PRODUS from PRODUSE, conn);
conine un string ce precizeaz comanda care se execut i o referin ctre obiectul SQLConnection.
SqlCommand cmd = new SqlCommand(select DENUMIRE_PRODUS from PRODUSE, conn); // Obtinem rezultatul cererii SqlDataReader rdr = cmd.ExecuteReader();
Facem observaia c am specficat explicit numai coloanele DENUMIRE_PRODUS i DESCRIERE. Tabela PRODUSE are cheia primar ID_PRODUS. Valoarea acestui cmp va fi atribuit de SQL Server. Dac ncercm s adugm o valoare atunci va fi generat o excepie.
96
Cteodat avem nevoie s obinem din baza de date o singur valoare, care poate fi o sum, o medie sau alt rezultat al unei funcii agregat. O alegere ineficient ar fi utilizarea metodei ExecuteReader i apoi calculul valorii. n acest caz, cea mai bun alegere este s lucrm direct asupra bazei de date i s obinem aceast valoare.
// Instantiem o comand nou SqlCommand cmd = new SqlCommand(select count(*) from PRODUSE, conn); // Executm comanda si obtinem valoarea int count = (int)cmd.ExecuteScalar();35
CAPITOLUL 6. ADO.NET
97
rdr = cmd.ExecuteReader(); while (rdr.Read()) { Console.WriteLine(rdr[0]);} } finally { if (rdr != null) {rdr.Close();} if (conn != null){conn.Close();} } } }
2) Realizai funcii care s implementeze operaiile elementare asupra unei baze de date i verificai funcionalitatea lor.
using System; using System.Data; using System.Data.SqlClient; class ADO2 { SqlConnection conn; public ADO2() { conn = new SqlConnection(Data Source=(local);Initial Catalog=MAGAZIN;Integrated Security=SSPI); } static void Main() { ADO2 scd = new ADO2(); Console.WriteLine(Produse aflate n magazin nainte de Insert); scd.ReadData();scd.Insertdata(); Console.WriteLine(Produse aflate n magazin dupa Insert); scd.ReadData();scd.UpdateData(); Console.WriteLine(Produse aflate n magazin dupa Update); scd.ReadData();scd.DeleteData(); Console.WriteLine(Categories After Delete); scd.ReadData(); int number_inregistrari = scd.GetNumberOfRecords(); Console.WriteLine(Numarul de inregistrari: {0}, numar_inregistrari); } public void ReadData() { SqlDataReader rdr = null; try {conn.Open(); SqlCommand cmd = new SqlCommand(select DENUMIRE_PRODUS from PRODUSE, conn); rdr = cmd.ExecuteReader(); while (rdr.Read()) {Console.WriteLine(rdr[0]);} } finally { if (rdr != null){rdr.Close();}
98
if (conn != null){conn.Close();} } } public void Insertdata() {try {conn.Open(); string insertString = @insert into PRODUSE(DENUMIRE_PRODUS, DESCRIERE) values (SCOOBY, jucarie de plus); SqlCommand cmd = new SqlCommand(insertString, conn); cmd.ExecuteNonQuery(); } finally {if (conn != null){conn.Close();} } } public void UpdateData() { try {conn.Open(); string updateString = @update PRODUSE set DENUMIRE_PRODUS = SCOOBY DOO where DENUMIRE_PRODUS = SCOOBY; SqlCommand cmd = new SqlCommand(updateString); cmd.Connection = conn; cmd.ExecuteNonQuery(); } finally {if (conn != null){conn.Close();} } } public void DeleteData() { try { conn.Open(); string deleteString = @delete from PRODUSE where DENUMIRE_PRODUS = BARBIE; SqlCommand cmd = new SqlCommand(); cmd.CommandText = deleteString; cmd.Connection = conn; cmd.ExecuteNonQuery(); } finally {if (conn != null){conn.Close();}} } public int GetNumberOfRecords() { int count = -1; try { conn.Open(); SqlCommand cmd = new SqlCommand(select count(*) from Produse, conn); count = (int)cmd.ExecuteScalar(); }
CAPITOLUL 6. ADO.NET
99
6.5. DataReader
Datele pot fi explorate n mod conectat (cu ajutorul unor obiecte din categoria DataReader), sau pot fi preluate de la surs (dintr-un obiect din categoria DataAdapter) i nglobate n aplicaia curent (sub forma unui obiect din categoria DataSet). Clasele DataReader permit parcurgerea ntr-un singur sens a sursei de date, fr posibilitate de modificare a datelor la surs. Dac se dorete modificarea datelor la surs, se va utiliza ansamblul DataAdapter + DataSet. Datorita faptului c citete doar nainte (forward-only) permite acestui tip de date s fie foarte rapid n citire. Overhead-ul asociat este foarte mic (overhead generat cu inspectarea rezultatului i a scrierii n baza de date). Dac ntr-o aplicaie este nevoie doar de informaii care vor fi citite o singura dat, sau rezultatul unei interogri este prea mare ca sa fie reinut n memorie (caching) DataReader este soluia cea mai bun. Un obiect DataReader nu are constructor36, ci se obine cu ajutorul unui obiect de tip Command i prin apelul metodei ExecuteReader() (vezi exerciiile de la capitolul anterior). Evident, pe toat durata lucrului cu un obiect de tip DataReader, conexiunea trebuie s fie activ. Toate clasele DataReader (SqlDataReader, OleDbDataReader etc.) implementeaz interfaa IDataReader.
6.5.1. Proprieti:
a) IsClosed (boolean, read-only)- returnez true dac obiectul este deschis si fals altfel b)HasRows (boolean,read-only) - verific dac reader-ul conine cel puin o nregistrare c) Item (indexator de cmpuri) d)FieldCount - returneaz numrul de cmpuri din nregistrarea curent
6.5.2. Metode:
a) Close() nchidere obiectului i eliberarea resurselor; trebuie s precead nchiderea conexiunii. b)GetBoolean(), GetByte(), GetChar(), GetDateTime(), GetDecimal(), GetDouble(), GetFloat(), GetInt16(), GetInt32(), GetInt64(), GetValue(), GetString() returneaz valoarea unui cmp specificat, din nergistrarea curent
36 Dac pentru instantiere este folosit operatorul new vei obine un obiect cu care nu putei face nimic pentru c nu are o conexiune i o comand ataate.
100
c) GetBytes(), GetChars() citirea unor octei/caractere dintrun cmp de date binar d)GetDataTypeName(), GetName() returneaz tipul/numele cmpului specificat e) IsDBNull() returneaz true dac n cmpul specificat prin index este o valoare NULL f) NextResult()determin trecerea la urmtorul rezultat stocat n obiect (vezi exemplul) g)Read() determin trecerea la urmtoarea nregistrare, returnnd false numai dac aceasta nu exist; de reinut c iniial poziia curent este naintea primei nregistrri. DataReader obine datele ntr-un stream secvenial. Pentru a citi aceste informaii trebuie apelat metoda Read; aceasta citeste un singur rnd din tabelul rezultat. Metoda clasic de a citi informaia dintr-un DataReader este de a itera ntr-o bucl while. Ex.1)
SqlCommand cmd=new SqlCommand(select * from elevi;select * from profi, conn ); conn.Open (); SqlDataReader reader = cmd.ExecuteReader (); do { while ( reader.Read () ) {Console.WriteLine ( {0}\t\t{1}, reader[0], reader[1] );} } while ( reader.NextResult () );
DataReader implementeaz i indexatori (n exemplul anterior am afiat primele coloane folosind indexatori numerici). Nu este foarte clar pentru cineva care citete codul care sunt coloanele afiate dect dac s-a uitat i n baza de date. Din aceasta cauz este preferat utilizarea indexatorilor de tipul string. Valoarea indexului trebuie s fie numele coloanei din tabelul rezultat. Indiferent c se folosete un index numeric sau unul de tipul string indexatorii ntorc totdeauna un obiect de tipul object fiind necesar conversia. Exemplu: Codul
SqlCommand cmd = new SqlCommand(select * from PRODUSE, conn); rdr = cmd.ExecuteReader(); while (rdr.Read()) {Console.WriteLine(rdr[0]);}
este echivalent cu
SqlCommand cmd = new SqlCommand(select * from PRODUSE, conn); rdr = cmd.ExecuteReader(); while (rdr.Read()){Console.WriteLine (rdr[ID_PRODUS]);
CAPITOLUL 6. ADO.NET
101
using System; using System.Data; using System.Data.SqlClient; class ADO3 { static void Main() {ADO3 rd = new ADO3(); rd.SimpleRead(); } public void SimpleRead() { SqlDataReader rdr = null; SqlConnection conn = new SqlConnection( Data Source=(local);Initial Catalog=MAGAZIN;Integrated Security=SSPI); SqlCommand cmd = new SqlCommand(select * from PRODUSE, conn); try { conn.Open(); rdr = cmd.ExecuteReader(); Console.WriteLine(DENUMIRE PRODUS DESCRIERE); while (rdr.Read()){string den = (string)rdr[DENUMIRE_PRODUS]; string descr = (string)rdr[DESCRIERE]; Console.Write({0,-20}, den); Console.Write({0,-30}, descr); Console.WriteLine(); } } finally {if (rdr != null){rdr.Close();} if (conn != null){conn.Close();} } } }
6.6. DataAdapter
Folosirea combinat a obiectelor DataAdapter i DataSet permite operaii de selectare, tergere, modificare i adugare la baza de date. Clasele DataAdapter genereaz obiecte care funcioneaz ca o interfa ntre sursa de date i obiectele DataSet interne aplicaiei, permind prelucrri pe baza de date. Ele gestioneaz automat conexiunea cu baza de date astfel nct conexiunea s se fac numai atunci cnd este imperios necesar. Un obiect DataSet este de fapt un set de tabele relaionate. Folosete serviciile unui obiect DataAdapter pentru a-i procura datele i trimite modificrile napoi ctre baza de date. Datele sunt stocate de un DataSet n format XML, acelai folosit i pentru transferul datelor. n exemplul urmtor se preiau datele din tablele elevi i profi:
SqlDataAdapter de=new SqlDataAdapter(SELECT nume,clasa FROM elevi, conn); de.Fill(ds,Elevi);//transfer datele n datasetul ds sub forma unei tabele locale numite elevi SqlDataAdapter dp=new SqlDataAdapter(SELECT nume, clasdir FROM profi,conn);
102
dp.Fill(ds,Profi);//transfer datele n datasetul ds sub forma unei tabele locale numite profi
6.6.1. Proprieti
a) DeleteCommand, InsertCommand, SelectCommand, UpdateCommand (Command), conin comenzile ce se execut pentru selectarea sau modificarea datelor n sursa de date. b)MissingSchemaAction (enumerare) determin ce se face atunci cnd datele aduse nu se potrivesc peste schema tablei n care sunt depuse. Poate avea urmtoarele valori: Add - implicit, DataAdapter adaug coloana la schema tablei AddWithKey se adug coloana i informaii relativ la cheia primar Ignore - se ignor lipsa coloanei respective, ceea ce duce la pierdere de date Error - se genereaz o excepie de tipul InvalidOperationException.
6.6.2. Metode
Constructori:SqlDataAdapter()|SqlDataAdapter(obiect_comanda)| SqlDataAdapter(string_comanda, conexiune); a) Fill() permite umplerea unei tabele dintrun obiect DataSet cu date. Permite specificarea obiectului DataSet n care se depun datele, eventual a numelui tablei din acest DataSet, numrul de nregistrare cu care s se nceap popularea (prima avnd indicele 0) i numrul de nregistrri care urmeaz a fi aduse. a) Update() permite transmiterea modificrilor efectuate ntrun DataSet ctre baza de date.
6.7. DataSet
Un DataSet este format din Tables (colecie format din obiecte de tip DataTable; DataTable este compus la rndul lui dintr-o colecie de DataRow i DataColumn), Relations (colecie de obiecte de tip DataRelation pentru memorarea legturilor printecopil) i ExtendedProperties ce conine proprieti definite de utilizator. Scenariul uzual de lucru cu datele dintr-o tabel conine urmtoarele etape: popularea succesiv a unui DataSet prin intermediul unuia sau mai multor obiecte DataAdapter, apelnd metoda Fill (vezi exemplul de mai sus) procesarea datelor din DataSet folosind numele tabelelor stabilite la umplere, ds.Tables[elevi], sau indexarea acestora, ds.Tables[0], ds.Tables[1] actualizarea datelor prin obiecte comand corespunztoare operaiilor INSERT, UPDATE i DELETE. Un obiect CommandBuilder poate construi automat o combinaie de comenzi ce reflect modificrile efectuate. Aadar, DataAdapter deschide o conexiune doar atunci cnd este nevoie i o inchide imediat aceasta nu mai este necesar.
CAPITOLUL 6. ADO.NET
103
De exemplu DataAdapter realizeaz urmtoarele operaiuni atunci cnd trebuie sa populeze un DataSet:deschide conexiunea, populeaza DataSet-ul,nchide conexiunea i urmatorele operaiuni atunci cnd trebuie sa fac update pe baza de date: deschide conexiunea, scrie modificarile din DataSet in baza de date,inchide conexiunea. Intre operaiunea de populare a DataSet-ului i cea de update conexiunile sunt inchise. Intre aceste operaii n DataSet se poate scrie sau citi. Crearea unui obiect de tipul DataSet se face folosind operatorul new.
Exemplu. DataSet dsProduse = new DataSet ();
Constructorul unui DataSet nu necesit parametri. Exist totui o suprancrcare a acestuia care primete ca parametru un string i este folosit atunci cand trebuie s se fac o serializare a datelor ntr-un fisier XML. In exemplul anterior avem un DataSet gol i avem nevoie de un DataAdapter pentru a-l popula. Un obiect DataAdapter conine mai multe obiecte Command (pentru inserare, update, delete i select) i un obiect Connection pentru a citi i scrie date. n exemplul urmtor construim un obiect de tipul DataAdapter, daProd. Comanda SQL specific cu ce date va fi populat un DataSet, iar conexiunea conn trebuie s fi fost creat anterior, dar nu i deschis. DataAdapter-ul va deschide conexiunea la apelul metodelor Fill i Update.
SqlDataAdapter daProd = new SqlDataAdapter (SELECT ID_PRODUS, DENUMIRE_PRODUS FROM PRODUSE, conn);
Prin intermediul constructorului putem instania doar comanda de interogare. Instanierea celorlalte se face fie prin intermediul propriettilor pe care le expune DataAdapter, fie folosind obiecte de tipul CommandBuilder.
SqlCommandBuilder cmdBldr = new SqlCommandBuilder (daProd);
La iniializarea unui CommandBuilder se apleleaz un constructor care primete ca parametru un adapter, pentru care vor fi construite comenzile. SqlCommandBuilder are nu poate construi dect comenzi simple i care se aplic unui singur tabel. Atunci cand trebui ca sa facem comenzi care vor folosi mai multe tabele este recomandat construirea separat a comnezilor i apoi atasarea lor adapterului folosind proprieti. Popularea DataSet-ului se face dup ce am construit cele dou instane:
daProd.Fill (dsProduse, PRODUSE);
n exemplul urmtor va fi populat DataSet-ul dsProduse. Cel de-al doilea parametru (string) reprezint numele tabelului (nu numele tabelului din baza de date, ci al tabelului rezultat n DataSet) care va fi creat. Scopul acestui nume este identificarea ulterioar a tabelului. n cazul n care nu sunt specificate numele tabelelor, acestea vor fi adugate n DataSet sub numele Table1, Table2, ...
104
Un DataSet poate fi folosit ca surs de date pentru un DataGrid din Windows Forms sau ASP.Net .
Exemplu. DataGrid dgProduse = new DataGrid(); dgProduse.DataSource = dsProduse; dgProduse.DataMembers = PRODUSE;37
Dup ce au fost fcute modificri ntr-un DataSet acestea trebuie scrise i n baza de date. Actualizarea se face prin apelul metodei Update.
daProd.Update (dsProduse, PRODUSE);
6.8. SqlParameter
Atunci cnd lucrm cu bazele de date avem nevoie, de cele mai multe ori s filtrai rezultatul dup diverse criterii. De obicei acest lucru se face n funcie de nite criterii pe care utilizatorul le specific (ex: vrei s vedei doar ppuile Barbie). Cea mai simpl metod de filtrare a rezultatelor este s construim dinamic string-ul SqlCommand dar aceast metoda nu este recomandat deoarece poate afecta baza de date (ex. Accesarea informaiilor confideniale). Dac folosim interogri cu parametri atunci orice valoare pus ntr-un parametru nu va fi tratat drept cod SQL, ci ca valoare a unui cmp, fcnd aplicaia mai sigur. Pentru a folosi interogri cu parametri trebuie s: a) construim string-ul pentru SqlCommand folosind parametri;
Ex. SqlCommand cmd = new SqlCommand(SELECT * FROM PRODUSE WHERE DENUMIRE = @den, conn);38
37 Se pot afia mai multe tabele dintr-un DataSet, semnul "+" permindu-i utilizatorului s aleaga care tabel s fie afiat. Pentru a suprima afiarea acelui semn "+" setm proprietatea DataMembers pe numele tabelului care va fi afiat. Numele tabelului este acelai care l-am folosit ca parametru n apelul metodei Fill. 38 Atunci cnd comanda va fi executat @den va fi nlocuit cu valoarea aflat n obiectul SqlParameter ataat. Dac nu asociem o instan de tipul SqlParameter pentru un parametru din string-ul de interogare sau avem mai multe instane SqlParameter pentru un parametru vom obine o eroare la rulare
CAPITOLUL 6. ADO.NET
105
Primul parametru al constructorului este un ir de caractere ce reprezint numele procedurii stocate. A doua instruciune de mai sus spune obiectului SqlCommand ce tip de comand va fi executat, prin intermediul proprietii CommandType. Exemplu:
SqlCommand cmd = new SqlCommand(StoredProcedure1, conn); cmd.CommandType = CommandType.StoredProcedure; //Tipul obiectului comanda este procedura stocata personDs = new DataSet(); personDa = new SqlDataAdapter(, conn); personDa.SelectCommand = cmd; personDa.Fill(personDs, PersonTable);
Primul argument al constructorului obiectului SqlCommand este numele procedurii stocate. Aceast procedur are un parametru numit @City. De aceea trebuie folosit un obiect de tip SqlParameter pentru a adauga acest parametru la obiectul de tip Command. Exerciiu de sintez. Construii o aplicaie pentru a simula gestiunea unei biblioteci colare.
106
Precizri.Toate informaiile se vor afla ntr-o baz de date. Creati propriile structuri de date adecvate rezolvarii problemei. Utilizati Microsoft Access pentru crearea bazei de date. Iniial aplicaia va afia o form Windows care permite selectarea operaiei efectuate (adugare carte/cri, adugare abonat, actualizare stare carte/cri/abonat, mprumut carte/cri, etc.)
S urmrim un scenariu de realizare a unei aplicaii simple cu o fereastr n care putem vizualiza date dintr-o tabel, putem naviga, putem modifica sau terge nregistrri. Iniiem adugarea unei surse de date (Add New Source) Configurm cu atenie (asistai de vrjitor) conexiunea cu o surs de tip SQL sau Access; figura surprinde elemente de conectare la o baz de date Access, numit Authors, baz stocat pe hard-discul local. Selectm tabelele care ne intereseaz din baza de date i cmpurile din cadrul tabelei ce vor fi reinute n TableAdapter (din categoria DataAdapter)
Cnd operaiunea se ncheie, date relative la baza de date la care ne-am conectat sunt integrate n proiect i pictograma, ca i structura bazei de date, apar n fereastra Data Source
CAPITOLUL 6. ADO.NET
107
Prin tragerea unor obiecte din fereastra Data Sources n fereastra noastr nou, se creeaz automat obiecte specifice. n partea de jos a figurii se pot observa obiectele de tip Dataset, TableAdapter, BindingSource, BindingNavigator i, n fereastr, TableGridView
BindingNavigator este un tip ce permite, prin instaniere, construirea barei de navigare care faciliteaz operaii de deplasare, editare, tergere i adugare n tabel. S observm c reprezentarea vizual a fiecrui obiect este nzestrat cu o sget n partea de sus, n dreapta. Un clic pe aceast sgeat activeaz un meniu contextual cu lista principalelor operaii ce se pot efectua cu obiectul respectiv.
Meniul contextual asociat grilei n care vor fi vizualizate datele permite configurarea modului de lucru cu grila (sursa de date, operaiile permise i altele).
108
n timpul rulrii aplicaiei, bara de navigare i elementele vizuale ale grilei permit operaiile de baz cu nregistrrile bazei de date. Operaiile care modific baza de date trebuie s fie definitivate prin salvarea noilor date .
BIBLIOGRAFIE
Marshall Donis, Programming Microsoft Visual C# 2005: The Language, Microsoft Press 2006,
ISBN:0735621810
Pelland Patrice, Build a Program NOW, Microsoft Visual C# 2005 Express Edition, Microsoft Press
2006,
LearnVisualStudio.NET http://www.learnvisualstudio.net resurse educaionale gratuite sub forma de
filme
Harris Andy, Microsoft C# Programming for the Absolute Beginner, Premier Press 2002,
ISBN: 1?931841?16?0
Wright Peter, Beginning Visual C# 2005 Express Edition: From Novice to Professional, Apress 2006,
ISBN 13:9780596003098
Solis Daniel, Illustrated C# 2005, Apress 2006, ISBN-13 (pbk): 978-1-59059-723-1,
http://www.programmersheaven.com/2/CSharpBook
Schneider Robert, Microsoft SQL Server 2005 Express Edition For Dummies, Wiley Publishing
ISBN: 0-12-167451-7
Christian Nagel, Bill Evjen, Jay Glynn, Karli Watson, Morgan Skinner, Allen Jones,
Professional C# 2005, Wiley Publishing, Inc., 2006, ISBN-13: 978-0-7645-7534-1 ISBN-10: 0-7645-7534-1 Sharp John, Visual C# 2005, DUNOD 2006 Iulian Serban, Dragos Brezoi, Tiberiu Radu, Adam Ward, GDI+ Custom Controls with Visual C# 2005, PACKT Publishing 2006, ISBN 1-904811-60-4 Simpson Alan, Visual Web Developer Server 2005 Express Edition For Dummies, Wiley Publishing 2006, ISBN-13: 978-0-7645-8360-5, ISBN-10: 0-7645-8360-3 Hoffman Kevin, Microsoft Visual C# 2005 Unleashed, Sams 2006, ISBN-10: 0-672-32776-7, ISBN-13: 978-0-672-32776-6 Popovici, Dorin Mircea i colaboratorii - Proiectare i implementare software, Editura TEORA, Bucureti, 1998 C# Language Specification, Microsoft Corporation, 1999-2003 C# Version 2.0 Specification May 2004, Microsoft Corporation, 1999-2005 David Conger, Programarea n C#, editura B.I.C. ALL 2003 Chris H. Pappas, William H. Murray C# pentru programarea Web, editura B.I.C. ALL 2004 MCAD/MCSD -Developing XML WEB SERVICES and SERVER COMPONENTS WITH MICROSOFT http://www.csharp-station.com http://msdn2.microsoft.com M.E.C. Serviciul Naional de Evaluare i Examinare - Ghid de evaluare, INFORMATICA i TEHNOLOGIA INFORMATIEI, Editura Aramis, Bucureti 2001 M.E.C. Consiliul Naional pentru Curriculum - Ghid metodologic pentru aplicarea programelor colare, Editura Aramis, Bucureti 2002 M.E.C Consiliul Naional pentru curriculum - Ghid metodologic pentru Educaie Tehnologic Informatic - Tehnologia Informaiei - Liceu teoretic - Editura Aramis, Bucureti 2001
.Net Framework
ISBN: 973-86699-5-2
Introducere n
Ediia 2008