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

IDulciuri

+Faina: string

Budinca

IDulciuri

+Orez: string

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:

0..*

Animal

Animal[] animale = new Animal[5];

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