Sunteți pe pagina 1din 14

1.

Introducere i un pic de programare obiectual


n cele ce urmeaz, vom ncerca s ne familiarizm cu programarea sub Windows. Aa cum bnuii, avnd n fa un sistem de operare grafic, programele pe care le vom scrie difer ntr-o oarecare msur de cele cu care suntei obinuii, n fapt, exist cteva diferene semnificative, dintre care putem aminti: Windows este un sistem de operare bazat pe interfee grafice, deci metodele de intrare-ieire alfanumerice, care acceseaz fiierele standard de intrare i ieire nu mai sunt efective. Aceasta, bineneles c nu nseamn ca nu le vom putea utiliza n programe. Windows este un sistem de operare n care, aa cum tii, se pot rula mai multe programe simultan. Se spune c Windows este un sistem de operare multitasking. n astfel de sisteme de operare, fiecare program (proces) va trebui s fie executat ntr-un spaiu de memorie binedeterminat, fr a avea posibilitatea ca mrimi dintr-un program s poat accesa adrese din spaiul altui program. Este motivul pentru care majoritatea limbajelor noi (C#, Java, etc) au renunat s ofere programatorilor posibilitatea manipulrii adreselor fizice prin intermediul pointerilor, prefernd n locul acestora utilizarea referinelor. Trebuie amintit faptul c, spre deosebire de aa numitele programe pe 16 bii, n Windows orice adres este generat pe 32, 64 sau chiar 128 de bii, depinznd de tipul procesorului cu care este dotat calculatorul. Spre deosebire de programarea pe 16 bii cu care suntei obinuii, n Windows intrrile-ieirile dintr-un program nu sunt n mod necesar sincrone cu execuia acestuia. Adic citirea sau afiarea datelor nu se face doar n momentul execuiei unor instruciuni de intrare-ieire, ci se poate face i asincron, n momentul producerii unor evenimente. n general, aplicaiile Windows sunt bazate exclusiv pe programarea orientat pe obiecte. Marea majoritate a mediilor de programare noi, ofer aplicaii de tip wizard, care uureaz semnificativ efortul programatorilor, n special pentru construirea interfeelor. 1.1 Windows Form Designer i acum, pe cai. Vom ncepe prin a studia un limbaj nou, aprut n acest mileniu, numit C# (se citete C sharp). Mediul de programare Microsoft Visual C# 2005 Express Edition, n care vom lucra n cele ce urmeaz, ofer un cadru (wizard) pentru construirea interfeelor, comun mediilor de dezvoltare de programe de tip Visual al firmei Microsoft, numit Windows Form Designer. Pentru a vedea ce ne ofer acest wizard, s deschidem un noi proiect Visula C#, numit unu. Pentru aceasta, vom deschide mediul de programare Microsoft Visual C# 2005 Express Edition, n caseta Recent Projects vom alege Create: Project . Apoi, n caseta New Project aprut, vom alege Windows Application i vom apsa OK. Vei avea n fa o aplicaie ca i cea prezentat n fig. 1.

Figura 1. Interfaa Form Designer

Se poate observa c n centru imaginii se gsete o machet a formei care urmeaz s constituie interfaa grafic a aplicaiei. Toate controalele necesare proiectrii interfeei pot fi aduse pe aceast form prin mecanismul drag and drop, utiliznd tab-ul Toolbox din stnga imaginii. Observaie: Daca tab-ul Toolbox lipsete, poate fi afiat alegnd din meniu View i respectiv Toolbox. n partea dreapt a imaginii, se pot vedea dou panouri. n dreapta sus se gsete panoul Solution Explorer, n care popt fi vzute toate proiectele deschise precum i fiierele asociate acestora. n dreapta jos, poate fi vzut panoul Properties. Acest panou conine toate proprietile elementelor selectate, oferind posibilitatea editrii acestora fr prea mare efort. nainte de a merge mai departe, va trebui s ne reamintim cte ceva despre programarea obiectual. Vom vedea de asemenea ca exist mici diferene fa de ceea ce am studiat n cursul de C. 1.2 S ne reamintimun pic de programare obiectual S ne reamintim c n cadrul programrii obiectuale, am introdus un tip nou de date, care ncapsuleaz un set de atribute i un set de metode de acces la acestea, numit clas. S ne reamintim de asemenea, c trivial spus, o variabil de tipul unei clase, sau mai corect o instaniere a unei clase, poart denumirea de obiect. Datorit faptului c majoritatea aplicaiilor pot conine o mulime de clase i instanieri ale acestora, pentru a 2

nelege structura acestora i relaiile dintre ele, a fost dezvoltat un limbaj special de descriere, numit UML (Universal Modeling Language). Vom ncerca n cele ce urmaz, s introducem i cteva noini referitoare la acest limbaj. S presupunem de exemplu c avem o clasa Prjitur. Reprezentarea Prjitur Savarina:Prjitur UML a acestei clase poate fi vzut n fig. 2.a. Se poate observa c numele clasei este scris n partea de sus casetei. n mod absolut similar, se poate a) b) Figura 2 reprezenta i o instaniere a clasei, fie aeasta Savarin (fig. 2.b). Numele instanei este prezentat mpreun cu numele clasei, separate prin :. 1.2.1 Proprieti i cmpuri Proprietile i cmpurile (atributele) asigur accesul la datele coninute n interiorul unui obiect. Practic, prin aceasta se pot diferenia diferite obiecte ce reprezint instanieri ale aceleiai clase. Aceste date vor furniza n fapt starea obiectului respectiv. Att cmpurile ct i proprietile sunt mrimi de un anumit tip. Un cmp se utilizeaz pentru a reprezenta o mrime cantitativ asociat obiectului, iar o proprietate pentru a limita valoarea acesteia la un anumit interval. De exemplu, vom utiliza un cmp pentru a reprezenta proprietatea Zahar a obiectului Savarin i repectiv o proprietate pentru a limita valoarea acestui cmp, de exemplu ntre 0 i 6. Att la cmpuri ct i la proprieti, accesul se poate face n 2 moduri: public sau privat (private). Un membru Prjitur public este accesibil ntregului cod al programului, n timp ce +Faina: string un membru privat este accesibil doar codului din interiorul +Drojdie: bool clasei. Uzual, cmpurile private sunt acei membri ai clasei ale +Lapte: bool cror valori sunt supuse unor restricii. Ei sunt expui restului +Zahar: byte codului (adic accesibili) n general prin intermediul unor +Altele: string proprieti publice. O reprezentre UML a cmpurilor i proprietilor poate fi vzut n fig. 3. Se poate observa c n UML, cea de-a doua caset Figura 3 este rezervat cmpurilor i proprietilor. Prefixul + este utilizat pentru a reprezenta caracterul public al cmpului sau proprietii, iar prefixul pentru a reprezenta caracterul privat. Prefixul este urmat de numele cmpului sau proprietii i respectiv tipul acestora. 1.2.2 Metode O metod este o funcie expus de un obiect. Metodele sunt utilizate pentru a permite accesul la atributele obiectului. Pot fi de asemenea publice sau private. Prin intermediul metodelor se poate verifica sau modifica starea unui obiect, inclusiv n situaia n care accesul se face asupra unor atribute private. n UML, metodele sunt prezentate n caseta a treia (fig. 4).

n fig. 4, a fost adugat metoda AdaugZahar, care primete ca parametru cantitatea de zahr adaugata sub forma unui octet fr semn i returneaz noua valoare a atributului Zahar. n UML, se utilizeaz de asemenea identificatorii in, out i inout pentru a specifica sensul fluxului de date.

Prjitur +Faina: string +Drojdie: bool +Lapte: bool +Zahar: byte +Altele: string +AdaugZahar(in cantitate:byte):byte

Figura 4 1.2.3 Constructori Iniializarea unui obiect este automat, alocarea memoriei pentru acesta facndu-se fr intervenia programatorului. Rezervarea memoriei se face de ctre o funcie numit constructor. Constructorul este o funcie avnd acelai nume cu numele clasei, care treebuie sa fie neaparat public i care poate sau nu s aib parametri. Orice clas are un constructor implicit, care nu are parametri. Acest constructor, n cazul utilizrii programelor de tip wizard, este adugat de ctre acestea i nu mai trebuie definit. n C#, constructorul unui obiect este apelat prin intermediul cuvntului new.

Exemplu: Prajitura Savarina = new Prajitura(); O clas poate expune mai muli constructori neimplicii, care pot avea parametri. Acetia vor fi apelai de o manier smilar. Exemplu: Prajitura Isler = new Prajitura(000, TRUE, TRUE, 150, ?); 1.2.4 Destructori Destructorul este metoda care elibereaz memoria calculatorului de obiectele a cror ciclu de via a expirat. Spre deosebire de C++, n C# destructorul nu trebuie definit. Mediul de programare implementeaz un colector de reziduri (garbage collector), care periodic inspecteaz dac exist memorie alocat unor obiecte care nu mai exist i realizeaz eliberarea automat a acesteia. 1.3 Tehnici de programare obiectual 1.3.1 Interfee n programarea obiectual, poate apare situaia n care clase diferite pot avea un numr de membri (atribute sau metode) comuni, care asigur legtura cu exteriorul. n aceast situaie, aceti membri pot fi grupai mpreun, constituind o interfa. Deci o interfa este o colecie de atribute i metode publice, grupate mpreun pentru a ncapsula o funcionalitate specific. O interfa odat definit, poate fi implementat n interiorul unei clase. O interfa nu poate exista doar ea insi. O interfa nu poate fi instaniat i n plus o interfa nu poate implementa cod n nici unul din membrii si. Ca exemplu, s considerm nc o clasa, numit Budinc, care expune aceeai membri ca i clasa Prajitur, diferind doar prin cmpurile Faina respectiv Orez. Toi membri comuni vor putea fi ncapsulai n interfaa IDulciuri. 4

<<Interface>> IDulciuri +Drojdie: bool +Lapte: bool +Zahar: byte +Altele: string +AdaugZahar(in cantitate:byte): byte

Prajitura +Faina: string

IDulciuri

Budinca +Orez: string

IDulciuri

Figura 5

O clas poate utiliza mai multe interfee, iar o interfa poate fi comun mai multor clase. 1.3.2 Motenirea Motenirea este cea mai important caracteristic a programrii obiectuale. Prin intermediul ei, o clas, numit clas derivat, poate moteni trsturile unei alte Animal clase, numit clas de baz, sau superclas, pe care le poate extinde i eventual +Hraneste() modifica. Se pot realiza astfel ierarhii de +Reproduce() clase, fr a fi necesar redefinirea fiecri clase n parte. Spre deosebire de C++, C# permite doar motenirea simpl. n figura 6 este prezentat o astfel de ierarhie de clase. Clasa Animal este clasa de baz i expune 2 Pasare Mamifer metode: Hraneste() i Reproduce(). Din aceast clas sunt derivate clasele Pasare i +Zboara() +Fuge() +FaceOua() +Alapteaza() Mamifer, care motenesc metodele clasei de baz, dar adaug fiecare 2 metode noi: Figura 6 Zboara() i FaceOua(), respectiv Fuge() i Alapteaz(). S ne reamintim accesibilitatea membrilor clasei. Membrii privai ai clasei de baz nu vor fi accesibili claselor derivate, n timp ce membri publici vor fi accesibili att claselor derivate ct i restului codului. Va apare un al treilea tip de acces, respectiv protejat (protected). Un membru protejat al clasei de baz va fi accesibil claselor derivate, dar nu va fi accesibil restului codului. Oricare dintre membrii clasei poate fi definit ca virtual, adic poate fi redefinit (supranscris) n clasele derivate. Cu alte cuvinte, un membru virtual poate furniza o implementare alternativ n clasele derivate. Aceast implementare alternativ nu terge implementarea original din clasa de baz, care rmne accesibil claselor derivate, dar o ascunde pentru restul codului. Un membru virtual nu poate fi privat, pentru c n acest caz nu ar fi accesibil claselor derivate pentru a fi redefinit. Dac un membru este virtual, el va apare n diagrama UML a clasei derivate, avnd evident o alt implementare. Metoda Hraneste() este implementat virtual n clasa Mamifer (fig. 7).

Exist situaii n care anumite metode virtuale ale clasei de baz nu pot fi implementate. Ele trebuie declarate, pentru a fi redefinite n clasele derivate. Astfel de metode se numesc virtuale pure. O clas care conine cel puin o metod virtual pur este o clas abstract. O clas abstract nu poate fi instaniat, deci nu se pot defini obiecte de acel tip. n UML numele unei clase abstracte se reprezint prin caractere italice. O clas poate fi sigilat (sealed). O astfel de clas nu poate fi folosit ca i clas Animal de baz, sau cu alte cuvinte, din ea nu se pot deriva alte clase. +Hraneste() Ierahia de clase este pus n eviden +Reproduce() n numele unei clase prin specificarea numelui tuturor claselor din amonte, separate prin punct. Vom avea astfel, n exemplul nostru Animal.Pasare, respectiv Animal.Mamifer, .a.m.d. Pasare Mamifer 1.3.3 Polimorfismul +Zboara() +Fuge() +Alapteaza() +FaceOua() Ca o consecin a motenirii, clasele +Hraneste() de baz i clasele derivate pot realiza o suprapunere a metodelor i proprietilor pe Figura 7 care le expun. Atfel, obiecte instaniate din clase avnd aceeai clas de baz, pot fi tratate n comun. De exmplu, cum clasa Animal expune metoda Hraneste(), aceasta va putea fi expus prin aceeai sintax de obiecte ale claselor derivate:
Mamifer pisica = new Mamifer(); Pasare vrabie = new Pasare() pisica.Hraneste(); vrabie.Hraneste();

Mai mult, prin intermediul polumorfismului, vom putea atribui unui obiect al clasei de baz, un obiect al unei clase derivate, fr a fi nevoie de nici o transformare explicit de tip:
Animal unanimal = pisica; unanimal.Hraneste();

Astfel, la apelarea metodei Hraneste() prin intermediul obiectului clasei de baz, surprinztor, va fi apelat metoda clasei derivate. Dar, o metod definit n clasa derivat, nu va putea fi apleat. Astfel, codul de mai jos, va genera eroare.
unanimal.Fuge();

Aceast metod va fi expus doar printr-o conversie explicit de tip:


Mamifer vulpe = (Mamifer) unanimal; vulpe.Fuge();

1.3.4 Relaii ntre obiecte Motenirea reprezint o relaie simpl ntre obiecte, n care membrii unei clase de baz sunt expui complet de obiecte aparinnd unor clase derivate. Exist ns i alte situaii n care relaiile ntre obiecte devin importante: Continut (containement) situaie n care o clas conine alt clas. Este oarecum sismilar motenirii, dar permite clasei care conine s controleze accesul la membrii clasei coninute i chiar s execute aciuni suplimentare naninte de a permite utilizarea membrilor clasei coninute. Colecie (collection) situaie n care o clas se manifest ca i container pentru instabe multiple a altei clase. Este similar cu a avea tablouri unidimensionale de obiecte, asupra crora se pot executa indexri, sortri, etc. 1.3.5 Coninerea Coninerea este simplu de realizat prin declararea unui obiect ca i cmp al unei clase. Acest cmp trebuie s fie public, pentru ca utilizatorii obiectului coninut s aib acces Alapteaza 1 la metodele i proprietile expuse de acesta. Ca alternativ, acest cmp poate fi +Lapte() privat. Astfel, nici unul din membrii clasei din care face parte acel obiect nu va fi accesibil. Accesul la acetia se va putea face doar prin intermediul membrilor clasei care conine. 1 Animal Astfel, controlul asupra membrilor clasei contineAlapteaza: Alapteaza coninute va fi total, putndu-se controla care +Hraneste() din ei sa fie expui i care nu. +Reproduce() De exmplu, clasa Mamifer poate conine clasa Alapteaz,care are metoda Figura 8 public Lapte(). Clasa Mamifer poate apela aceast metod dac este nevoie, de exmplu prin intermediul metodei Hraneste() (fig. 8). 1.3.6 Colecia Un tablou unidimensional de obiecte de acleai tip poate fi declarat ca mai jos:
Animal[] animale = new Animal[5];

0..*

Animal

O colecie este n esen un ir de elemente de acelai tip. Coleciile sunt implementate n clase de aceeai manier ca i alte obiecte i sunt numite n general prin pluralul obiectelor pe care le stocheaz. Spre exemplu, o colecie de obiecte de tip Animal, va putea fi numot Animale. Complexitatea unei colecii este superioar unui simplu tablou unidimensional, prin faptul c

Animale

Figura 9

implementeaz de obicei metode de tipul Add() i Remove() care adaug sau terg elemente din colecie. De asemenea, este n general utilizat o proprietate de tip Item, care returneaz obiectul de la un indice dat. Reprezentarea UML a unei astfel de colecii poate fi vazut n fig. 9. Prin marcajul 0..* se specific faptul ca colecia Animale va conine zero sau mai multe obiecte de tip Animal. O descriere pe larg a POO, n sens clasic, putei gsi n Anexa 1. 1.3.7 Evenimente Obiectele pot genera evenimente (events). Pentru aceasta, codul va trebui completat cu un handler (event handler), care n fapt este o funcie special, ce va trebui apelat pentru generarea unui eveniment specific. Acest funcie, trebuie de asemnea s fie capabil s asculte (listen) pentru a detecta producerea evenimentului specific. n acest mod, se poate crea o aplicaie orientat pe evenimente (event-driven). Aplicaiile Windows sunt n totalitate aplicaii conduse de evenimente. Orice aciune asupra interfeei, apsarea unui buton, scrierea unei litere, micarea mouse-lui, va genera un astfel de eveniment. Astfel, intrrile-ieirile din program devin asincrone cu execuia lui. 1.4 S revenim la forme. E timpul s ncepem s vedem cu ce ne ajut Form Designer n construirea unei aplicaii Windows. 1.4.1 Toolbox Prin intermediul Toolbox-ului, programatorul are la dispoziie toate tipurile de controale necesare pentru construirea unei aplicaii. Toolbox-ul poate fi particularizat pentru a satisface nevoile programatorului, dar pe moment vom studia moful de utilizare al toolboxului implicit.
Figura 10. Toolbox

1.4.2 Controale Marea majoritate a controalelor sunt obiecte de clase derivate din clasa System.Windows.Forms.Control. Aceast clas furnizeaz funcionalitatea de baz pentru controale, de aceea multe din proprietile i evenimentele controalelor, chiar dac acestea sunt structural diferite, vor fi identice. La rndul lor, clasele care definesc unele controale, pot fi clase de baz pentru alte controale, mai complexe. 1.4.3 Proprieti ale controalelor Toate controalele vor dispune de un set de proprieti, care definesc comportamentul acestora. Clasa de baz Control va furniza un set de proprieti, motenite i eventual supranscrise de toate controalele. n cele ce urmeaz, vom prezenta un set de astfel de proprieti, furnizate de clasa Control, deci comune tuturor controalelor. O descriere detaliat a acestor proprieti poate fi gsit n MSDN.

Anchor prin aceast proprietate se poate specifica comportamenul controlului la

redimensionarea ferestrei ce-l conine. Ancorarea lui de una din marginile ferestrei va face ca poziia acestuia fa de marginea respectiv s nu se schimbe. Ancorarea lui de toate marginile ferestrei va avea ca efect redimensionarea controlului odat cu redimensionarea ferestrei. BackColor stabilete culoarea de fond a controlului. Bottom stabilete distana de la marginea de sus a ferestrei la marginea de jos a controlului. Dock ataeaz controlul de una din marginile ferestrei. Enabled activeaz controlul, adic permite acestuia s recepioneze evenimente de la utilizator. Dac aceast proprietate este FALSE, controlul este inactiv. ForeColor definete culoarea textului. Height definete nlimea controlului. Left definete marginea stng a controlului, relativ la marginea stng a ferestrei. Name identificatorul controlului. Poate fi utilizat n cod pentru a individualiza i accesa controlul. Parent printele controlului. Right - definete marginea dreapt a controlului, relativ la marginea stng a ferestrei. TabIndex numrul asociat controlului n ordinea de tab. Ordinea de tab stabilete ordinea in care controalele primesc input focusul (se selecteaz) la apsarea tastei TAB. TabStop Stabilete dac controlul primete input focusul la apsarea tastei TAB. Dac controlul nu are aceast proprietate, la apsarea tastei TAB va fi srit. Tag este o proprietate care n general nu este utilizat de control. Poate fi doar un ir de caractere, care este stocat n interiorul controlului. Top - stabilete distana de la marginea de sus a ferestrei la marginea de sus a controlului. Visible dac aceast proprietate este TRUE, controlul este vizibil. n caz contrar, dei exist n form, el nu poate fi vazut. Width - stabilete limea controlului.

1.4.4 Evenimente generate de controale Atunci cnd utilizatorul acioneaz asupra unui control (apas un buton, selecteaz o opiune radio, scrie ntr-o list, etc) aplicaia trebuie s fie capabil s sesizeze faptul ca s-a acionat asupra controlului respectiv, s identifice tipul aciunii i s execute o secven de cod care s rezolve problema n concordan cu tipul aciunii. Pentru a sesiza aciunea asupra lor, controalele genereaz evenimente. Clasa Control implementeaz un set de evenimente comune tuturor controalelor, iar acestea, la rndul lor, vor genera i un set de evenimente specifice. Cele mai uzuale evenimente sunt prezentate mai jos, lista complet a acestora fiind disponibil n MSDN.
Click este generat cnd se apas click cu mouse-ul asupra unui control. Poate fi uneori generat i de apsarea tastei Enter.

DoubleClick este generat cnd se apas dublu click asupra unui control. Dac

controlul este buton, acest eveniment nu va putea fi generat, pentru ca la prima apsare se genereaz automat Click. DragDrop este generat cnd se finalizeaz (este eliberat butonul mouse-lui) o operaie drag-and-drop n care este implicat controlul. DragEnter este generat atunci cnd obiectul implicat ntr-o operaie drag-and-drop ajunge n interiorul controlului. DragLeave - este generat atunci cnd obiectul implicat ntr-o operaie drag-and-drop prsete suprafaa controlului. DragOver este generat cnd un obiect implicat ntr-o operaie drag-and-drop ajunge deasupra controlului. KeyDown este generat cnd o tast devine apsat n timp ce controlul deine input focusul. Se genereaz ntotdeauna nainte de KeyPress i KeyUp. KeyPress - este generat cnd o tast devine apsat n timp ce controlul deine input focusul. Se genereaz ntotdeauna dup KeyDown i nainte de KeyUp. Spre deosebire de KeyDown care furnizeaz codul de scanare al tastei apsate, KeyPress furnizeaz codul ascii al tastei. KeyUp - este generat cnd o tast este eliberat n timp ce controlul deine input focusul. Se genereaz ntotdeauna dup KeyDown i KeyPress. GotFocus este generat cnd controlul primete input focusul. LostFocus este generat cnd controlul pierde input focusul. MouseDown este generat cnd prompterul mouse-lui este deasupra controlului i se apas o tast a mouse-lui. MouseMove este generat continuu atta timp ct prompterul mouse-lui traverseaz controlul. MouseUp - ste generat cnd prompterul mouse-lui este deasupra controlului i se elibereaz o tast a mouse-lui. Paint se genereaz la desenarea controlului. Validated este generat cnd un control este n curs de a primi focusul. Se genereaz dup ce evenimentul Validating se termin i indic faptul c validarea controlului este complet. Validating - ste generat cnd un control este n curs de a primi focusul.

1.5 Primul exemplu S ncercm acum s aplicm ce-am nvat ntr-un prim program Windows. Vom completa proiectul unu, deschis la paragraful 1.1. Pentru nceput, s adugm formei un buton. l vom trage din caseta common controls i l vom poziiona n colul stnga jos al formei. l vom mri astfel nct sa ajunng de form ptrat. Observai c Form Designer i-a asociat eticheta button1. O putem schimba, modificnd poziia corespunztoare n caseta de proprieti. Cutm proprietatea Text i introducem textul Activeaz (fig. 11). Astfel, am schimbat n mod static o proprietate a obiectului buton, numit de ctre Form Designer button1, care este un obiect al clasei Button.

10

Urmeaz s-i asociem un handler de eveniment. Dac apsm dublu click pe buton, Form Designer va aduga un handler asociat evenimentului Click i ne va permite s-i completm codul. Observm c s-a generat urmtorul cod:

Proprietatea Text Figura 11 namespace unu { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { } } }

Metoda cu codul bold este handlerul asociat evenimentului Click produs de butonul button1. Ea primete ca parametri obiectul care produce acel eveniment i respectiv un obiect EventArgs. Codul implementat n interiorul funciei va fi executat la apsarea butonului button1. Ce observm? i n C#, o funcie returneaz un tip (void n cazul nostru), are un nume i un numr de parametri formali. n acest caz special, funcia fiind un handler, ea nu trebuie apelat, fci este lansat n execuie de producerea evenimentului asociat. Haidei s ncercm s adugm noi handleri pentru alte evenimente produse de buton. De exemplu, s interceptm evenimentele generate de intrarea prompterului 11

mouse-lui n suprafaa butonului, respectiv prsirea acesteia. Aceste evenimente sunt MouseHover i MouseLeave. Vom completa codul ca mai jos:
public Form1() { InitializeComponent(); button1.MouseHover += new EventHandler(button1_MouseHover); button1.MouseLeave += new EventHandler(button1_MouseLeave); } private void button1_MouseHover(object sender, EventArgs e) { } private void button1_MouseLeave(object sender, EventArgs e) { }

Ce am fcut? Am adugat aplicaiei doi noi handleri, asociai celor 2 evenimente i le-am definit funciile asociate. Observai c funciile poart numele declarate ca parametru pentru metoda EventHandler(). i acum, s completm codul celor 2 funcii.
public partial class Form1 : Form { private Color culoare; public Form1() private void button1_MouseHover(object sender, EventArgs e) { culoare = button1.BackColor; button1.BackColor = Color.DarkGray; } private void button1_MouseLeave(object sender, EventArgs e) { ((Button)sender).BackColor = culoare; }

Am adugat clasei Form1 o variabil privat culoare, care este un obiect de clasa Culoare. n funcia button1_MouseHover(), am atribuit acestei variabile valoarea atributului BackColor al obiectului button1 i apoi am modivicat valoarea acestui atribut la culoarea DarkGray. n metoda button1_MouseLeave(), am refcut vechea culoare a butonului. Astfel, am modificat atributul butonului n mod dinamic. Ce observm? Atributele unei clase sunt adugate la fel ca i n C++. Observaii: 1. Observai c n timp ce scriem codul, Form Designer ne ofer informaii asupra codului i l poate completa singur (la apsarea tastei TAB). 2. Se poate vedea c atributul BackColor l-am modificat n 2 moduri: fie prin intermediul numelui button1, fie cu secvena ((Button) sender). Este corect oricum, pentru c handlerul primete n argumentul sender numele obiectului care a generat evenimentul. 12

Compilai programul (Build, Build Solution) i executai-l (Debug, Start Without Debugging). Observai efectul trecerii prompterului mouse-lui pe deasupra butonului. Haidei s ncercm acum s crem dinamic, prin program, un nou buton. Acesta va fi creat la apsarea butonului button1, deci codul va fi implementat n handlerul asociat acestui eveniment.
private void button1_MouseLeave(object sender, EventArgs e) { ((Button)sender).BackColor = culoare; } private void button1_Click(object sender, EventArgs e) { Button butonnou = new Button(); butonnou.Width = 120; butonnou.Height = 100; butonnou.ForeColor = Color.Red; butonnou.Text = "Apasa-ma si pe mine!"; butonnou.Click += new EventHandler(butonnou_Click); Controls.Add(butonnou); } private void butonnou_Click(object sender, EventArgs e) { }

Ce am fcut? Am creat un nou buton, numit butonnou, apelnd constructorul clasei Button. Am setat atributele Width, Height, ForeColor i Text pentru acest obiect, am creat un handler pentru evenimentul Click i apoi am adugat efectiv noul obiect formei, prin intermediul metodei Add() a clasei Controls. Recompilai proiectul (Build, Rebuild Solution) i executai-l. Ce se ntmpl cind apsai pe buton? Ultimul lucru pe care l mai avem de fcut este s completm handlerul butonnou_Click().
private Color culoare; private bool apasat = false; private void butonnou_Click(object sender, EventArgs e) { int i; if (apasat == false) { ((Button)sender).ForeColor = Color.Green; apasat = true; for (i = 0; i < 60; i++) { int j, k; j = 1000; while (j >= 0) { k = 10000;

13

do k--; while (k >= 0); j--; } ((Button)sender).Width--; ((Button)sender).Height--; } } else { ((Button)sender).ForeColor = Color.Red; apasat = false; for (i = 0; i < 60; i++) { ((Button)sender).Width++; ((Button)sender).Height++; } } }

Codul nu reprezint o problem. Ce ar fi de observat, este c tipurile simple din C# sunt aceleai ca i cele din C++. Mai mult, la fel variabilele trebuie declarate nainte de a fi utilizate, iar domeniul lor de vizibilitate este similar. Operatorii ++ i -funcioneaz similar. De asemenea, instruciunile if-then, for, do-while i while au formatul absolut similar celui din C++. Fr a apare n acest cod, se poate spune c i instruciunea switch este similar. i acum, putem trece la studiul diferitelor controale. Dar asta, n capitolul urmtor.

14

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