Documente Academic
Documente Profesional
Documente Cultură
G L A N , C O N S T A N T IN
C urs de C # : program are n V isual C# 2008 Express
E dition / C onstantin G lan, Susana Glan. - B ucureti :
E ditura L & S Info-m at, 2008
ISB N 978-973-7658-16-6
I. G lan, Susana
004.43 C#
C UPR IN S
C# i platform a .N E T .................................................................................. 7
.NET Fram ew ork......................................................................................................................................8
Compilarea programelor pe platforma .N E T ................................................................................ 9
Instrumente de dezvoltare a aplicaiilor .N E T ............................................................................ 10
Principalele caracteristici ale arhitecturii .N E T .......................................................................... 10
Mediul Integrat Visual Cri 2008 Express E dition.................................................... ...................... 11
Instalare.............................................................................................................................................11
Compilare n linie de com and.......................................................................................................12
Primul program CU........................................................................................................................... 12
O scurt analiz a programului salut.cs......................................................................................... 14
Crearea unei aplicaii de tip consol............................................................................................. 14
IntelliSense - o facilitate important a editorului de c o d .......................................................... 16
Rezumatul capitolului............................................................................................................................ 17
ntrebri i e x erc iii............................................................................................................................... 17
Rezumatul capitolului............................................................................................................................ ^
ntrebri i ex erciii..............................................................................................................................." J
Metode generice................................................................................................................................117
C olecii.................................................................................................................................................... 119
Clasa generic S t a c k < T > ............................................................................................................ 119
Clasa generic L i s t < T > .............................................................................................................. 120
Clasa generic D i c t i o n a r y C T k e y , T v a l u e > .................................................................121
Tratarea excepiilor................................................................................................................................123
Manevrarea stringurilor........................................................................................................................124
Operaii i m etode............................................................................................................................ 125
Formatarea stringurilor................................................................................................................... 125
Transformarea stringurilor n valori num erice........................................................................... 126
Citirea unui ir de valori num erice ..................................................................................... 127
Citiri i afiri din fiiere de tip tex t.................................................................................................. 128
Rezumatul capitolului........................................................................................................................... 130
ntrebri i e x erc iii...............................................................................................................................130
.... -*
III < nil 1'i i 1
6 C# p en tru liceu Cuprins C a p ito lu l!. C# i platform a .N E T 7
.N E T F ram ew o rk
* Base Class L ib ra ry
Este vorba despre Biblioteca de Clase .NET. Aceast bibliotec,
acoper o arie larg a necesitilor de programare, incluznd
interfaa cu utilizatorul, conectarea cu bazele de date i accesarea
datelor, dezvoltarea aplicaiilor web, comunicarea n reele i altele.
Codul bibliotecii este precompilat, fiind ncapsulat de regul n
funcii, numite metode, pe care programatorul le poate apela din
propriul program. La rndul lor, metodele aparin claselor, iar
clasele sunt organizate i separate ntre ele cu ajutorul spaiilor de
nume (namespaces). Despre toate aceste noiuni vom vorbi pe larg
n capitolele urmtoare. Ceea ce trebuie reinut pentru moment,
este c programatorii combin propriul cod cu codul Bibliotecii de
Clase .NET pentru producerea de aplicaii.
C a p ito lu l!. CU i p la tfo rm a .N E T 9
C o m p ila re a p ro g ra m e lo r pe platfo rm a .N E T
Limbaje interpretate
Cnd programai ntr-un limbaj de programare interpretat, vei scrie codul i
vei rula aplicaia. Cu ajutorul unui interpretor specific limbajului, fiecare linie de cod
este interpretat chiar n momentul rulrii i este preschimbat imediat n cod
main i executat. Partea bun este c putei rula codul pn la primul bug,
putei nltura eroarea n cod iar apoi s continuai execuia codului. Limbajul nu
necesit timp de compilare i de legare. Partea neplcut este c limbajele
interpretate sunt lente. Limbajul Basic a fost iniial un limbaj interpretat, dar mai
apoi, ncepnd cu anii 1980, au aprut i versiuni compilate. Marea majoritate a
limbajelor de scriptare Web sunt de asemenea limbaje interpretate.
Limbaje compilate
Codul scris ntr-un asemenea limbaj, numit cod surs, este translatat de
ctre compilator ntr-un cod apropiat de nivelul mainii, numit cod executabil (de
exemplu codul coninut n fiierele (*.exe). Dac n timpul compilrii apar erori,
atunci este necesar s le nlturai, dup care vei compila din nou. Dac aplicaia
trece acum de compilare fr erori de sintax, atunci se va produce codul
executabil i vei putea s rulai aplicaia. Limbajele C i C++ sunt exemple clasice
de limbaje compilate.
Din aceast perspectiv C# este un limbaj compilat. Dar nu n sensul descris
mai sus. Ca s nelegei, este necesar s tii c n urma compilrii unui program
C#, nu se creaz un cod executabil. Se creeaz un fiier numit a s s e m b ly care de
regul se identific cu extensia .exe sau .d!l. Un asemenea fiier nu poate fi
executat pe un sistem pe care nu exist infrastructura .NET. Fiierul conine un tip
special de cod, numit L im b a j Interm ediar, pe scurt CIL (Common intermediate
Language). Limbajul CIL definete un set de instruciuni portabile, independente
de orice tip de procesor i platform.
Figura ilustreaz procesul de creare a codului executabil pe platforma .NET.
Cod surs
C# C om pilator C# .Net
Cod surs
C om pilator J# .Net
,J# C IL i com pilare
m etadate cu J I T
(.exe i .dll) i execuie
Cod surs C om pilator C++.Net r
C!
Securitate
.NET furnizeaz un model comun de securitate, valabil pentru toate
aplicaiile, care include un mecanism unificat de tratare a excepiilor. O excepie
este un eveniment neprevzut, care ntrerupe execuia unui program, atunci cnd
de pild, se execut o intruciune ilegal.
Portabilitate
Un program scris pentru platforma .NET poate rula fr nici o modificare pe
oricare sistsm pe care platforma este instalat.
Caracteristicilor de mai sus li se adaug i altele, care ies ns din cadrul
acestei lucrri.
Visual C# 2008 Express Edition (pe scut: VCSE), este un mediu free de
dezvoltare a aplicaiilor produs de Microsoft. Este un IDE (integrated development
environment), care ofer un set de instrumente, ntre care un editor de cod pentru
scrierea programelor C#, compilator, depanator, instrumente pentru build
automation (automatizarea procesului de compilare) i altele. Kit-ul de instalare C#
Express, include Platforma .NET 3.5, iar aceasta la rndul ei include ntre altele
Biblioteca de Clase.
Cerine de sistem
Sistemele de operare suportate sunt: Windows Server 2003, Windows Vista',
Windows XP.
instalare
Visual C# 2008 Express Edition poate fi descrcat de pe site-ul Microsoft,
ia adresa http://www.microsoft.com/express/download/. Alternativ, n josul paginii
avei opiunea de a descrca Visual Studio Express Edition pentru o instalare
offline. Visual Studio conine mediile de programare Visual C#, Visual Basic,
Visual C++, precum i serverul de baze de date Microsoft SQL Server 2005.
Instalarea se face simplu, cu ajutorul unui wizard, ns pentru montarea imaginii
DVD-ului (fiier cu extensia ISO) avei nevoie de un utilitar cum ar fi de pild
Daemon Tools.
Ca observaie, indiferent dac vei instala Visual Studio sau doar Visual C#
2008 Express, vei opta ntotdeauna pentru instaiarea .NET Framework, Visual
C#, MS SQL Server i MSDN (Micorsoft Developer Network). MSDN conine o
foarte bogat documentaie de care nu v putei lipsi cnd dezvoltai aplicaii.
12 Partea I. L im bajul C#
Primul program C#
Este o tradiie pstrat n timp, ca o carte de programare s nceap cu
programul care afieaz pe ecran s a l u t lu m e ! Vom compila i executa acest
program C# n linie de comand, urmnd paii de mai jos:
3. E xecutarea p rog ra m u lu i
Rularea programului se face simplu, prin tastarea numelui fiierului .exe:
c:\teste>salut
Programul afieaz:
Salut l u m e !
important ' * * * *
,0 deosebirffa d e 'C + i este faptul'c trebuie s existe n cjiail
de fa clasa S a ltf care gzduiete metoda Mainf). Aceast, degai^ce'C# ^ste
un lim b a j p u r o rientat obiect, i riti pci exista deftniii de funcii fn.aknra claselor
n acest sens, C# seamn cu Java. Totui, n Java numele clasei care conine
metoda main() trebuie s coincid n mod obligatoriu cu numele fiierului. Dac
vei schimba mai sus numele clasei, de exemplu Hello, o s constatai c nu vei
avea nici o problem la compilare.
Linia Console.WriteLine("Salut lume!"); este apelul metodei
statice WriteLine din clasa Console. O s revenim asupra metodelor statice n
capitolele urmtoare. Pentru moment, reinei c o metod static se apeleaz
astfel: nume clasa.nume metod.
M y T e m p la te s
S earch O n tn e
Tem plates...
Name: sakit
| OK 1 ! C a re d
u s in g S y s te m ;
' u s in g S y s te m .C o lle c tio n s .C e n e ric ;
! u s in g S y s te m .L ir.q ;
u s in g S y s te m .T e x t;
n am esp ace s a lu t
' {
j c la s s -
{
j: s ta tic v o i d M a in ( s c r ir .g [) a rg s)
| {
: )
)
16 Partea I. L im bajul C#
5. Rularea programului.
Programul este gata de compilare i rulare. Se apas F5 ori click pe iconul ^
ntrebri i exerciii
C apitolul 2
Limbajul C# . Introducere
Limbajul C# este deosebit de simplu, cu numai 80 de cuvinte cheie i 12
tipuri incorporate. Dar C# este n acelai timp un limbaj foarte productiv din punct
de vedere al programrii aplicaiilor i pe deplin adaptat conceptelor moderne de
programare.
Fiind un limbaj orientat pe obiecte, o caracteristic esenial a sa este
suportul pentru definirea i lucrul cu clasele. Clasele definesc tipuri noi de date.
Variabilele de tip clas se numesc obiecte. Uneori un obiect este abstract, cum ar fi
o tabel de date sau un thread (program sau proces lansat n execuie). Alteori
obiectele sunt mai tangibile, cum sunt un buton sau o fereastr a aplicaiei.
Obiectele sunt un element fundamental n programare datorit rolului lor n
modelarea problemelor din practic care trebuie rezolvate. Programarea orientat
pe obiecte se sprijin pe trei piloni fundamentali: ncapsularea datelor, m o te n ire
i p o lim o rfis m .
Clasele C# conin c m p u ri i p ro p rie t i care rein informaii despre obiecte
i m e to d e (funcii aparinnd clasei). Metodele ncapsuleaz cod care descrie ceea
ce poate face obiectul, aciunile i capabilitile sale. Obiectele la rndul lor,
interacioneaz, comunic ntre ele.
C# este un limbaj care ofer suport explicit pentru tratarea eve n im e n te lo r.
Vom reveni pe larg asupra tuturor acestor concepte n capitolele urmtoare.
C# admite program area generic. Programarea generic este un stil de
programare diferit de programarea orientat pe obiecte. Scopul programrii
generice este scrierea de cod care s fie independent de tipul datelor. De exemplu,
imaginai-v o funcie care primete ca parametru un ir numeric pe care l
sorteaz. Algoritmul de sortare nu depinde de tipul elementelor irului. Acestea pot
fi de pild ntregi sau reale. n aceast situaie n C# putei defini o funcie
generic, care va folosi dup caz, iruri ntregi sau reale.
C#, aa cum s-a vzut n capitolul precedent utilizeaz un garbage
c o lle c to r (colector de deeuri) pentru eliberarea memoriei ocupate de obiectele de
care aplicaia nu mai are nevoie. Obiectele C# se aloc ntotdeauna dinamic, adic
n timpul execuiei programaului i se distrug n mod automat.
/*
Programul declarar variabile, iniializeaz
variabile i face atribuiri
*/
C apitolul 2. L im b a ju l C#. Introducere 19
namespace SpatiulMeu
{
class Test
{
static void Main(string[] args)
{
int a; // Declararea unei variabile locale
a = 20; // Atribuire
double b = 10; // Declarare i iniializare
string s = "obiect de tip string";
System.Console.WriteLine("a = " + a ) ;
System.Console.WriteLine("b = " + b ) ;
System.Console.WriteLine("s este " + s ) ;
}
}
}
a = 20
b = 10
s este obiect de tip string
Tipuri abstracte
Programul declar un tip (clasa cu numele Test) i un membru al clasei
(metoda Main). Este o diferen fa de C++, unde de regul tipurile abstracte se
declar n fiiere header, iar definiiile acestora n fiiere .cpp separate.
Variabile locale
Metodele unei clase pot s declare variabile locale, aa cum este variabila
ntreag a, variabila real b i variabila de tip string, s. Tipul string este un tip
definit n Biblioteca de Clase .NET, fiind destinat lucrului cu iruri de caractere.
Variabilele locale pot fi iniializate cu valori la momentul declarrii.
Comentarii
C# admite comentarii multilinie ( / * ... * / ) i comentarii de o singur linie
( I I ), ntocmai ca C++.
20 Partea I. L im bajul C#
Clase |
C# lucreaz cu clase. Fiind un limbaj pur orientat obiect, nu putei scrie un 5
program C# fr clase. Totul se petrece n interiorul claselor. Tot ceea ce aparine I
unei clase, va fi definit n interiorul ei. Nu exist variabile globale i nici funcii |
globale. Un program trebuie s aib cel puin o clas, aceea care conine metoda |
M a in . O clas se definete cu ajutorul cuvntului cheie c la s s . j
Exemplu: f
class Persoana
t *
{ I
// membrii clasei v
}
Observaie: I
Programatorii C++ trebuie s fie avizai de faptul c n C# dup ultima j
parantez nchis a clasei, nu se pune ; . j
4
Spaii de nume definite de programator \
Exist spaii de nume predefinite. Ne referim la acelea care fac parte din I
Biblioteca de Clase .NET. n acelai timp C# permite programatorilor s-i creeze !
propriile spaii de nume pentru organizarea logic a aplicaiilor mari. Ai remarcat I
desigur namespace SpatiulMeu definit n primul program. Este bine de reinut i
c prezena lui este opional i c att clasa care conine metoda Main, ct i !
celelalte clase ale programului pot s fie incluse sau nu n interiorul unui I
namespace. I
j
Calificarea complet a numelor cu ajutoruloperatorului . j
Afirile pe ecran s-au fcut prin apelul metodei statice writeLine din |
clasa Console. Clasa Console este definit n spaiul de nume System. Pentru
utilizarea claselor C# din Biblioteca de Clase .NET, dar i a metodelor statice ale j
acestor clase, exist alternativele: |
1. Utilizarea directivei using; !
Directiva using face vizibile n program toate numele de clase dintr- j
un spaiu de nume. Reamintim c spaiile de nume sunt containere logice j
care servesc la separarea numelor de tipuri ntr-o bibliotec de clase sau j
ntr-un program. f
Exemple: |
using System; - toate numele definite n spaiul de nume |
System devin accesibile. |
~
using System.Windows.Forms - clasele din spaiul de nume \
Forms devin vizibile n program. Observai c spaiile de nume se I
pot include unele n altele. De pild System conine mai multe f
clase, dar i spaii de nume printre care spaiul de nume Windows, j
Spaiul de nume Windows la rndului lui inciude mai multe spaii 1
de nume, ntre care i Forms.
C apitolul 2. L im b a ju l C#. In troducere 21
class Test
{
static void Main()
{
Console.WriteLine("C#");
1
}
// A l d o i le a p ro g ram p r e c iz e a z c a le a c o m p le t
// a n u m e lu i m e to d e i
class Test
{
static void Main()
{
System,Console.WriteLine("C#");
>
}
u s i n g S y s te m ;
c la s s P ro g ra m
t
s t a t i c v o id M a i n ( s t r i n g [] arg s)
{
fo r ( i n t i = 0 ; i < a r g s .L e n g t h ; i+ + )
C o n s o le .W r ite ( a r g s [ i] + " " ) ;
}
1
22 Partea I. L im bajul C#
OBSERVAII
Vom reveni n capitolul urmtor asupra buclei for. n acest moment reinei
sintaxa preluat din limbajul C.
Length este o proprietate public a clasei abstracte Array, care returneaz
numrul de elemente ale irului. Toate tablourile unidimensionale din C#
motenesc clasa Array, deci pot utiliza proprietile acesteia.
Suild E vents | |
Debug*
Working directory: I
j Q
Re so u rces 3 Enable the Visual Studio hosting process
Settings
Vei alege un prototip sau altul, n funcie de necesiti. Dac dorii ca aplicaia s
ntoarc sistemului de operare o valoare ntreag, de pild un cod de eroare cnd
programul se termin, atunci vei prefera o signatur care returneaz int. Dac
aplicaia folosete argumente transmise de ctre utilizator din linie de comand,
atunci vei opta pentru o versiune cu un parametru de tip ir de stringuri.
IMPORTANT
r- C# este case-sensitive. Aceasta nseamn c M a in este corect, iar m a in greit, c
W r i t e L i n e nu este tot una cu w x i t e l i n e .
> Cuvintele cheie din Cit, (retum , i n t , v o i d , i f , etc) se scriu cu litere mici.
> Pentru tipurile definite de programator, pentru spaiile de nume i pentru metode,
exist convenia p e care este indicat s o respectai i anume: prim a liter este
mare i fiecare cuvnt coninut ncepe tot cu liter mare.
Exemple: Console .ReadLine () - metod
System.Time Zone - spaiu de nume
System.Data. SqlClient - clas
ntrebri i exerciii
Capitolul 3
Fundamentele limbajului C#
Acest capitol descrie elemente de baz ale limbajului C#: tipurile de date,
sintaxa, expresiile, operatorii, directivele de procesare.
Toate programele din acest capitol se pot testa cu ajutorul unei aplicaii de tip
consol n Visual C# 2008 Express Edition.
Tipuri
Tipuri predefinite
C# ofer toate tipurile de baz necesare unui limbaj de programare modern.
In C# toate tipurile sunt obiecte, chiar i cele mai elementare tipuri. Cuvintele cheie
pentru tipurile predefinite (int, char, double, etc.) sunt mapate direct peste tipuri
struct din spaiul de nume System. De exemplu, cuvntului cheie int i
corespunde clasa System. Int32 din Biblioteca de Clase .NET. Avei libertatea s
declarai o variabil ntreag astfel:
Maparea tipurilor primitive peste tipuri din .NET asigur faptul c tipurile create n
C# pot interaciona cu tipuri create n alte limbaje care lucreaz pe platforma .Net.
Tipurile referin predefinite sunt object i string.
a
t<
' i;
26 Partea I. L im bajul C#
Tipul o b j e c t |
Tipul object este rdcina ntregii ierarhii de tipuri i clasa de baz a 1
tuturor claselor din .NET Fram ew ork. Aceasta nseamn pe de o parte c toate |
clasele din .NET motenesc clasa object i pe de alat parte c oricare clas |
definit de programator deriv n mod implicit din object. f
Tipul s t r i n g
Tipul s t r i n g reine un ir de caractere din setul Unicode. Unicode este un
standard care permite reprezentarea tuturor caracterelor scrise n orice limb
scris, nu doar n limbile de circulaie internaional (n jur de 100.000 carcatere).
. Declarri de variabile
I
Toate declarrile de mai jos sunt legale:
ushort u = 7;
int a = 10;
long p = 3, q = 8L;
ulong x = 2UL, y = 5L, z = 10U, w = 8;
float fl = -4.5, f 2 = 3.8F ;
double dl = 1.3, d2 = 0.2 D ;
char c = 'T /
D e c i m a l d = 12.4M; // m desemneaz o constant decimal
Tipuri d efinite de p ro g ra m a to r
Tipul class
class nume c l a s a
(
m o d i f i c a t o r _ a c c e s T i p num e_m em bru;
// a li m em b ri
}
Exemplu:
class ntreg
{
public int x; // x - c m p (m e m b ru ) al c la s e i
De re in u t:
Variabilele de tip clas se numesc obiecte sau instane ale clasei.
Crearea unuiJobiect de tip clas, se numete instaniere.
ntreg r l , r 2 ; // D e c l a r d o u r e f e r i n e
rl = new ntreg(); // C r e e a z u n o b i e c t r e f e r i t d e rl
r2 = new ntreg(); // C r e e a z u n o b i e c t r e f e r i t d e r2
Numele Iulia
class Testlntreg Varsta 8 ani
{
static void Main() N ot
{ Metodele Write i WriteLine din clasa Console, admit formatarea
ntreg r = new ntreg(); afirii n maniera funciei printff) din C. Modificatorii {0} i {1}
r.x = 10; // A t r i b u i e v a l o a r e a 10 c m p u l u i x specific locul i ordinea n care se vor afia valorile argumentelor
C o n s o le . W r i t e ( r . x ) ; / / A f i e a z 10 p.nume, respectiv p .varsta.
}
} \n este o secven escape, reprezentnd caracterul (newline).
Observai c un program C# poate s conin una sau mai multe clase, dintre care
una singur conine metoda Main. Tipuri valoare i tipuri referin
class StackHeap
{
static void Main(string[] args)
{
irit x = 7; // V a r i a b i l l o c a l .
S 3 = new S(); // s - v a r i a b i l l o c a l
C r; // R e f e r i n a r s e m e m o r e a z p e Stiv,
r = new C(); // A l o c n Heap u n o b i e c t r e f e r i t d e
de REINUT:
Obiectele de un anume tip se pot converti n obiecte de un alt tip n mod implicit
sau explicit. Tipurile predefinite suport de asemenea conversii.
Conversiile implicite
Acest tip de conversie se produce n mod automat. O face compilatorul i
avei garania c se produce fr pierdere de informaie.
Exemplu:
ahort a = 4 ;
int n = a; // Conversie implicit spre tipul int.
II Nu s e p i e r d e in fo rm a ie
Conversiile explicite
Dac ncercai s atribuii unei variabile de tip short valoarea unei variabile
de tip int, compilatorul nu va efectua conversia implicit, deoarece aceasta poate
cauza pierdere de informaie. Avei totui posibilitatea de a efectua aceast
conversie cu ajutorul operatorului de conversie explicit (cast operator) :
int n = 10000;
short sl = n; I I Incorect. Nu v a c o m p i l a
short s2 = (short)n; I I Corect.Conversie explicit
II cu p i e r d e r e de in fo rm a ie
// D e c la r ri
object o = nuli;
int a = 2000;
short b = 3 ;
char c = 1T ';
long d = 10;
double f = 1.2;
// T e s ta re a c o n v e rtib ilit ii
a = d; I I Eroare.
a =(int)d; II Corect. Conversie explicit
o = b; I I Corect. T o a t e t i p u r i l e se c o n v e rte s c
II i n m od i m p l i c i t l a t i p u l object
b = o; I I Eroare.
C apitolul 3. F undam entele lim bajului C# 33
32 Partea I. L im bajul C#
u s in g S y s te m ;
class TestEnum
A
"Relaionali i
II
It I
O p e r a to r i a ritm e tic i
{ de testare a is X is T trua, dac x este
{. l } \ n r o m a n a :
Con s ol e . W r i t e ( " m a t e : { O i \ n i n f o : (2)'
tipului c o n v e rtib il la T. A ltfe l,
(int)Note.Mate, (int)Note.Info, (int)Note.Romana) false
as X as T R e tu m e a z x c o n v e rtit la
1
T s a u nuli d a c
c o n v e rs ia e im p o s ib il
Programul afieaz: Eqalitate == != X y x ! =y E g a i i d if e r it
AND logic & X 4 y A N D lo g ic p e bii
A X " y
mate: 10 XOR logic X O R lo g ic p e bii
info: 9 OR logic I X I y O R lo g ic p e bii
ro m a n a : 8 AND && X SS y E v a lu e a z y n u m a i d a c x
IMPORTANT !
Tablouri Tablourile sunt n realitate o b ie cte care motenesc clasa Array. De aceea,
metodele i proprietile acestei clase pot fi folosite pentru tablouri. Proprietatea
Un tablou este o structur de date coninnd variabile de acelai tip. n C#g ^ g c la s e iA r returneaz numrul de elemente ale tabloului
tablourile sunt tipuri referina. Tablourile pot fi unidimensionale sau| __________________ _______________
multidimensionale. Cele multidimensionale, la rndul lor pot fi dreptunghiularei
sau neregulate (ja g g e d). | Exemplul 2:
Mai jos, a, b, c, sunt tablouri de double, char, string, respectiv obiecte
Tablouri unidimensionale de tip A.
* class TabUnidim2
Declararea tablourilor unidimensionale se face preciznd un tip de dat_
urmat de operatorul de indexare i numele tabloului. Crearea tabloului se face cu |
class A
new urmat de tip i dimesiunea tabloului cuprins ntre paranteze ptrate.
{
}
Declarare: T i p [ ] a ;
Creare: a = new Tip[n] ; static void Main()
{
Tablourile se indexeaz de la 0. Un tablou cu n elemente este indexat de la 0 la n-f doublet] a = new double[100];
1. char[] b = new char[50];
string[] s = new string[1000];
Exemplul 1:
Programul de mai jos definete un tablou cu 5 valori de tip I n t . // Tablou de 7 obiecte de tip A
A [] ob = new A [7 ] ;
using System; for (int i = 0; i < ob.Length; i++)
if ( ob[i] == null ) //
class TabUnidiml Console.Write("null ");
for (int i = 0; i < a.Length; i++) null null null null null null null 0 0 0 0 0 0 0 0 0 0
Console.W r i t e (" a [{0}] = (l}\n", i, a[i](
Observaii:
1. C# v permite s definii clase imbricate (nested), aa cum este cazul
clasei A, definit n interiorul clasei TabUndim2 .
Programul afieaz: 2. Valorile implicite ale tablourilor numerice sunt setate la 0, iar elementele
referin sunt setate la nuli.
a[0] = l
a[l] = 2
a [2] = 3
finiialjalizare
a [3] = 4
a [4] = 5 Tablourile unidimensionale se pot iniializa cu valori de acelai tip cu tipul
Ijtabloului:
38 P artea I. L im bajul C# C apitolul 3. F undam entele lim bajului C# 39
E xem plu :
Exemple:
I using System;
// Tablou cu 4 elemente.
int[] a = new int[] { 7, 4, 3, 0 };
class TabBidim
// Sintax alternativ. Tablou cu 3 elemente {
i n t [] b = {10, 2, 17};
static void Main()
{
float[] c = { 1.2F, 7.9F, -8F };
int[,] y;
s t r i n g [] sl = new string[] { "UNU", "DOI", "TREI" }, // y = { { 1, 2, 3 }, { 2, 3, 0 } }; // Ilegal
i n t [,] x ;
// Sintax alternativ. Tablou cu 3 elemente
3 tring[]s2 = { "UNU", "DOI", "TREI" }; x = new i n t [, ] { { 1, 2, 3 }, { 2, 3, 0 } } ; / / OK
Exemple:
I)
// Tablou bidimensional cu 3 linii i 5 coloane
d o u b l e [,] a = new d o u b l e [3, 5 ] ; ! Ieire:
1 9 4 | new int[] { 1, 4 },
1 new i n t [] { 5, 9, 0, 7, 2 },
2. A doua variant de iniializare a unui tablou neregulat este urmtoarea: | new int[] { 6, 8, 3 }
I };
in t[][] a = new i n t [ ] []
{ for (int i 0; i < a.Length; i++)
new int[] f 1, 4 },
new i n t [] { 5, 9, 0, 7, 2 }, for (xnt j 0/ j 'C aifij .Lsncffch ; j++)
new i n t [] { 6, 8, 3 } Console.Write(a[i][j] + " ");
}; Console .Writ'eLine () ;
n fiecare caz compilatorul deduce tipul de dat din tipul constantelor de iniializai^
42 Partea I. L im bajul C# C apitolul 3. F undam entele lim bajului C# 43
Accesarea elementelor tabloului se face astfel: a[i] [j, k ] , unde i este al i-lea|
tablou din a, iar j i k este poziia valorii cutate n matricea i. De exem plu,! n cazul instruciunilor if imbricate, trebuie s inei seama de regula conform
valoarea -1 din a, se obine: a [2] [3, 1]. s creia un else se asociaz cu cel mai apropiat if care nu are else:
if (expresiei)
if (expresie2)
In stru c iu n i instruciunel;
else
n C# o declarare (statement) poate fi: o expresie, o instruciune simpl, oj| intruciune2; II se asociaz cu if (expresie2)
instruciune compus, o instruciune de control al fluxului de execuie (if, for,|
while, etc.), un apel de funcie, un bloc de cod, dar i o declarare de variabil! 0 e retinut:
local. | 1. Metoda ReadLineO din clasa System, c o n s o le citete linia
Un program C# este o secven de asemenea statements care se evalueaz| urmtoare din stream-ul standard de intrare {tastatur).
n ordine. n continuare, vom folosi cuvntul instruciune pentru statement. Fiecare;! 2. Metoda Parse(s), membr a structurii System.Int32 convertete
intruciune se termin cu Intruciunile C# sunt preluate cu unele mici modificri! stringul s ntr-un numr ntr-un nteg pe 32 de bii. Amintii-v c tipul
din C i C++. n continuare vom prezenta intruciunile care controleaz fluxul de ; int este un alias pentru structura Int32.
execuie al programului. j|
>! Din pcate biblioteca .N E T nu furnizeaz operatorul , aa cum o face
In s tru c iu
i n e a d e s e le c ie
if ... else f C++, capabil s extrag bytes din stream-uri i s-i converteasc direct spre tipul
Instruciunea i f . . . e l s e este mprumutat din limbajul C. Controleaz; dorit (Exemplu C++: int x ; cin x). Metodele Read() sau ReadLineO
fluxul programului prin evaluarea unei expresii booleane. n funcie de valoarea de I care se definesc ca membre ale diferitor clase din .N E T , citesc ntotdeauna din
adevr, selecteaz pentru executare o secven de instruciuni sau o alta. ; | stream-urile de intrare un caracter, un bloc de caractere sau o linie i returneaz
caracterul citit sau un string. Drept urmare, de cte ori avei nevoie -s citii valori
if (expresie_boolean) numerice, vei obine un string, pe care l vei converti cu Par se (). Toate tipurile
instruciuneal; de date ntregi Intl6, Int32, SByte, etc, definesc aceast metod.
else
instructiunea2; Instruciunea de selecie s w itc h
Instruciunile if imbricate sunt greu de scris corect, greu de citit i greu de
sau
depanat, switch este o intruciune de control mai potrivit atunci cnd avei un set
if {expresie_boolean) complex de alegeri de fcut. Sintaxa este identic cu cea din C++.
{
bloc instruciunii ; Sintaxa:
}
else jswitch ( )
{
bloc ir,struciuni2; : case vall: bloc_instruciunil;
} break;
case val2: bloc_instruciuni;
E xem plu: break;
// alte cazuri
string s = Con s o l e .R e a d L i n e O ; default: bloc instruciuni; // opional
;>
int x = i n t .P a r s e (s); n este o variabil de tip ntreg, de tip char sau de tip string. vall, val2, ... etc,
if ( x >= 0 ) sunt valorile pe care le poate lua n. Controlul este transferat etichetei case care
Console.Write("pozitiv") ; potrivete valorii lui n.
else Diferena fa de switch din C++ este aceea c C# nu suport cderea
Co n s o l e .Write("negativ"); implicit la seciunea urmtoare (fall through). Exemplul urmtor nu va compila:
44 Partea I. L im bajul C# C apitolul 3. F undam entele lim bajului C# 45
int k = 0;
switch ( k ) Sintaxa:
{
case 0: fo r e a ch (T i p i d e n t i f i c a t o r in e x p r e s i e )
Console.WriteLine ( "cazul 0" ); b lo c_instruciuni;
// goto case 1;
case 1: I Exemplu:
case 2:
Console.WriteLine( "cazul 1 si 2" ) using System;
break;
} class TestForeach
{
Cderea prin ramuri se poate face numai pentru cazuri vide, cum e case 1. Dac ; static void Main()
dorii un salt direct la o anume etichet, folosii instruciunea de salt necondiion, {
goto. Dac scoatei de sub comentariu goto case 1 ; n secvena de progra i n t [] a = {10, 20, 30)
precedent, atunci pe ecran se va afia: foreach (int x in a)
Console.Write(x
cazul Console.WriteLine()
cazul si 2
string[] st = { "UNU", "DOI", "TREI"
1! foreach (string s in st)
Ciclul f o r
Console.W r i t e (s + " ");
Este o instruciune identic cu cea din C++.
i
ll
Sintaxa:
I Ieire:
for (e x p r e s i e i ; e x p r e s ie 2 ; expresie3)
{ 110 20 30
blo c_ in stru ciu n i; iONU DOI T R E I
}
Ciclul w h i l e
Dac bloc_instruciuni e format din o singur instruciune, atunci acolade!
sunt opionale. Se evalueaz mai nti expresiei. Apoi se evalueaz : Este mprumutat fr modificri din C++.
expresie2. Aceasta controleaz bucla. Dac expresie2 este evaluat true, s
execut instruciunile cuprinse ntre acolade, apoi expresie3. Se reia evaluare i Sintaxa:
expresie2 i. ciclul continu pn cnd expresie2 este evaluat false. Api
iwhile ( e x p r e s i e )
controlul este cedat instruciunii urmtoare ciclului for.
!(
Toate expresiile sunt opionale. Dac expresie2 lipsete, condiia de tei
bloc_instruciuni;
este evaluat true:
fo r ( ;; )
|Dac bloc_instruciuni e format dintr-o o singur instruciune, atunci
Console.Write("Ciclu infinit!");
^acoladele sunt opionale. Se evalueaz expresie. Dac este evaluat true,
atunci se execut bloc_instruc:iuni. Se reia evaluarea expresiei. Ciclul
Ciclul f o r e a c h Icontinu ct timp este evaluat true.
foreach este nou n familia de limbaje C. Este folosit pentru iterarea prini
elementele unui tablou sau ale unei colecii. Coleciile sunt containere de t ^Exemplu:
generic, care pot reine secvene omogene de obiecte, aa cum vom vedea mi
trziu.
46 Partea I. L im bajul C#
int x = 5 ;
while ( x > O )
x-- ;
Ciclul d o w h ile
Este preluat fr modificri din C++. Este un ciclu cu test final, deci
bloc_instruciuni se evalueaz cel puin o dat.
Sintax:
do
{
b lo c _ in s tr u c iu n i;
} while (e x p r e s i e );
Exemplu:
int x = 5;
do
{
x--;
} while ( x > 0);
Observaie
Rezultatul evalurii expresiilor care controleaz buclele C# trebuie s fie <j!
valoare boolean, adic true sau false. Secvena urmtoare nu va compila: [
int x = 5; j
do |
< j
x--; 1
} while ( x ); // Ilegal! x este evaluat la o valoare int |
Instruciuni
* de salt necondiionat
*
C# admite instruciunile de salt g oto, break i c o n tin u e . ij
Instruciunea g o t o ij
Utilizarea goto este nerecomandabil, deoarece produce cod greu da ;
neles (cod spaghetti). n cazul n care dorii totui s o folosii urmai paii: i:
!:
1. Creai o etichet ( identificator urmat de : ) t
2. g o to etichet
C apitolul 3. F undam entele lim baju lu i C# 47
kExemplu:
i
tusing System;
Ii
>public class GoTo
I {
f 3 tatic void Main)
[ {
! int x = 1;
\ repeta: li Eticheta
| Console.W r i t e ( x + " ");
x+ + ;
[ if (x <= 5)
l goto repeta; // Salt la eticheta
I >
I 1
[
I Ieire:
ijr1 2 3 4 5
t
i
i Instruciunile b r e a k i c o n t in u e
Dac n blocul de instruciuni al unei bucle se execut continue, atunci are
[ loc un salt la nceputul buclei. Instruciunea break duce la ieirea forat din ciclu.
; Exemplu:
; using System;
o 2 4 6 8 10
48 Partea I. L im bajul C#
Sugestie i
Nu este indicat sutilizai intens aceste instruciuni,deoarece creeaz puncte j
multiple de ieire din cicluri, ceea ce duce la cod dificil de neles i de ntreinut j
(cod spaghetti). \
S p a ii de num e j
n capitolele 2 i 3 s-au discutat primele noiuni referitoare la s p a ii de num e j
(,namespaces). Am artat c sunt containere logice care gzduiesc definiii ale >
tipurilor de date. Au fost introduse n C# pentru evitarea conflictelor de nume n j
utilizarea bibliotecilor de clase, dar i pentru organizarea i sistematizarea tipurilor |
de date. De exemplu, dac ntr-o aplicaie utilizai dou biblioteci neprotejate prin I
spaii de nume, care provin de la furnizori diferii, este posibil ca un acelai nume t
de clas, s-i spunem Button, s fie definit n ambele biblioteci, ceea ce ar crea o :
coliziune n program, inacceptabil de ctre compilator. 1
ntreaga^ B ib lio te c a de Clase .NET se gsete n interiorul acestor j
namespaces. n afara spaiilor de nume ale bibliotecii .NET Framework sau ale j
bibliotecilor altor furnizori, C# v permite s v creai propriile spaii de nume. Se s
definesc foarte simplu cu ajutorul cuvntului cheie namespace. j
Exemplu: I
I
namespace MySpace j
< 1
static void Main() j
{ i
} 1
I
I
Spaii de nume imbricate (nested) \
ntr-un spaiu de nume putei defini nu numai tipuri de date ci i alte spaii de }
nume. j
Exemplu: j
namespace X
< j
namespace Y i
{ j
> I
namespace Z j
< I
namespace W j
{ I
>
}
static void Main()
j
{ !
} j
C apitolul 3. F undam entele lim bajului Cir 49
E xem plu:
Cum vom accesa numele clasei B u t t o n ?
System.Windows.F o r m s .Button b =
new System.W i n d o w s .F o rms.B u t t o n ();
}
}
50 P artea I. L im bajul C#
using System.Windows.Forms;
Not:
Pentru ca programul de lapunctul b) s compileze, trebuie s aducei
proiectului de tip consol o referin,la spaiul de nume System. Windows.Forms ^
astfel: I
n S o lu tio n E xp lo re r, click dreapta pe numele proiectului.
Alegei A dd reference.
n tab-sheet- u l .N e talegei System.Windows.Forms i apsai OK.
A T E N IE ! I
O directiv u sin g nu v permite accesul la nici un spaiu de nume definit n
spaiul de nume pe care l specificai.
Exem plu:
using System;
namespace N1
t
namespace N2
{
namespace N3
{
public class C { }
}
1
}
using F = System.Windows.Forms;
Directive de p reprocesare
Directiva # d e fin e
Numele simbolice se definesc cu directiva #define, naintea oricrei
secvene de cod din program. Alte directive pot fi definite i n alte zone ale
programului.
Exemplu:
#define DEPANARE
// Cod neafectat de directiva #define
#if DEPANARE
// Cod care se compileaz dac este definit numele DEPANARE
#else
// Cod care se compileaz daca nu este definit DEPANARE
#endif f
II Cod neafectat de preprocesor
Directiva # u n d e fin e
Dac ntr-un punct n program dorii ca un anume identificator definit cu
#define s nu mai fie definit, deci s nu mai fie cunoscut de ctre preprocesor,
atunci folosii directiva #undef:
#define DEPANARE
#define MAXIM
#undef DEPANARE
#if DEPANARE
// Cod care NU se compileaz
#elif MAXIM
// Cod care compileaz pentru c nu e definit DEPANARE,
// dar este definit MAXIM
#endif
n trebri i exerciii
C apitolul 4
O biecte i clase \
i
j
Limbajul C# este un limbaj orientat-obiect. Limbajele orientate pe obiecte au .j
calitatea c permit programatorului s-i creeze noi tipuri complexe de date. ;i
Tipurile se obin prin definirea de clase. Clasele sunt baza programrii orientat pe j
obiecte. O clas reunete cod i date care descriu o anumit categorie de obiecte. \
Clasa este apoi folosit pentru construirea de obiecte. Crearea unui obiect se j
numete in sta n ie re . Obiectul creat se numete in sta n a clasei.
Diferena dintre un obiect i o clas este aceeai ca diferena ntre o pisic i t
descrierea unei pisici. Descrierea este clasa, iar pisica este obiectul. De altfel,
clasele i obiectele au aprut n programare tocmai din necesitatea de a modela j;
obiectele din realitate, dar i obiecte abstracte. !
O clas Pisica, specific trsturile care ne intereseaz ia o pisic: nume, |
ras, greutate, culoarea blnii, etc. De asemenea, clasa descrie aciunile pe care o 1
pisic le poate face: s sar, s zgrie, s toarc, etc. Pisica Kitty, rasa Birmanez, j
greutatea - 4 Kg, culoarea blnii - gri, este o instan a clasei, deci un obiect de tip j
Pisica.
Marele avantaj al claselor este c ncapsuleaz caracteristicile i
capabilitile obiectului ntr-o singur unitate de cod. O clas descrie complet
obiectele de tipul su, nemaifiind nevoie n acest scop de cod exterior clasei.
Mai trebuie s reinei urmtoarele: programarea orientat pe obiecte nu ;
este doar programare cu obiecte. ntre obiecte pot exista relaii, obiectele pot ;
comunica ntre ele, obiectele pot folosi alte obiecte. j
Capitolul 4. Program are O rientat pe O biecte n C# 55
1. Abstractizarea
Abstractizarea este simplificarea realitii prin modelarea unor clase care
pstreaz doar trsturile obiectului real care sunt eseniale i suficiente pentru
atingerea scopului propus. Membrii clasei (cmpuri, metode, etc.) definesc aceste
trsturi.
2. ncapsularea
Un obiect ncapsuleaz date i cod care acioneaz asupra acestor date.
Clasa ofer protecie membrilor si. Nu toi membrii clasei pot fi accesai din afara
ei. O regul important n OOP este aceea c datele membre trebuie s rmn
private, s fie inaccesibile din lumea exterioar clasei, pentru a prentmpina
modificrile accidentale. Partea accesibil a clasei o constituie membrii publici, de
regul metodele. Acetia pot fi utilizai de ctre poriuni din program care lucreaz
cu obiectele clasei. Membrii publici ai unei clase formeaz in te rfa a clasei.
3. Motenirea
Motenirea este mecanismul prin care un limbaj orientat-obiect v permite s
definii noi clase care incorporeaz i extind o clas deja definit. Noile clase se
numesc clase derivate. Ele motenesc atributele i comportamentul clasei pe care
o extind, fiind versiuni specializate ale clasei de baz. Clasa pe care o extindei se
numete clas de baz. Ca exemplu, s presupunem c dorii pentru aplicaia
dumneavoastr un buton care s aib funcionalitatea unui buton de apsare, dar
s aib n plus anumite proprieti: s fie rotund, s aib un mic punct luminos
central care clipete cnd este apsat, etc. Avei dou opiuni: s scriei o clas
care s ndeplineasc toate cerinele sau s scriei o clas MyButton, care s
moteneasc de pild clasa System.Windows .Forms .Button. A doua variant
este avantajoas, deoarece clasa MyButon motenete ntregul comportament i
caracteristicile unui buton obinuit i vei avea nevoie s adugai doar codul cerut
de cerinele suplimentare. R e u tiliz a re a c o d u lu i este unul dintre beneficiile
importante pe care le aduce motenirea.
4. Polimorfismul
n programarea orientat pe obiecte, polimorfismul (cuvnt care vine din
greac i care nsemn a avea mai multe forme") este caracteristica unei interfee
de a fi folosit cu aciuni multiple. O funcie sau un obiect au un comportament
polimorfic, dac acestea au mai mult de o singur form.
Polimorfismul, caracterizat de expresia interfa comun, aciuni multiple",
este deci capacitatea de a folosi n funcie de context, mai multe forme ale unui tip
sau metod, fr s ne intereseze detaliile de implementare.
Exist cteva tipuri de polimorfism. Unul dintre acestea se obine n OOP cu
ajutorul motenirii. S lum un exemplu din viaa real: Un dresor de circ are trei
animale : un arpe, un porumbel, i un tigru. Cnd vrea s cheme unul dintre ele,
i 56 Partea I. L im bajul C#
Clasele C#
n afara celor cincisprezece tipuri predefinite n C#, putei crea propriile tipuri i
de date (user-defined types). Exist ase categorii de tipuri pe care le putei crea:
1. Tipuri c la s s
2. Tipuri s tr u c t
3. Tipuri ta b lo u
4. Tipuri enum
5. Tipuri d e le g a te
6. Tipuri in te rfa c e
Definiie
Clasele sunt entiti logice care modeleaz obiecte din lumea real sau
obiecte abstracte. Clasele ncapsuleaz date i fu n c ii care opereaz cu aceste;
date. }
C m p u r ile (acestea sunt date m em bre) sunt v a ria b ile care reinl
informaii despre obiect.
M e to d e le sunt fu n c ii m e m b re ale clasei.
D e s tru c to ri
* O p e ra to ri
In d e x a to ri
> E v e n im e n te
Definirea c la s e lo r
0 clas se declar cu ajutorul cuvntului cheie class.
Sintaxa minimal:
class nume_clas
{
// Cmpuri
[modificator de acces] Tip nume;
// Metode
[modificator de acces] TipRetur NumeMetod(Parametri);
}
A trib u tu l D e s c rie re
public Acces nelimitat
private Acces limitat la propria clas
protected Acces limitat la propria clas i la clasele derivate
internal Acces limitat la programul care conine clasa
protected internal Acces limitat la program i la clasele derivate
Dac modificatorul de acces lipsete, atunci membrul respectiv este n mod implicit
private. Parantezele ptrate indic opionalitatea.
class X
(
// membrii clasei
}
X r = new X () ;
Exemplul 1:
class Program i
Clasa Program are ca membru doar metoda static Main(). Aceast metod
este punctul de intrare n program (entry point). Membrii statici ai unei clase exist
independent de obiectele clasei. Din acest motiv, Main () poate fi apelat de ctre
platforma .NET, fr s fie nevoie de un obiect de tip Program.
I
Exemplul 2:
class Test I
{
int x = 100; // Cmp privat
Exemplul 3:
using System;
class Test
f
private int x; // Cmp privat
// Metode publice
public int GetX()
{
return x;
}
Capitolul 4. P rogram are O rientat pe O biecte n C# 59
Ieire: 10
Programul de mai sus are dou clase. n clasa P r o g r a m , metoda M a i n ( ) ,
I creaz un obiect de tip T e s t , care mai apoi este utilizat pentru accesarea
I membrilor si publici,
i
f
| Metode. Parametrii metodelor.
t
I Metoda este un bloc de cod care poate fi apelat din diferite pri ale
| programului i chiar din alte programe. Cnd o metod este apelat, i execut
codul, apoi transfer controlul codului care a apelat-o. Metodele pot fi
implementate ca membri ai claselor sau ai structurilor sau ca prototipuri n interfee.
| Metodele pot s aib sau s nu aib parametri i pot s returneze sau nu valori.
| Dac nu returneaz valori, returneaz void. De asemenea, metodele pot fi s ta tice
| sau ne-statice.
I A TE N IE !
I Spre deosebire de C sau C++, n C# nu exist metode globale. Metodele nu
se pot declara n afara unui tip de date.
// codul metodei
| 1
Parametri valoare
n mod implicit, tipurile valoare sunt pasate metodelor p rin valoare. Aceasta
nseamn c atunci cnd un obiect de tip valoare este transmis ca argument unei
metode, o copie temporar a obiectului este creat de ctre metod pe stiv. Cnd
metoda i termin execuia, copiile temporare sunt distruse. n general avei
nevoie doar de valoarea argumentelor, ns sunt situaii cnd dorii s modificai
valoarea argumentelor. n acest caz, mecanismul transmiterii prin valoare nu v
ajut.
Exem plu:
using System;
class S
{
public void Schimba(int x, int y) // x, y - parametri
{ // formali
int aux; // x, y, aux - variabile locale
aux = x; x = y; y = aux;
)
}
class Test
{
static void Main()
{
S s = new S ();
int a = 10, b = 20; // a, b - variabile locale
*
/ / a , b - argumente pasate prin valoare ||
s.Schimbata, b ) ;
Console.WriteLine("a = {0}, b = {1}", a, b) ;
Programul afieaz: a = 1 0 , b = 20
Observm c a i b au rmas nemodificai n urma apelului, deoarece la 1
transmiterea prin valoare x i y sunt copii locale ale argum entelor a i b. |f
Argumentele nu trebuie s fie n mod obligatoriu variabile. Poate fi argument orice 1|
expresie care se evalueaz la tipul parametrului formal. jj
Parametri referin j
Dorim s modificm programul anterior, astfel nct valorile a i b s se jj
modifice dup apel. Se aplic modificatorul re f asupra parametrilor formali
j:
asupra parametrilor actuali astfel:
C apitolul 4. P rogram are O rientat pe O biecte n C# 61
Parametri de ieire
Parametri de ieire sunt utilizai pentru a transmite date din interiorul metodei
spre codul care a apelat-o. Nu conteaz valorile iniiale ale argumentelor, ci doar
cele finale.
Cerine:
> Trebuie utilizat modificatorul o u t att n definiie, ct i n apelul metodei.
> Este obligatoriu caargumentul transmis funciei trebuie sfie o variabil i
nu o expresie. Acestei variabile nu este nevoie s-i fie atribuit o valoare
nainte de a fi utilizat ca parametru actual.
Exemplu:
class OutP a r a m
{
public void Metoda(out int x)
{
// int y = x; // Eroare!
x = 100; // Iniializare nainte de
x++; // a se citi din variabila x
}
1
?
f
62 Partea I. L im bajul C#
class Program
{
static void Main(string[] args)
{
OutParam op = new OutParam) ;
int z; // Nu e nevoie de iniializare
op.Metoda(out z ) ;
System.Console.Write(z) ;
}
}
Parametri tablou j
Parametrii tablou (parameter array) admit zero sau mai muli parametrii
actuali pentru un acelai parametru formal. I
R e s tric ii:
Poate exista doar un singur parametru tablou n lista de parametri
formali.
Dac exist un parametru tablou, atunci acesta este ultimul n lista'
de parametri formali.
Pretinde modificatorul params n declaraie, dar nu este permis n
apelul metodei.
E x e m p lu :
class Params
{
public void Prin(params int[] x)
{
foreach (int i in x)
System.Console.W r i t e (i + " ");
System.Console.WriteLine() ;
Capitolul 4. P rogram are O rientat pe O biecte n C# 63
class Program
{
static void M a i n (string[] arg3)
{
Params p = new Params <);
p . P rint(1, 3); // n
p.Pr i n t (2, 4, 6, 8);
int{] a = { 10, 20, 30 };
// n
}
p .Print(a); // n
}
Ieire:
1 3
2 4 6 8
10 20 30
Invocarea metodei se poate face n dou moduri: o lista separat prin virgul cu
valori de tipul parametrului (*), sau un tablou de elemente (**).
O ultim observaie: n C# tablourile sunt tipuri referin, astfel nct
parametrii tablou sunt i ei referine.
S u p ran crcarea m e to d e lo r
Exemplu:
n clasa Overloading dorim s suprancrcm metoda: void F(int a) {}
class Overloading
{
void F(int a) { }
void F(char b) { } // Corect
void F(int a, char b) { } // Corect
void F(int a, int b) { } // Corect
using System;
class C
{
public const int H = 24;
}
class TestConst
{
static void Main(string[] args)
{
Console.Write(C.H);
}
}
De reinut:
Constantele trebuie iniializate la declarare.
Constantele membre se acceseaz la fel ca membrii s ta tic i:
NumeClas.NumeConstant.
Constructori
class Maina
{
public string marca; ,
public int pret;
} !
class Test
{
static void Main(string[] args)
{
Maina m = new Masina(); // Apelul constructorului '
}
}
using System;
class Maina
! t
public string marca;
; public int pret;
l public Maina(string m, int p) // Constructor
I <
marca = m;
i pret = p;
\ >
I i
class Test
ATENTIE
t !
i In momentul n care ai definit cel puin un constructor, compilatorul nu mai
sintetizeaz constructorul implicit. De aceea, dac dorii i unul fr parametri,
f trebuie s-l definii.
Exemplu:
.
f class Maina
| (
i public string marca;
: public int pret;
68 Partea I. L im bajul C#
public M a i n a () // 1
marca = "Fiat";
pret = 1000;
public Maina(string m) // 2
marca = m;
pret = 20000;
marca = "Ford";
pret = p;
marca = m;
pret = p;
1
}
Constructori de copiere
Dac dorii ca un obiect s fie creat ca o copie fidel a unui alt obiect, atunc
este convenabil s definii un constructor de copiere (copy constructor). C# ni
furnizeaz un constructor de copiere implicit, aa cum ofer un constructor de
instan implicit. De aceea va trebui s-l definii dumneavoastr.
Exemplu:
C apitolul 4. Program are O rientat pe O biecte n C# 69
using System;
c la s s C
{
private int x; // Cmp privat
class TestCopyCtor
{
static void Main(string[] args)
Din exemplu vedem c parametrul constructorului de copiere are tipul clasei, iar
argumentul de apel este un obiect ( c l) al clasei.
Cuvntul cheie t h i s
this este o referin la obiectul curent. Toate metodele nestatice ale clasei
posed aceast referin i au acces la ea.
Exemplificm utilizarea referinei this n urmtoarele circumstane:
1. Pentru rezolvarea ambiguitilor care apar cnd numele parametrilor
formali ai unei metode coincid cu numele altor membri.
2. Returnarea de ctre o metod a unei referine la obiectul curent.
using System;
class Copil
{
private string nume;
private int varsta;
70 P artea I. L im bajul C#
class Test_this
{
static void Main(string[] args)
{
Copil c = nex Copil("Alin", 17);
c.Afiseaza(); // Ieire: Alin 17
c.ModificVarsta(l);
c.Afiseaza(); // Ieire: Alin 18
)
>
Nu este eroare la compilare. Dar parametrul formal nume ascunde cmpul clasei]
astfel nct metoda nu acceseaz cmpul privat al clasei, ci realizeaz o inutil
autoatribuire a parametrului formal. Oricare membru al clasei poate fi accesat ri
metodele clasei astfel: this .membru. n acest fel, this.nume = nume
realizeaz o iniializare corect a cmpului nume.
Mai observm c metoda M odificVarstaO returneaz o referin ti
obiectul curent. Cine este de fapt obiectul curent ? Asta nu vom ti, pn r
momentul n care metoda este apelat: c.ModificVarsta(18); Prin urmare,
refer obiectul curent i this refer evident acelai obiect. De altfel, n momenti
apelului, this refer deja obiectul alocat cu new, pentru c c transfer n thi
referina ctre obiect.
Exist i alte situaii n care avei nevoie de t h i s , aa cum vom vedea m<
departe.
Capitolul 4. P rogram are O rientat pe O biecte n C# 71
Destructorul clasei
cl a s s A v i o n
{
// Membrii clasei
~Av i o n ( ) // D e s t r u c t o r
{
// Eliberarea resurselor gestionate de obiect
}
}
IMPORTANT
Destructorii au acelai nume cu cel al clasei, prefixat cu caracterul ~.
O clas poate avea un singur destructor.
Destructorii nu se apeleaz niciodat. Ei se invoc n mod automat.
Constructorii nu au parametri i nu accept modificatori.
n structuri nu se pot defini destructori.
Destructori nu pot fi suprancrcai.
Proprieti
using System;
clas3 C o p i l
{
private s t r i n g nume; // Cmpuri private
private int varsta;
72 P artea I. L im bajul C#
class TestProprietati
{
static void Main(string[] args)
{
Copil c = new Copil("Valentin , 18);
Console.WriteLine(c.Nume + " " + c.Varsta); // get
c.Nume = "Andrei"; // set
c.Varsta = 20; // set
Console.WriteLine(c.Nume + " " + c.Varsta); // get
}
)
Prototipul proprietii este format din tipul returnat de ctre proprietate (aici
string, respectiv int) i numele proprietii (Nume i Varsta). Tipul proprietii,
este tipul cmpului pe care II gestioneaz proprietatea.
Corpul proprietii conine doi accesori: get i set. Unul din ei poate s lipseasc.
g e t are urmtoarele caracteristici:
v' Nu are parametri
v' Are tip de retur de acelai tip cu al proprietii.
Accesorii pot fi declari n orice ordine. Nici o alt metod n afar de get i set nu
poate exista n corpul proprietii. Accesorii se apeleaz n mod implicit.
Exemplu: t
n set putei plasa orice cod defensiv de protecie a cmpului asociat
proprietii:
using System;
class ntreg
{
private int n; // Cmp privat
public int N
get ( return n; } 1
set
{ // Cod care protejeaz n de aciuni nedorite
if {value > 1000) n = 1000;
else
if (value < 0) n = 0;
else n = value;
}
class Test
{
static void Main(string[] args)
{
ntreg i = new ntreg();
i.N = 1200; // set
Console.Write(i.N + " "); // get
i.N = -10; // set
Console.Write(i.N); // get
}
}
Ieire: 1000 0
Proprieti statice
Proprietile se pot declara static. Procedai astfel cnd dorii s le
asociai unor cmpuri statice. Proprietile statice nu pot accesa ali membrii ai
clasei, dect pe cei statici i exista independent de existena instanelor clasei. Se
acceseaz prin numele clasei, la fel ca ali membri statici.
C apitolul 4. Program are O rientat pe O biecte n C# 75
Exemplu:
class Numr
{
private static int nr; // Cmp static
public static int Nr // Proprietate static
t
get { return nr; }
set { nr = value; }
}
)
class TestConst
{
static void Main(string[] args)
{
Numr.Nr = 1 0 0 ; // set
System.Console.Write(Numr.Nr); // get
)
}
Convenie de notare
Pentru claritate, se obinuiete ca numele proprietii s fie acelai cu cel al
cmpului privat asociat. Diferena este c n timp ce cmpul ncepe cu liter mic,
proprietatea ncepe cu liter mare. Sfatul nostru este s urmai aceast convenie.
E xem plu:
using System;
class X
{
public int Valoare // Proprietate
{ // implementat
get; set; / / I n mod automat
}
>
76 Partea I. L im bajul C#
class TestAutoPropertie
{
static void Main(string[] args)
{
X x = new X ( ) ;
x.Valoare = 1 0 ; // set
Console.Write(x.Valoare); // get
}
}
Restriciile proprietilor
Proprietile nu definesc o locaie de memorie. Din acest motiv, nu pot fi
transmise cu modificatorii o u t sau r e f .
Nu pot fi suprancrcate.
Indexatori
Indexatorii permit instanelor unei clase sau ale unei structuri s fie indexate, i
la fel ca elementele unui tablou. Indexatorii i proprietile sunt similari din mai
multe puncte de vedere:
Sintax asemntoare.
Pot avea unul sau doi accesori.
Nu definesc o locaie de memorie.
Codul accesorilor poate s fie asociat sau s nu fie cu un cmp al
clasei.
Exist i diferene:
O proprietate acceseaz de regul un singur cmp privat, n timp ce
un indexator poate accesa mai muli membrii ai clasei.
Numele unui indexator este ntotdeauna this.
Un indexator este ntotdeauna un membru de instan. Din aceast^
cauz nu poate fi declarat static.
Sintax:
T i p R e t u r n a t this[int i n d e x ] -
{
get
{
/ / S e returneaz valoarea precizat prin index
>
set
Exemplu:
using System;
class Tablou
{
private int[] a; // Tablou coninut - Cmp privat
private int n; // Dimensiunea tabloului
private const int MAX = 1000;
class Testlndexer
<
static void Main(string[] args)
{
Tablou t = new T a b l o u (100);
for (int i = 0; i < 10; i++)
t[i] = i; // set
t[-l] = 10; // set
78 Partea I. Limbajul C#
Ieire:
10 1 2 3 4 5 6 7 8 9
Operatori de conversie
H
n capitolul 3, paragraful Conversii ntre tipuri, am vzut c ntre tipurile:
predefinite se pot face conversii implicite sau explicite. Conversiile explicite s e j
realizeaz cu ajutorului operatorului ( ) . 1
Exemplu:
double x = 2.3;
int y = 6;
x *> y; // Conversie implicii s
y = (double)x; // Converise explicii
i
C# v permite s definii un tip special de operatori n clase i structuri, care
realizeaz conversii implicite sau explicite ntre tipul clasei sau a structurii i alta
tipuri predefinite sau tipuri clas* sau struct. -i
Operatorii de conversie sunt metode statice, introduse cu cuvntul cheie
operator.
Sintax:
public static explicit operator T i p l (Tip2 t)
sau
Tipl este tipul spre care se face conversia. Tip2 este tipul care se convertete
spre Tipl. Unul dintre cefe dou tipuri trebuie s fie de tipul clasei sau structurii
care conine operatorul de conversie.
Exemplul 1:
Definim doi operatori care realizeaz conversii explicite de la tipul
Bancnota spre int i de la lnt spre tipul Bancnota:
// conversii_explicite.cs
using System;
claas Bancnota
{
private int valoare;
d a s s TestConversieExplicita
{
static void Main()
{
int val 100;
Bancnota b * (Bancnota)val; // Conversie explicit
Console.WriteLine ((int)b); // Conversie explcit
)
80 Partea I. Limbajul C#
Exemplul 2:
Modificm programul anterior, astfel nct s obinem operatori de conversii
implicite:
// conversii_implicite.cs
using System;
class Bancnota
{
private int valoare;
Clase interioare
O clas interioar (inner class sau nested class) este o clas a crei definiie]
se gsete n interiorul definiiei altei clase.
Exemplu:
using System;
class TestlnnerClass
{
static void Main{)
{
A.B obj = new A.B(); // Creeaz un obiect de tip B
obj.F(); // Afieaz: F();
}
)
2. Metodele clasei interioare pot accesa toi membrii clasei care o conine, prin
intermediul operatorului ' . ' :
Exemplu:
using System;
Coninere
Cnd o clas are ca membri unul sau mai multe obiecte de tip clas, vorbim
despre conpnara (containment) sau compozlpa.
Tn figur, ilustrm clasa Calculator. Un
calculator are mai multe componente. Acestea sunt Calculator
instane ale altor clase : Monitor, Tastatura,
Mouse i UnitateCentrala. Monitor
Tastatur
Mouse
Unitate central
Exemplu:
Programul de mai jos definete trei clase:
Motor, Caroserie, Maina. Clasa Maina are ca
Figura 4.1 Coninere '
membri privai cte o referin spre obiecte de tip
Motor i Caroserie.
class Maina
{
private string marca;
// Maina ARE O caroserie c i ARE KW motor m
private Caroserie c;
private Motor m;
// Constructorul clasei
public Maina(Caroserie c, Motor m, string marca)
{
this.c = c;
this.m = m;-
this.marca - marca;
)
Capitolul 4. Programare Orientat pe Obiecte n C# 83
class TastContinaro
{
public static void Main()
i
Caroseria C nev Caroseria();
Motor M naw Motor();
Maina mea * naw Maina(C, M, "Volvo");
1
1
Clase pariale
partial class A
{
public void F{)
{
System.Console.Write ("F() ");
}
}
partial class A
{
public void 6()
{
System.Console.WriteLine("G()") ;
}
}
Ieirea programului: F () G ()
84 Partea I. Limbajul C#
Practic, este vorba despre o singur clas cu numele A, a crei definiie a fost
fragmentat. Compilatorul unific definiiile pariale i instaniaz n mod corect
obiectul a de tip A.
Mediul Visual C# 2008 genereaz n mod curent asemenea definiii pariale.
Dac creai un proiect de tip Windows Forms, vei constata c definiia de clas a
formei principale, s-i spunem Forml, este fragmentat n dou fiiere diferite:
Form1.cs i Forml.Designer.cs.
Clase sigilate
sealed este un cuvnt cheie. Cnd modificatorul sealed este aplicat unei
clase, are efectul de a mpiedica alte clase s o moteneasc.
Exemplu:
sealed clasa A { / * . . . * / )
Suprancrcarea operatorilor
Toi operatorii unari i binari au implementri predefinite care sunt
disponibile n orice expresie n care sunt implicate tipuri predefinite. C# v permite
s redefinii semnificaia unui operator standard, astfel nct operatorul respectiv s
poat fi aplicat instanelor clasei voastre, tn acest fel sporii funcionalitatea
claselor.
Ce nelegem prin suprancrcarea operatorilor (operator overloading)? Este
un mecanism prin care instanele clasei pot fi integrate n expresii aritmetice sau
logice n calitate de operanzi, cu utilizarea operatorilor specifici tipurilor predefinite:
+, *, / , <, >, etc. Cnd definii o metod de tip operator, de exemplu pentru
operaia de adunare, atunci spunem c am suprancrcat operatorul +".
S presupunem c avem o clas care descrie o fracie i dorim s efectuam
operaii cu instane de tip Fracie, n felul acesta:
Sintaxa
n cazul operatorilor binari:
I I fracie.cs
using System;
Fracie c a + b; // operatort
Console.WriteLine("c = a + b = {0}",
c.ToString());
Fracie d = new Fracie(2, 4);
if (d = b) //operator==
Console.WriteLine("d = b = {0}", d) ;
if (a H b) //operator!
Console.WriteLine(a + " != " + b);
a += b; // operator +3=
Capitolul 4. Programare Orientat pe Obiecte n C# 87
Console.WriteLine("a = " + a ) ;
}
}
Ieire:
a = 3/4
b * 1/2
e = a + b * 5/4
d = b = 1/2
3/4 != 1/2
a = 5/4
De reinut:
> Operatorul de atribuire = nu se suprancarc. El este furnizat n mod
implicit de ctre compilator (e * a + b).
> Operatorii unari au un parametru, iar cei binari doi parametri: n ambele
cazuri, cel puin unul dintre operanzi trebuie s fie de tipul clasei sau al
structurii.
> Operatorii unari au un singur parametru.
> C# pretinde ca n situaia n care suprancrcai = atunci trebuie s
suprancrcai i !=. Similar, operatorii < i > trebuie suprancrcai n
perechi, la fel ca i <= cu >=.
> Dac suprancrcai operatorul +, atunci C# sintetizeaz automat +=.
Aceeai regul este valabil i pentru + cu +=, * cu *= , etc.
Metoda ToString()
n clasa Fracie, am definit metoda ToStringO . De fapt, am redefinit
pentru Fracie, aceast funcie. ToStringO este o metod a clasei object,
clasa de baz a tuturor claselor. Rolul ei este de a retuma o reprezentare a
obiectului clasei ntr-un obiect de tip string. De cte ori dorii o conversie
particular spre string a obiectelor clasei, redefinii aceast metod motenit.
Pentru aceasta folosii cuvntul cheie overrida. Observai c metoda
ToStringO se apeleaz n mod implicit atunci cnd transferai obiectul ntr-un
context n care se cere un string: apelul Console .WriteLine ("a = + a);
pune a ntr-un context n care se ateapt un string, deci a se convertete la
string prin apelul implicit al metodei ToStringO
using System;
private int n;
public ntreg(int i) // Constructor
1 ;
}
// Operatorul de incrementare
public static ntreg operator + + (ntreg x)
{
return new ntreg(++x.n);
>
// Operatorul unar -
public static ntreg operator - (ntreg x)
{
return new ntreg(--x.n) ;
}
public override string ToStringO
{
String s = string.Format("{0}1 n) ;
return s;
m
}
NOTA:
Nu este nevoie s creai dou versiuni diferite ale operatorului ++ ca_
suporte incrementare prefixat i sufixat. O singur versiune este suficient,
compilatorul are grij s implementeze diferenierea ntre prefixare i sufixare.
IMPORTANT
Este recomandabil s nu modificai operanzii pasai m etodelor o p e ra to ri
loc de aceasta, creai noi instane de tipul valoni de retur i returnai ace|
instane. Urmnd aceast practic, vei evita probleme la depanare.
| Operatori relaionali: = cu !=, < cu >, <= cu >= (acetia trebuie suprancrcai n
perechi).
> Crearea unui nou operator (se pot suprancrca doar operatori predefinii).
> Schimbarea sintaxei unui operator.
> Redefinirea modului de lucru a unui operator cu tipuri predefinite.
> Schimbarea precedenei sau asociativitii unui operator.
Structuri
iSintaxa:
{M o d i f i c a t o r A c c e s ] struct N um eStcuctur
// membrii structurii
a
xemplu:
sing System;
truct Punct
private double x;
private double y;
set { x = v a l u e ; }
}
public double Y // Proprietatea Y
1
get { return y; }
set ( y = value; }
}
}
class Teststruct
{
static void Main(string[] args)
{
Punct pi = new P u n c t (2.3, 3.5);
Console.Write("x = {0}, y = {1}", pl.X, pl.Y);
)
)
Structurile sunt recomandabile pentru obiecte mici, aa cum este un obiect de tip
Punct, care trebuie instantiate n numr mare, eventual ntr-o bucl. Pentru c
sunt tipuri valoare, se construiesc pe stiva programului, care se acceseaz mai
rapid dect memoria Heap.
Interfee
i
Sintaxa minimal:
[ m o d i f i c a t o r i ] interface N u m e l n t e r f a
{
// Corpul interfeei
}
interface II { /*...*/ }
interface 12 { /*...*/ }
class C : II, 12
{ /*...*/ }
Exemplu:
using System;
interface IPrintable
{
void Prin(string s) ;
}
Ie ire :
Prietenilor mei Salut!
M otenire
Motenirea este unul dintre cele mai importante i mai puternice concepte n
Programarea Orientat pe Obiecte. Motenirea v permite s definii o nou clas
care incorporeaz i extinde o clas existent.
Diagrama de mai jos prezint o ierarhie de clase bazat pe motenire. Un
animal este o fiin, un om este o fiin, un cine este un animal, un brbat este
om, .a.m.d. Vom generaliza cu afirmaia urmtoare:
Specializare i generalizare
Una dintre cele mai importante relaii ntre obiecte n lumea real este
specializarea, care poate fi descris ca o relaie /S A. Cnd spunem c un cine
esfe un animal, ne gndim de fapt c un cine este un tip specializat de animal.
Cinele este un animal pentru c are toate caracteristicile unui animal, dar
specializeaz aceste caracteristici conform speciei sale. O pisic esfe un animal,
deci are n comun cu cinele caracteriscticile animalelor (ochi, gur, etc) dar difer
fa de un cine prin caracteristici specifice pisicilor.
Pe de alt parte, tipul Animal, generalizeaz tipurile Pisic i Cine.
Aceste relaii sunt ierarhice. Ele formeaz un arbore. Urcnd n arbore,
generalizm; cobornd, specializm.
C apitolul 4. Program are O rientat pe O biecte n C # 93
Implementarea motenirii
IMPORTANT
n C# toate clasele sunt clase derivate. Oricare clas deriv n mod direct
sau indirect din clasa object. Dac o clas nu specific n mod explicit
derivarea dintr-o alt clas, atunci ea motenete direct clasa object. In felul
acesta, object este baza tuturor ierarhiilor de clase.
Exemplu:
Cele dou declarri ale clasei Avion specific acelai lucru: faptul c Avion
deriv din object:
// Corect // Incorect
class A : B, II, 12, 13 class A : II, B, 12, 13
{ {
1 }
// Incorect n C#
class A : B, C, D
{
}
// Corect
class C :D { }
class B :C { }
class A :B { }
using System;
Ieire:
Animalul se hrnete
Pisica toarce
using System;
class Baza
{
p ubl i c B a z a ()
{
Console.WriteLine("Constructor B a z a " ) ;
}
)
class D e r i v a t : Baza
{
pub l i c D e r i v a t ()
{
Console.Wri t eLine("Constructor Derivat");
}
}
public class Te s t C o n s t r u c t o r
{
static v o i d Main()
{
Derivat d;
d = n e w Derivat(); // Apelul constructorului clasei
} // derivate
1
Ieire:
Constructor Baz a
Constructor D e r i v a t
Dac constructorul bazei are parametri, atunci apelul implicit nu poate avea loc.
Constructorul derivat trebuie s invoce n mod explicit constructorul bazei,
fumizndu-i i argumentele corespunztoare:
Exemplu:
using System;
class Baza
t
private int x;
public Baza(int y)
{
x = y;
}
}
Membrii ascuni
Dac n clasa derivat avei un cmp cu acelai nume cu al unuia din clasa
de baz, sau avei o metod cu aceeai signatur (acelai nume i aceeai list de
parametri formali) cu a uneia din clasa de baz, atunci numele membrilor din clasa
de baz sunt ascunse metodelor clasei derivate. Pentru a accesa membrii ascuni
ai bazei, se ntrebuineaz new n faa membrilor bazei i cuvntul cheie base,
pentru accesarea membrilor ascuni.
Exemplu:
using System;
class Baza
{
public int camp = 10;
public void M e t o d a ()
{
Console.WriteLine("Baza.MetodaO");
}
>
Ieire:
B a za .M e to d a ()
| Derivat.Metoda() 10
| Baza.Metoda ()
I
100 Partea I. L im bajul C#
P o lim orfism
Conversia referinelor
Dac avei o referin la un obiect al clasei derivate, putei obine o referina
la partea de baz a obiectului, folosind operatorul de conversie () ca mai jos:
class Baza
{
public void M e t o d a ()
{
System.Console.WriteLine("Baza.Metoda()");
}
}
// XJpcast
Baza b = (Baza)d;
b.Metoda ();
}
}
Ieire:
Derivat.M e t o d a ()
Baza.Metoda()
C apitolul 4. Program are O rientat pe O biecte n C# 101
Se constat c referina la
partea de baz a obiectului nu
poate vedea" restul obiectului
clasei derivate, deoarece
privete printr-o referin b la
clasa de baz. Prin b vei
putea s invocai numai
Metoda () clasei de baz.
Metode virtuale
n paragraful anterior am artat c ntr-o clas derivat putei defini o metod
cu acelai prototip cu al unei metode din clasa de baz, dar c o referin la un
obiect de tipul clasei de baz nu poate invoca noua metod definit cu new.
Pentru ca o referin la un obiect al bazei s poat accesa membri ai
obiectelor derivate, altfel spus, pentru a obine polimorfism bazat pe motenire,
este nevoie de urmtoarele:
> Clasa de baz declar acel membru virtual.
> Clasa derivat redefinete acel membru, cu exact aceeai semntur i tip
de retur, adugnd cuvntul cheie override, naintea tipului de retur.
Exemplu:
using System;
namespace Polimorfism
{
class Baza
{
virtual public void M e t o d a ()
{
Console.WriteLine("Metoda() din Baza");
}
}
class Derivat : Baza
{
override public void M e t o d a ()
{
Console.WriteLine("Metoda() din Derivat");
}
}
class TestPolimorfism
{
static void Main(string[] args)
102 P artea I. L im b aju l C #
{
Derivat d = new Der iv a t ();
d.Metoda(); // Ieire: " Met o d a Q din Derivat"
// Polimorfism
Baza b = new B a z a ();
b . M e t o d a (); // Ieire: " Met o d a O din Baza"
b = new D e r i v a t ();
b.Metoda{) ; // Ieire: "MetodaO din Derivat"
}
}
}
using System;
class A
{
.virtual public void F()
{ Console.WriteLine("FO din A"); }
>
class Test
{
static voi d Main(string[] args)
{
A a = new B{) ; // a refer un obiect de tip B
a.F() ; // Ieire: "F( ) din A"
a = new C () ; // a refer un obiect de tip c
a . F () ; // Ieire: "'F() din C"
a = new D () ; // a refer un obiect de tip D
a.F() ; / / Ieire: "' FO din C"1
}
}
C apitolul 4. P rogram are O rientat pe O biecte n C # 103
Dac o referin de tipul ciasei de baz refer un obiect de tip derivat i prin acea
referin invocai o metod virtual, atunci se apeleaz cea mai apropiat metod
override definit pe lanul ierarhic. Dac nu exist metode redefinite, atunci se
invoc metoda virtual din clasa de baz.
Restricii
Reinem urmtoarele aspecte:
Se pot declara virtual urmtorii membri: metode, proprieti,
evenimente i indexatori.
Cmpurile nu pot fi declarate v i r t u a l .
Metodele redefinite cu override trebuie s aib acelai nivel de
accesibiliate cu metodele virtuale corespunztoare. De exemplu nu este
corect ca o metod virtual declarat public s fie redefinit cu o
metod declarat private.
Nu se pot redefini metodele non-virtuale.
Nu pot fi redefini metodele statice.
Modificatorul sealed
Aplicat unei clase, modificatorul sealed mpiedic alte clase s o
moteneasc, sealed poate fi aplicat i unei metode sau unei proprieti care
redefinete o metod sau o proprietate a clasei de baz. n aceast situaie, se
permite altor clase s moteneasc clasa care are un membru sealed, dar
metoda sau proprietatea sealed nu mai poate fi redefinit n clasele derivate.
Exemplu:
class A
1
protected virtual void F() { /*...*/ }
protected virtual void G{) { /*...*/}
}
class B : A
{
sealed protected override void F() { / * . . . * / }
protected override void G() { /*...*/ }
}
class D : B // Corect. B poate fi motenit
{
protected override void F() { /*...*/ } // Eroare !
protected override void G() { /*...*/ } // Corect
}
Cnd se aplic unei metode sau unei proprieti, modificatorul sealed trebuie s
fie folosit ntotdeauna cu override.
104 P artea I. L im bajul C# C apitolul 4. Program are O rientat pe O biecte n C# 105
Utilitatea polimorfismului Tabloul LimbaVorbita reine referine ale unor obiecte de tipuri diferite, dar care
n practic se opereaz deseori cu colecii de obiecte. Mai precis, cu colecii sunt legate prin relaie de motenire, avnd ca baz a ierarhiei clasa
de referine la obiecte. Dac obiectele sunt legate printr-o relaie de motenire LimbaVorbita. Dac relaia de motenire nu ar exista, atunci referinele ar fi
avnd o clas de baz comun, atunci nu trebuie ca ele s fie de acelai tip- Dac trebuit s fie de acelai tip. Programul implementeaz polimorfismul. Interfaa de
toate obiectele redefinesc o metod virtual a clasei de baz, atunci putei invoca apelare unic ( lv.SeVorbeste) ) care se utilizeaz pentru fiecare obiect, duce
aceast metod pentru fiecare obiect. la aciuni specifice, n funcie de obiectul referit.
using System;
class LimbaVorbita // Clasa de baz
R ezu m a tu l c a p ito lu lu i
virtual public void SeVorbeste) { } // nu va fi invocat
Clasele sunt entiti logice care modeleaz obiecte din lumea real sau
obiecte abstracte. Clasele ncapsuleaz date i metode care opereaz cu
class Engleza : LimbaVorbita aceste date.
Constructorii unei clase sunt metode speciale care au rolul de a creea, a
override public void SeVorbeste)
construi obiecte.
{ Console.WriteLine("Engleza"); }
* Destructorul clasei este o metod special care distruge instanele
claselor.
class Franceza : LimbaVorbita
Proprietile sunt membri ai clasei cu ajutorul crora se acceseaz
override public void SeVorbeste() cmpurile private ca i cnd ar fi fost declarate public,.fr ca prin aceasta
{ Console.WriteLine("Franceza"); } : s se ncalce principiul proteciei datelor.
Suprancrcarea operatorilor este mecanismul prin care instanele clasei
class Spaniola : LimbaVorbita pot fi integrate n expresii aritmetice sau logice n calitate de operanzi, cu
utilizarea operatorilor specifici tipurilor predefinite: +, * , / , <, >, etc.
override public void SeVorbeste) Motenirea este mecanismul care permite s s se defineasc o nou
{ Console.WriteLine("Spaniola"); ) clas care incorporeaz i extinde o clas existent.
* Polimorfismul este caracteristica unei variabile referin de a putea referi
lass Catalana : Spaniola obiecte de tipuri diferite. C# admite polimorfism bazat pe relaia de
motenire.
override public void SeVorbeste)
{ Console.WriteLine("Catalana"); }
n treb ri i ex erc iii
class Test 1. Care este diferena dintre un obiect i o clas ? Dar dintre o referin i un
obiect ?
static void Main(string[] args) 2. Indicai principalele deosebiri care exist ntre membrii statici i cei nestatici
{ ai unei clase.
LimbaVorbita[] L = new LimbaVorbita[4]; 3. Ce relaie se modeleaz ia motenire ? Dar la coninere ?
L [0] = new Engleza); L[l] = new Franceza); 4. Implementai o clas cu numele Persoana i o a doua clas cu numele
L [2] = new Spaniola); L[3] = new Catalana);
E le v . Clasele trebuie s aib constructori, cmpuri private i proprieti.
5. Scriei o clas cu numele BigNumber care implementeaz operaii cu
foreach (LimbaVorbita lv in L)
lv.SeVorbeste(); numere mari. Suprancrcai cel puin operatorii de adunare, scdere i
nmulire.
}
}
Ieire:
Engleza
Franceza
Spaniola
Catalana
106 P artea I. L im bajul C#
C apitolul 5
D eleg ri
Declarare !
r
O delegare este un tip, aa cum i clasele sunt tipuri. Un tip delegare f
trebuie declarat nainte de crearea obiectelor de tipul su. Declararea este creat f
cu cuvntul cheie delegate, urmat de tipul de retur i de signatura metodelor pe j
care delegarea le accept. *
Exem plu:
d e l e g a t e v o i d D e l e g a r e a M e a ( i n t x) ;
D e l e g a r e a M e a d;
j
s
'
O biectele de tip delegare se creeaz n dou moduri :
' l'
1. Cu sintaxa specific instanierii obiectelor:
C apitolul 5, Trsturi eseniale ale lim bajului CU 107
d = new DelegareaMea(ReferinObiect.Metod) ;
sau
d = new DelegareaMea(NumeCXas.MetodStatic) ;
d = R e fe rz n O b ie c t.M e to d ;
sau
d = N v m e C la s .M e to d S ta tic ;
using System;
class Simplu
{
// Metod de instan care potrivete delegrii
public void F (string s)
{
Console.WriteLine(S + "F() " ) ;
}
// Metod static care potrivete delegrii
public static void G(string s)
{
Console.WriteLine(s + "G() ");
)
}
class Program
{
static void Main()
{
Del d; // Declar o referina de tip Del
Simplu s = new Simplu();
Ieire:
Prima invocare: F ()
Prima invocare: G()
Prima invocare: G()
A doua invocare: G ()
A doua invocare: G ()
Exemplul anterior descrie modul n care putei atribui o metod listei de invocare a
delegrii, cu operatorul de atribuire =, apoi putei aduga sau elimina alte metode
cu acelai prototip cu operatorii += sau -= .
using System;
class Test
{
private int x = 0;
// Metode cu acelai prototip cu al delegrii
public int F ()
{
x += 2;
return x;
}
public int G ()
{
x + = 6;
return x;
class Program
{
C apitolul 5. Trsturi eseniale ale lim b a ju lu i C # 109
Evenim ente
Lucrul cu evenimente
II event.cs
using System;
// Clase Subscriber
class A
{
public void HandlerA()
1
Console.WriteLine("Obiect A, notificat la {0}",
DateTime.Now);
}
)
class B
{
public void HandlerB()
1
Console.WriteLine("Obiect B, notificat la {0}",
DateTime.Now);
>
}
class Test
{
static void Main()
{
Publisher p = new Publisher();
// Obiectele a si b vor fi notificate la declanarea
// unui eveniment
A a = new A ();
B b = new B ();
IMPORTANT________________________
nregistrarea metodelor ataate unui eveniment se face cu operatorul +=,
iar ndeprtarea lo r din lista de invocare, se face cu -= .
s e n d e r este o referin la object, deci poate referi obiecte de orice tip, inclusiv
Publisher. n apelul eveniment (this, ev) ; argumentele sunt: referina this
la obiectul de tip Publisher i referina ev la un obiect de tip MyEventArgs.
using System;
// Clase S u b s c r i b e r
114 P artea I. L im bajul C#
class A
1
public void HandlerA(object sender, MyEventArgs e)
{
Console.WriteLine{"Obiect A, notificat la (0}",
e .Momentul) ;
}
)
class B
{
public void HandlerB(object sender, MyEventArgs e)
{
Console.WriteLine("Obiect B, notificat la {0}",
e.Momentul) ;
}
}
class Test
{
static void Main()
{
Publisher m = new Publisher();
A a = new A(); // Obiectele a si b vor fi notificate
B b = new B(); // la apariia evenimentului
m.Declanseaza();
}
}
De retinut:
Dac vrei s scriei cod eficient, vei trata evenimentele folosind clasele de
baz E ve n tH a n d le r i E ventA rgs, iar delegrile vor avea prototipul compatibil
.NET, chiar dac C# admite orice model delegat.
G enerice
OOP ncapsuleaz n acelai obiect date care reflect starea obiectului, mpreun
cu metode care descriu capabilitile lui, scopul programrii generice este scrierea
de cod care s fie independent de tipurile de date.
Clase generice
public int P o p ()
{ return a[ n]; }
}
// stiva_generic.cs
using System;
Ieire:
6 4 2
Alin Ionel Marcel
using System;
Ieire:
Alin 18
1 2
2.3 F
Metode generice
Toate metodele unei clase generice sunt la rndul lor generice, deoarece pot
utiliza parametrii generici ai clasei. n afara genericitii implicite, putei defini
metode cu proprii parametri generici, care nu depind de cei ai clasei.
Exemplu:
using System;
this.u = u;
1
// Metoda generic - are proprii parametri generici
public void F<V1, V2><V1 a, V2 b)
{
Co n s o l e .WriteLine(a.ToString() + " " + u . T oStringO +
" " + b.ToString());
}
}
Ieire:
S traiti 104 ani!
Iulia F 8
C olecii
t
Platforma .Net conine clase specializate pentru depozitarea datelor.
Aceste clase implementeaz stive, cozi, liste, tabele de dispersie (hash-tables).
Coleciile non-generice sunt definite n spaiul de nume System.Collections.
Coleciile generice se definesc n System.Collections.Generic.
'^ ^ 'r f - j n w * "''
using System;
using System.Collections. Generic;
class StivaGenerica
1
public static void Main()
{
// Declar o stiv vid cu elemente de tip string
Stack<string> st = new Stack<string>();
Ieire:
N r . de elemente: 4
PATRU
jiHfWM'Oi
TREI
120 P artea I. L im bajul C #
DOI
UNU
Scoate 'PATRU'
Vrful stivei: 3
using System;
using System.Collections.Generic;
// Parcurge colecia
foreach (string c in copii)
Console.Write(c + " " );
Console.WriteLine("\nNr. copii: (0)", copii.Count);
Console.WriteLine("\n\nSterge \"Nelutu\":");
copii.R e m o v e ("Nelutu");
Ieire:
Ionel Radu Viorel Adisor Nelutu
Nr. copii: 5
Viorel exista ? true
Sorteaza alfabetic:
Adisor Alin Ionel Nelutu Radu Viorel
terge "Nelutu :
Adisor Alin Ionel Radu Viorel
Clasa este echivalentul clasei map din STL, C++. Realizeaz o mapare, o
coresponden biunivoc ntre o mulime de chei i o mulime de valori. Cheile sunt
unice, n sensul c nu pot exista mai multe chei identice n dicionar. Fiecrei chei i
corespunde o singur valoare asociat.
Clasa ofer metode care implementeaz operaii rapide de inserare a
perechilor cheie-valoare, de tergere i de cutare a valorii dup cheia asociat. n
dicionar, perechile cheie-valoare sunt ncapsulate n obiecte de tip
KeyValuePair.
Exemplu:
uslng System;
using System.Collections.Generic;
122 P artea I. L im bajul C#
Ieire:
Cheia Vlad are valoarea: 213048
Cheia Vlad are valoarea: 215773
C apitolul 5. T rsturi eseniale ale lim b a ju lu i C# 123
Ionescu 209791
Pop 232145
Vlad 215773
Cazacu 219465
Dragnea 279950
Simion 200371
Tratarea ex ce p iilo r
try
{
// Cod care poate arunca excepii
1
catch(System.Execption e)
{
// Cod care trateaz excepia
1
finally
{
// Cod care se execut dup try-catch indiferent
// dac se arunc sau nu execepii
Exemplu:
using System;
class TestExceptii
jjfe
I P artea I. L im bajul C#
124
Console.WriteLine(a[4]);
catch (Exception e)
>
Ieire:
Excepie!
System.IndexOutOfRangeException: Index was outside the bounds
of the array at TestExceptii.Main() in c:\teste\Program.cs:
line 7
i
Blocul catch declar o variabil de tip execpie (e) care poate fi utilizat pentru a
obine informaii suplimentare. Codul din blocul finally se execut indiferent
dac se arunc sau nu o excepie n blocul try, permind programului s
fj-T elibereze resursele (fiiere deschise, memorie alocat, etc.). Dac excepia se
ul
produce, atunci blocul finally se execut dup catch. &
iii Blocul finally poate s lipseasc. Pentru acelai bloc try, se pot declara mai
Ts-
it
multe blocuri catch, fiecare dintre ele, preciznd o posibil excepie care se poate I
lansa din try.
4 Hi
Tipul string n C# este un alias pentru clasa System, string din .Net
Framework. Este un tip referin. Obiectele de tip string ncapsuleaz un ir de
caractere n format Unicode. Stringurile sunt imutabile. Odat creat, un obiect de
tip string nu mai poate fi schimbat; toate operaiile care modific un string
returneaz un alt string modificat.
ii-
ini
0:-
C apitolul 5. Trsturi eseniale ale lim bajului C# 125
Operaii i metode
string definete operatorii relaionali =, != i operatorii de concatenare +,
+=. Definete de asemenea mai muite metode utile. Vom exemplifica utilizarea
ctorva dintre ele.
using System;
class TestString
{
public static void Main()
{
string sl = "Salut", s2 = "salut ;
if (sl != s2) // Compar stringurile, nu obiectele
Console.WriteLine("sl != s2") ;
if ( sl.ToUpper) = s2.ToUpper() )
Console.WriteLine(sl.ToUpper()); //Afieaz SALUT
Formatarea stringurilor
Pentru formatarea stringurilor exist n clasa string metodele statice
Format (), suprancrcate.
Exem plu:
using System;
class TestString
1
public static void Main()
x
int x = 123; double y = 23.4589;
string s = String.Format("x = {0}, y = {1}", x, y) ;
Console.WriteLine(s); // Afieaz: 123 23.4589
}
}
Mai sus, { 0 } se refer la primul obiect (x) din lista de parametri, iar { 1 } identific
cel de-al doilea obiect (y).
126 P artea I. L im bajul C#
E x e m p lu :
Afieaz:
x = 1.233E+002
y = 23.46
E x e m p lu :
double x = 23.4589;
Console.WriteLine("|x = {0,10:F2}|", x) ;
Console.WriteLine("|x = {0,-10:F 2 } |", x ) ;
A fi e a z :
|x = 23.461
|x = 23.46 |
E x e m p lu :
E x e m p lu :
E x e m p lu :
using System;
public class TestSplit
Console.Write(w[i] +
}
}
}
Ieire:
12_27_496_
Cunosctorii limbajului C au remarcat desigur similitudinea ntre metoda Split ()
i funcia strtok ().
Toate intrrile i ieirile n C#, la fel ca n C++ sau Java, presupun folosirea
stream-urilor. Un stream este o reprezentare abstract a unui dispozitiv fizic
(memorie, fiier, reea, etc.), n care informaia se poate accesa doar cte un byte
odat. ntr-un stream informaia circul ntr-un singur sens. De exemplu, un
program nu va scrie datele direct ntr-un fiier, ci le va scrie ntr-un stream de ieire
care reprezint fiierul.
Exist stream-uri de intrare i stream-uri de ieire. Din stream-urile de intrare
programul citete date, iar n cele de ieire scrie date. Pstrnd dispozitivul n
form abstract, destinaia sau sursa stream-ului poate fi ascuns. Aceasta
permite reutilizarea codului, iar codul este similar atunci cnd aplicaiile scriu sau
citesc din fiiere sau din reea, de pe disc, din memorie, sau din oricare alt
dispozitiv.
.NET Framework definete n spaiul de nume S ystem .lO acele clase care
reprezint stream-uri cu fiiere. Sunt mai multe astfel de clase. n acest paragraf ne
referim la doar un singur aspect: citirea i scrierea datelor numerice din fiiere text.
lat un program pentru exemplificare:
using System;
using System.lO;
class FileReadWrite
{
static void Main()
{
s tring[] s = nuli;
string linie = nuli;
C apitolul 5. T rsturi eseniale a le lim bajulu i C# 129
int x = 0;
12 335 561
0 25 5 76
99 1 773 67 3
12 335 561
0 25 5 76
99 1 773 67 3
Observaii:
Vom crea o aplicaie numit Salut, care are un singur buton plasat pe o
form. La apsarea lui, apare o fereastr sistem de tip MessageBox, care afieaz
un mesaj de salut. Urmai paii:
; >'
; f i C heckedtistBox 3 Fo rm l.cs
^ Form l.Designer.es
I r f Com boBox
.|U ^ Fo rm l.re sx
: ^ DateTimeFlcker
IP ; ^ Program .cs
I A Label -'III
Linklabe!
; u s tB o x
\ Listview
; $ 2 CheckedLlstSox (none)
No
I S ComboBox Apaja
Apes* .g
1 H w DafceTimePicker TextAAgn WddleCenter
; A Label [ TextrmageReU Overlay
; A LinkLabel I UseMnemonic True
j S 3 ListBox j UscVisudStyle! T ru e
UseWaitCursor False
I l y ListVlew
0 Nefvtvim
7. Urmeaz tratarea evenimentului C lick, pentru ca aplicaia s rspund
acestui eveniment. Avei dou variante:
a. Dublu click pe suprafaa butonului.
b. n fereastra P roperties, click pe iconul fulger", numit Events. Din
lista de evenimente la care poate rspunde butonul, selectai
evenimentul C lick i apsai Enter.
n ambele situaii se deschide E d ito ru l de Cod. Fiierul deschis este
F o r m l.c s , iar metoda nou creat este b u t t o n l _ c l i c k . Acesta este
handler-ui de eveniment. Va fi invocat n mod automat la click pe buton.
iSaU-Forml **:[,j*buttonl_.CJd<ob)ee>
rjl u s i n g S y s te ;
; u sing S y s t e .C o lle c t io n s .G e n e r ic ;
j u sing Syste.C om ponentH odel;
! u sing S y s t e .D e c ;
; u s in g S y s c e r e .D r a w in g ;
! u s in g S y s t e . L in c i;
Fereastra
: u s in g S y s te .T e x t; aplicaiei
'- u s in g S y s te . l/livdous. Foetus;
Observaie:
>
Pentru afiarea mesajelor de informare se utilizeaz metoda static Show()
a clasei System. Windows .Forms .MessageBox.
Controale
Controalele sunt instane ale unor clase .NET definite n spaiul de nume
S yste m .W in d o w s.F o rm s. Marea majoritate a acestor clase deriv din clasa
Control, care definete funcionalitatea de baz a oricrui control. Aa se explic
faptul c unele proprieti i evenimente sunt comune tuturor controalelor. Clasele
de tip control sunt organizate ierarhic, pe baza releiei de motenire, aa cum se
vede din diagrama parial de mai jos:
n mod evident, diagrama de mai sus este incomplet. Numrul de controale este
mult mai mare.
Proprieti
Proprietile sunt membri ai claselor din care fac parte. Ele definesc
caracteristicile controalelor, de pild culoarea, poziia, dimensiunile acestora.
Controalele motenesc proprietile claselor printe. n unele cazuri le suprascriu
(override), pentru a obine un comportament particular i definesc de asemenea
altele noi.
Fereastra P ro p e rtie s a mediului integrat este un instrument important.
Selectnd un control, avei acces vizual la proprietile i evenimentele pe care le
suport controlul. Controalele se creaz cu adevrat run-time, ns proprietile lor
iniieie pot fi stabilite design-time n aceast fereastr. Desigur c aceste
proprieti se pot modifica programatic n timpul execuiei programului.
C apitolul 6. A p licaii de tip W indows Form s 135
Evenimente
ncepnd cu aceast parte a lucrrii, ne vom preocupa doar de
evenimentele pe care le genereaz controalele Windows.
IMPORTANT
Programele cu interfa grafic cu utilizatorul sunt c o n d u s e de eve n im e n te
(event-driven)
Tratarea e v en im en telo r
Pentru acelai control putei trata mai multe evenimente, definind desigur
cte un handler specific. Mai mult dect atat, un acelai handler poate fi utilizat
pentru mai multe controale, aa cum vom vedea n continuare.
Vom realiza un proiect cu trei controale de tipuri diferite. Pentru fiecare
control tratm evenimentul C lick. n mod evident, putem scrie cte un handler care
s rspund fiecrui control. Vom proceda ns altfel. Vom crea un singur handler
pentru C lick pe oricare control. Acest lucru este posibil, datorit signaturii speciale
a handlerelor .NET:
136 Partea a Il-a . Program are W indow s cu V isual C # E xpress E dition
Aplicaia ClickEvent
Pentru realizarea proiectului, urmai paii de mai jos:
p r i v a t e v o i d b u t o n _ C l i c k ( o b j e c t sender, EventArgs e)
A doua variant este s dai alt nume metodei, din fereastra P roperties, I
editnd cmpul din dreapta etichetei Click. Putei pune de pild numele J t ^
e v e n im e n t_ C lic k , apoi apsai Enter.
C apitolul 6. A p licaii d e tip W indows F orm s 137
8Ut0n S A ction
I evenim ent Cflekjj
, 0 CheckBox
( MouseCaotureChsng
! g CheckedLlstBox
M ouseC kk
< Combo6ox !S App^'ir.iiHi*
; T jg OrfeTimePictor ! PaW
; A tabel ,S Heh<VKir
\ A UnUabel CKangeUICues
ControiAdded
LtstSox
ControlRemoved
> } ! UstVtow
HdpRoquested
i i r MskedToxtBox Query AccesslbiStyHelp
; MonthClendar StyleChanged
Z i Notifylcon ! SystemCdorsCbanged
f! ; v e r if System.Windows.Forms.CheckBox
'Sj.CJ#Ewitv _
a Action
A p a sa re 3,1
-----
MouseCaptureCharjeveniment_Click
MouseClick
j O validare A p p e ara n ce
Paint
B e h a v io r
C h a n g e U IC u e s
ControlAdded
f A pasare j
l OK j
I 'I
Observaii:
n corpul handlerului, c.Name i c.Text sunt proprieti ale controalelor,
reprezentnd numele obiectului care reprezint controlul, respectiv
eticheta afiat pe control. T extB ox nu are proprietatea Text.
Expresia Control c = (Control) sender; necesit o conversie
explicit (downcast), deoarece sender e de tip object, Control e
subclas pentru Object (sau object), iar conversiile implicite au loc
numai de la subclase la superclase.
A). Dup primul pas de creare a proiectului, aveam o form goal, cu eticheta
F o rm l. S-au generat fiierele de baz ale proiectului: Forml.cs,
Forml.Designer.es i Program.cs.
Partea important este faptul c metoda Main() din clasa Program apeleaz
metoda Run ( ) .Run () e metod static a clasei Application. Run () lanseaz
n execuie aplicaia. O instan a clasei FormaMea este creat i este fcut
vizibil. n acest fiier ar trebui s nu modificai nimic.
Fiierul FormaMea.cs
Observaii:
Fierul definete clasa FormaMea. Cuvntul cheie parial spune faptul
c definiia clasei se va completa n alt fiier (FormaMea.Designer.cs).
FormaMea motenete clasa Form din .NET, pentru ca s aib toate
caracteristicile unei forme Windows.
Constructorul clasei, care se invoc la crearea formei, apeleaz metoda
InitializeComponent (). Aceast metod execut tot codul necesar la
140 Partea a Il-a . P rogram are W indow s cu V isu al C # E xpress E dition
Fiierul FormaMea.Designer.es
Fiierul reine tot ce s-a stabilit n etapa de design, relativ la form i
controale. Codul fiierului se genereaz n mod automat.
n S o lu tio n E xplorer, facei click drept pe fiierul F o rm a M e a .D e s ig n e r.e s
i alegei View Code:
Metoda InitializeComponentQ
// S e t a r e a p r o p r i e t i l o r i n i i a l e ale controlului
// b u t o n ca urmare a aciunilor de design n fereastra
// Properties i Form Designer.
this.buton.Location = new System.Drawing.Point(78, 23);
this.b u t o n .Name = "buton";
this.buton.Size = new System.Drawing.Size(75, 23);
this.b u t o n .Text = "Apasare";
Aplicaia DtpRuntime
Realizm o aplicaie care n timpul execuiei, prin apsarea unui buton, creaz
un nou control pe form, de exemplu un DateTimePicker. Un control
DateTimePicker afieaz data curent.
C apitolul 7
La cele de mai sus se mai adaug i alte tipuri de controale, care vor fi descrise n
cele ce urmeaz, nsoite de exemple practice.
Controlul Button
n spaiul de nume S ystem .W indow s.F orm s se definesc trei controale care
deriv din clasa ButtonBase: Button, CheckBox i RadioButton.
B u tto n este de departe cel mai comun control. Pentru a inspecta
proprietile i evenimentele unui buton, este suficient s creai rapid o aplicaie de
tip Windows Forms, s aducei pe form un buton i s parcurgei fereastra
P roperties. De multe ori ns nu este de ajuns pentru a v lmuri. De aceea, v
sftuim ca s avei mereu deschis Helpul mediului integrat i s v obinuii s
cutai rapid acolo oricare clas, proprietate sau cod exemplificator. Din meniul
Help, alegei C on tents. n panoul din stnga, expandai nodul .Net Fram ew ork
SDK. Apoi expandai .Net Fram ew ork C lass L ib ra ry. Expandnd mai departe
nodul S ystem .W ind ow s.F o rm s Nam espace, ntreaga galerie de clase de tip
control v este accesibil cu toate informaiile necesare.
Revenind la B utto n , acesta poate genera mai multe tipuri de evenimente,
ns n proporie covritoare, evenimentul C lick este cel mai folosit.
Aplicaia ButtonExample
Vom face o mic aplicaie care trateaz alte dou tipuri de evenimente i
pune n eviden cteva dintre proprietile butoanelor.
5. n panoul din stnga aducei un buton, iar n cel din dreapta, plasai dou
butoane.
8i
in
buttonl 42
ix ton
;'ij _____
v|: (button3 j
11. Facei dublu click pe butonul cu eticheta Ieire, pentru a trata evenimentul
C lick. Introducei n corpul handlerului de eveniment, codul: .
C ontroalele L a b e i i L inkLabel
Aplicaia LabelExample
Vom realiza un proiect care exemplific cel mai simplu mod de utilizare a
etichetelor.
LaraatiNoteoad
Observaii:
Proprietatea Link A r e a a unui control L inkLabel, este o structur care
reine poziia primului caracter al link-ului i numrul de caractere din link.
lat cum putei crea programatic un L in kL ab e l care va fi adugat pe o
form:
v o i d A d d L i n k L a b e l ()
{
// Creaz o etichet
LinkLabel lnk = new LinkLabel ();
S y s t e m . D i a g n o s t i c a . P r o c e s s .S t a r t ( " w o r d p a d . e x e " ,
@"c:\Salut.doc");
C apitolul 7. Controalele W indows F orm s 151
Aplicaia GroupRadioCheck
Proiectul ilustreaz un mod simplu de utilizare a controalelor RadioButton,
CheckBox i GroupBox.
Excursii
Tara Transport
!S l
Excursii
T ara Transport
O Austria P I Avionul
0 Grecia O Balonul
O Frana
O Italia | Verifica )
O Germania [ Ieire |
TP'"'" 1 1 u
10. Facei dublu click pe butonul Verifica, pentru a trata evenimentul C lick. n
handler-ut de eveniment, scriei codul evideniat cu bo ld :
{
string msg = "Vom pleca in
// Verific care dintre butoanele radio e apsat
if (radioButtonl.Checked)
msg += radioButtonl.Text;
if (radioButton2.Checked)
msg += radioButton2.T e x t ;
i f {radioButton3.Checked)
m s g += radioButton3.Text;
if (radioButton4.Checked)
msg += radioButton4.Text;
if (radioButton5.Checked)
msg += radioButton5.T e x t ;
// Afieaz mesajul
MessageBox.Show(msg + " !");
11. Facei dubiu click pe butonul Ieire, pentru tratarea evenimentului C lic k . In
Editorul de Cod vei scrie:
La rulare, obinei:
154 Partea a II-a. P rogram are W indow s cu V isual C# Express Edition
MessageBox
Excursii
Tara T ransport
O Austria 0 Avionul
O fra n a
O 'talia [ Verifica ]
( - ) Germania [ Ieire )
C ontrolul T extB o x
P ro p rie t i:
Metode:
Evenim ente:
Aplicaia TextBoxExample
i i i m k f y ! 7 ! | | |
ID-ul:
-- --------- ------~ - :
Parola:
----------------- ----- --
CNP:
I Autentificare |
3. Selectai primul control de tip TextB ox. Din fereastra P roperties setai
proprietatea Name la valoarea idTextBox. Setai n acelai mod pentru al
doilea control proprietatea Name la valoarea p a r o l a T e x t B o x i
c npTextBox pentru al treilea control de tip TextBox. Pentru eticheta
CNP, setai proprietatea Name ia valoarea cnpLabel, iar pentru buton,
autentifButton.
156 Partea a Il-a . Program are W indow s cu V isual C# E xpress Edition
4. Iniial, numai primul cmp text este activ, celelalte dou fiind dezactivate,
n acest scop se utilizeaz proprietatea Enabled. Dorim ca nc de la
apariia formei controalele parolaTextBox i cnpTextBox s fie
dezactivate. Pentru aceasta, vom scrie codul necesar n constructorul
formei. Selectai forma, apoi n P roperties setai cmpul Name la valoarea
TextBoxEx. n felul acesta, ai modificat numele clasei formei, care iniial
era F o rm l. Facei click drept n SolutionExplorer pe numele formei i
alegei View Code. n constructorul clasei introducei urmtoarele:
{
// Dac cmpul Text are valoarea "parola"
if (parolaTextBox.Text "parola")
<
// Eticheta i controlul de tip text
// pentru CNP devin vizibile
cnpLabel.Visible = true;
cnpTextBox.Visible = true;
else
MessageBox.S h o w {"Autentificare cu succes!");
}
Utilizatorul va completa primul cmp de text cu ID-ul lonet', dup care va apsa
Tafa, al doilea cmp cu parola parola", dup care apas E nter, iar in al treilea va
trece un numr format din 13 cifre, apoi va face click pe buton. Aplicaia verific
corectitudinea ID-ului, a parolei i a CNP-ului, ntr-un mod, desigur rudimentar, dar
suficient pentru ceea ce ne-am propus.
La rulare, nainte de introducerea parolei, avem:
1 TextBoxControl 3 (M )
ID-ul: | ionel
Parola:
Parola:
CNP: 1900125060780 j
Autentificare cu succes!
[ Autentificare j OK
De reinut:
* Proprietatea P assw ordC har stabilete caracterul care mascheaz textul
introdus de utilizator.
C apitolul 7. C ontroalele W indows Form s 159
E f e m e n t e d e S t i t
Este recomandabil ca n aplicaiile n care folosii m ai multe controale, s
introducei propriile nume pentru referine i tipuri. Numele trebuie s fie sugestive,
adic s indice menirea i tipul controlului. Exemplu: id T e x tB o x ,
p a r o la T e x tB o x , etc. Numele claselor trebuie s nceap cu liter mare, de
exemplu T extB oxE xam ple. n felul acesta vei distinge uor referinele i tipurile.
Focusul Controalelor
Controlul care primete intrrile de la tastatur este cel care are focusuE .
n oricare moment, un singur control al aplicaiei poate avea focusul. Schimbarea
focusului se face acionnd tastele sgei, tasta Tab, sau mouse-ul.
Ordinea n care controalele primesc focusul se stabilete programatic cu
ajutorul proprietii Tablndex. Controlul cu valoarea 0 pentru T ablndex primete
primul focusul. Visual C# 2008 permite stabilirea design time a focusului
controlalor. n meniul View, alegei Tab Order, apoi facei click pe etichete pentru
modificri.
ji j < \ | Formt'
I I Are "focus" j Nu are focus Are "focus Nu are "focus"
I I
u
I I Nu are "focus" j Nu are "focus" Nu are "focus" Nu are "focus"
......................... - .............J
Figura 7.1 Focus stabilit design time Figura 7.2 Focusul la rulare
160 Partea a Il-a . Program are W indow s cu V isual C # E xpress Edition
Controalele invizibile sau cele dezactivate nu pot fi accesate cu tasta Tab, i nu pot
primi focusul, chiar dac li s-a asociat un index de tabulare design time sau run
time.
Probleme propuse
P ro p rie t i:
Metode:
Evenim ente:
Urmai paii:
3. Facei click pe caseta controlului, acolo unde scrie Type Here, i creai un
prim meniu numit Fiier, cu opiunile Nou i Ieire:
.Form1.
Tyjc I' ?
Multiline
ilt'Rfer'':'\; Editare 1
ContextMenubtrip
fj Copiaza
.Ji Decupeaz
3 SiLipestel
*- i: ;
8. Acum vei asigna meniul de context controlului T extB ox. Selectai controlul
T extB ox i n P roperties atribuii proprietii C o n te xtM e n u S trip valoarea
contextMenuStripl, adic referina la obiectul de tip meniu contextual
al aplicaiei:
164 Partea a Il-a . P rogram are W indow s cu V isual C# E xpress Edition
: CharacterCasing Normal
|B | c o n tex tM e n u S tri v
!; S (AppIicationSetting:
; | E (DataBindings)
Copiaza
^ Decupeaz
| Lipete
C apitolul 7. C ontroalele W indows F orm s 165
Forme
O form este un tip special de control care reprezint o fereastr. Este
folosit ca suport pentru alte controale. Prin setarea proprietilor se obin diferite
tipuri de ferestre, avnd diverse dimensiuni, aparene, stiluri i culori. Formele sunt
instane ale clasei Form.
P ro p rie t i:
Metode:
Evenim ente:
O metod obinuit de creare a unei forme este de a defini o clas derivat din
clasa Form:
La crearea unui nou proiect de tip Windows Forms, mediul integrat genereaz
o clas cu numele implicit Forral, iar aceast clas se instaniaz Tn Main ():
Application.Run(new F o r m l ());
Ca variant alternativ, click drept pe numele proiectului, alegei Add, apoi New
Item....
C apitolul 7. C ontroalele W indows Form s 167
n fereastra Add New Item - [nume proiecf\ selectai iconul Windows Form i
introducei un nume pentru noua form:
Dialoguri modale
Anumite tipuri de ferestre se prezint ca dialoguri cu utilizatorul. Acesta
introduce date n controale, pe care apoi le valideaz sau nu (apsnd de exemplu
butoanele OK sau C ancel). Acest tip de fereastr dialog nu permite utilizatorului s
acceseze alte ferestre ale aplicaiei pn cnd dialogul nu este nchis. De
exemplu, n M icrosoft Word, cnd alegei Open n meniul File, se deschide un
dialog care v cere s alegei un fiier. Fereastra blocheaz aplicaia i nu putei
ntreprinde nici o alt aciune n editor, pn n momentul n care ai nchis dialogul.
Un asemenea tip de dialog, se numete d ia lo g m odal.
Un dialog modal este o form care se deschide cu metoda showDialog ():
Aplicaia DialogModal
Realizm un proiect de tip consol care lanseaz o form ca dialog modal.
Urmai paii:
2. n panoul dialogului New Project selectai Empty Project, iar n caseta text
Name, introducei numele proiectului: DialogModal.
4. n dialogul A dd New Item, selectai iconul Code File, apoi n caseta Name,
introducei numele fiierului: Modal.cs.
using System;
using System.Windows.F o rms;
class Pogram
1
public static void Main)
{
Forma f = new Forma); // Instaniere
A dd R e fe re n c e .. 4- *
.NET ; C O M _ R e j e c t s . Brow se Recent
OK Cancel
Dialoguri nemodale
D escrierea a p lic a ie i:
Urmai paii:
ilistBoxl f Adauga ]
i
i
1
i i
l
i | Ieire |
1
C apitolul 7. C ontroalele W indows F orm s 171
=,s
OK
// nchidem forma F o r m 2 .
C l o s e ();
private Form2 f ;
11. Pentru ieire din aplicaie, facei dublu click pe butonul Ieire. n corpul
handler-ului evenimentului Click, scriei:
I Itemul 1 Adauga
! Itemul 2
! Itemul 3
: Itemul 1) OK
Ieire
C apitolul 7. C ontroalele W indows F orm s 173
Not:
IM P O R T A N T !
Cnd apelai Close {) pentru un dialog modal, fereastra nu se distruge ci
devine invizibil. Aceasta, deoarece dup nchiderea ferestrei, avei de regul
nevoie de membrii clasei, ca n aplicaia de fa:
De reinut:
Cnd nchide un dialog modal, utilizatorul ar trebui s aib cel puin dou
opiuni: s pstreze datele pe care le-a introdus n controale sau s renune la ele.
Pentru aceasta, are nevoie de dou butoane, s le spunem O K i Cancel. Evident,
174 P artea a Il-a . Program are W indow s cu V isual C # Express E dition I
switch (rez)
{
case DialogResult.OK :
// Ceea ce dorii s se execute dac s-a ieit cu OK
break;
case DialogResult.Cancel :
// Cod care se execut n caz c s-a acionat Cancel
break;
}
Aplicaia OkCancel
Deschide
dialogul modal
6. Tratm evenimentul Click pentru butonul formei Form l. Facei dublu click
pe buton. n metoda handler, introducei codul evideniat n Bold:
switch (rez)
{
case DialogResult.OK;
MessageBox.Show("Dialog inchis cu OK");
break;
176 P artea a II-a. P rogram are W indow s cu V isu al C# E xpress E dition
case D i a l o g R e s u l t . Cancel:
M e s s a g e B o x .S h ow("Dialog nchis cu Cancel");
break;
!S Form2 j
D e schid
dialogul modal
OK
C an c e l .sfi
Htli
De reinut:
Putei desemna butoane care retumeaz valori egale cu cele ale unor
membri ai enumerrii D ialogR esult.
* Valoarea retumat la acionarea click asupra unui asemenea buton este
aceeai pe care o retumeaz metoda S h o w D i a l o g O . Acest lucru
permite ca ulterior nchiderii formei s se dirijeze fluxul de execuie al
programului n funcie de rezultatul ntors de form.
Probleme propuse
D ia lo g u ri p re d e fin ite
Eroare de copiere
Retry Cancel
in d ic a ie :
Alegei un utilitar, cum este M icrosoft Word i revedei toate aceste dialoguri,
accesndu-le pe rnd din meniul F ile . Merit s o facei, pentru c acum le vedei
cu ochii programatorului.
E x e m p lu :
if (openFileDialog.ShowDialog() =
System.Win d o w s .F o r m s .DialogResult.OK)
{
// Cod care deschide fiierul
}
Observaie:
Toate cele apte dialoguri predefinite sunt d ia lo g u ri modate, deoarece
utilizeaz metoda ShowDialogO. Un dialog modal ntrerupe aplicaia, iar
utilizatorul nu poate continua pn n momentul n care dialogul a fost nchis.
Aplicaia DialoguriPredefinite
Proiectul pe care l propunem este o aplicaie cu un meniu din care
utilizatorul poate selecta opiuni de deschidere a dialogurilor predefinite. Pentru
unele dialoguri, se va scrie i cod suplimentar, mai ales referitor la setarea
proprietilor. Vestea bun este c vei scrie ntotdeauna aproape la fel atunci cnd
lucrai cu dialoguri predefinite.
sier. |[ Eormat
Deschide
Salveaza ca
Setare pagina
Imprimare
Previzualteare
|R*I
B ie r ' | Format |
1 Font
1 gulori
1 ' -
// Setrile de pagin
pageSetupDialogl.PageSettings =
printDocumentl.DefaultPageSettings;
182 Partea a II-a. P rogram are W indow s cu V isual C# E xpress E dition
8 asie cokxs;
r i B l I H I
i l i e i F i r
Custom colors:
Define Custom Colors
184 Partea a Il-a . Program are W indow s cu V isual C # E xpress Edition
Comentarii:
Proprietatea Filter este comun dialogurilor O penF ileD ialog i
S aveA sD ialog, ntruct este motenit de la clasa de baz comun,
FileDialog. Caracterul ' | ' (pipe) delimiteaz tipurile de fiiere pe
care le putei selecta, dar i intrrile n combobox : "Fiiere Rich
Text (*.r t f ) 1*.rtf|Fiiere Text (*.txt)|*.tx t " ;
Not:
n ce privete printarea efectiv a unui document, aceasta se face prin
apelul metodei Prin () a clasei PrintDocument. Ciasa PrintDocument este
definit n spaiul de nume S yste m .D ra w in g .P rin tin g . Obiectul de tip
PrintDocument preia setrile de pagin stabilite de ctre utilizator n dialogul
PageSetupDialog, i trimite documentul la imprimant. Codul necesar poate fi
gsit n documentaia clasei P rin tD o cu m e n t sau n articole din MSDN {Microsoft
Developer Network).
Sfat practic
S avei n permanen deschis Helpul mediului integrat. Acolo gsii
imediat clasele cu care lucrai, cu descrierea complet a cmpurilor,
proprietilor, m etodelor i evenimentelor lor, dar i cu exemple de cod care v
pot ajuta. Vei descoperi foarte repede membrii a i claselor care v p o t fi utili.
Reamintim locaia B ib lio te c ii de Clase: Help -> C o n te n ts -> .NET
Fram ew ork S D K -> .N E T F ra m e w o rk C lass Library.
M D I - M ultip le D o c u m e n t Interface
Aplicaiile MDI difer de cele de tip SDI (Single document interface) prin
aceea c SDI au o singur fereastr copil. Notepad este un asemenea exemplu.
Dac dorii s editai dou documente, trebuie s deschidei dou instane
Notepad.
Att fereastra printe ct i ferestrele copil sunt de fapt forme .NET. O form
devine container n momentul n care proprietatea isMdiContainer este setat
true.
Aplicaia implementeaz:
Urmai paii:
{
C r e a t e C h i l d ();
b) Aranjare T ile :
Aplicaie MOI
190 P artea a Il-a . P rogram are W indow s cu V isual C # E xpress Edition
De reinut:
ActiveMdiChild.WindowState = FormWindowState.Maximized;
Probleme propuse:
R ich T extB ox deriv direct din clasa TextB oxB ase, la fel ca i T extB ox. n
vreme ce un T e xtB o x se utilizeaz pentru a introduce secvene scurte de
caractere de la tastatur, un R ich T e xtB o x se utilizeaz cu precdere ca editor de
text.
Controlul are toate facilitile unui TextB ox, dar ofer i altele, cum sunt
posibilitatea de formatare a fontului (Italic, Bold, Underline! i a paragrafului. Textul
se poate introduce de ctre utilizator, poate fi ncrcat din fiiere de tip RTF (Rich
Text Format) sau din fiiere text. Clasa are metode pentru deschidere i pentru
salvare de fiiere n aceste formate. Un control de tip T e x tB o x poate fi nlocuit fr
modificri majore de cod cu un control R ichTextB ox.
n aplicaia care urmeaz vom utiliza pentru prima oar i o bar de
instrumente, cu ajutorul controlului T o o lS trip . nainte de a continua, cteva cuvinte
despre acest control:
Controlul ToolStrip
Aplicaia RichTextBoxExample
Vom realiza un mic editor de text, asemntor celui creat n subcapitolul
TextBox. Controlul care afieaz textul va fi de data aceasta un R ichT extB ox.
Aplicaia va avea un meniu, faciliti de deschidere i salvare a documentelor n
format RTF, ca i posibilitatea de a seta fontul i culoarea lui. Evident, pentru
implementarea acestor faciliti, vom utiliza dialoguri predefinite.
S S E d ito r d e f i ie r e R T F
i l| Fiier l| - E o r m a t ' i
Nou
'1 deschide l
3 alveaza Ca i
"a Ie s 're
;...... T ir '
7. Click drept pe fiecare buton din T o o lS trip i alegei Set Image. n dialogul
S elect R esource, apsai butonul Im p o rt. Vei lipi astfel pe fiecare buton
imaginea dorit:
I j j ; :Set image.,. - ,
Enabled
8. Dorim s atam fiecrui buton cte un Tool Tip Text, adic un mic text
care apare cnd staionai o clip cu mouse-ul asupra butonului. Pentru
aceasta, selectai pe rnd cte un butorn i din P ro p e rtie s atribuii
proprietii T ext un text scurt, reprezentnd rolul butonului:
IAlege un Font^
10. Vom trata evenimentul C lic k pentru fiecare dintre opiunile meniului, dar i
pentru butoanele din T o o lS trip . Dublu click pe opiunea Nou. n corpul
handler-ului de eveniment, scriei codul:
194 P artea a I l-a . P rogram are W indow s cu V isual C# E xpress E dition
if (openFileDialogl.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
{
// Metoda LoadFile() deschide fiierul
richTextBoxl.LoadFile(openFileDialogl.FileName);
}
12. Dublu click pe opiunea de meniu Salveaza Ca. Corpul handler-ului trebuie
s conin exact acelai cod scris n aplicaia Dialoguri Predefinite din
subcapitolul precedent. Precizm doar codul suplimentar:
if (saveFileDialogl.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
{
// Metoda SaveFile() salveaz pe disc textul
// controlului ntr-un fiier cu formatul RTF
richTextBoxl.SaveFile(saveFileDialogl.FileName,
RichTextBoxStreamType.RichText);
>
System.Windows.Forms.DialogResult.OK)
{
// Poriunea selectat din text preia
// caracteristicile alese de ctre utilizator
richTextBoxl.SelectionFont =
fontDialogl.F o n t ;
}
}
Observaie:
r
Editorul de mai sus lucreaz numai cu Fiiere R T F . La ncercarea de
deschidere a unui alt tip de fiier, aceast versiune a metodei
L o a d F i l e O arunc o excepie. Din acest motiv, ntr-o aplicaie
serioas, vei apela asemenea metode numai n interiorul blocurilor try/
catch:
try
{
richTextBoxl.LoadFile(openFileDialoal.FileName);
}
catch (System.Exception e)
{
MessageBox.Show(e.Message) ;
}
Controlul ToolTip
singur instan a clasei este suficient pentru a furniza texte de informare pentru
toate controalele unei forme.
Exemplu:
ToolTip t = new Tool T i p O ;
Button b = new Bu t t o n ();
ComboBox c = new ComboBox();
t.SetToolTip(b, "Valideaza datele");
t.SetToolTip(c, "Lista elevilor din clasa a Xll-a B " ) ;
Dac dorii stiluri i afiri diferite pe aceeai form, vei utiliza mai multe controale
T o o lT ip .
P ro prie ti :
M e to d e :
H i d e () - Ascunde fereastra T o o lT ip
S h o w () - Seteaz un text pentru T o o lT ip i l afieaz
RemoveAll{) - nltur toate textele asociate cu un control T o o lT ip
E v e n im e n te :
Aplicaia ToolTipExample
n proiectul de fa se folosete acelai T o o lT ip pentru mai multe controale
de pe aceeai form. Se utilizeaz designer-ul pentru toate aciunile necesare.
Nume:
Adresa
Studii
O Medii
O Superioare OK
O Cstorit
Cancel
Nume: Nume: j
~j Introducei numele, iniiala tatlui i prenumele
Adresa; Adresa: [
O Cstorit
Cancel
Qasalonf .... . ----------------
{lice n , m a ste ra t s a u d o c to ra t \
C apitolul 7. C ontroalele W indows F orm s 199
De retinut:
i
C o n tro lu l N o tify lc o n
P rop rieti :
ContextMenu - Returneaz sau seteaz un meniu de context pentru icon
Icon - Returneaz sau seteaz un iconul controlului
Text - Returneaz sau seteaz un text ToolTip. cnd cursorul
mouse-ului staioneaz deasupra iconului
Visible - Stabilete dac iconul e vizibil n zona de notificare
Metode:
Evenimente:
Aplicaia NotifylconExample Jg
Vtf
Pe o form plasm un buton care la click o ascunde. Folosim un Notifylcon |
pentru reafiarea formei. Reafiarea se produce la dublu click pe icon sau la ciick fj
ntr-un meniu de context. jfi
Acunde Forma
I-
C apitolul 7. C ontroalele W indows F orm s 201
Properties;^:
jj] / :M
(A pp licatio n Settin gs)
(Name) n o t if y ic o n l
8 ailoon Tip Icon N on e
BalloonTipText
BalloonTipT'itle
S C on te x tM e n u Strip c o n te x tM e n u S trip 1
G e n e ra te M e m b e r True
S| I P S l (Ic o n ) Qi
M odifie rs P rivate
Tag
T e xt C lic k d r e a p t a p e n t r u m e n i u d e c o n t *
Visible T ru e
A c u n d e Fofma
La click pe butonul Ascunde Forma, forma devine invizibil. La dublu click pe icon,
forma redevine vizibil, iar iconul rmne vizibil. Din meniul de context putei de
asemenea s controlai vizibilitatea formei:
De reinut:
* Controlul N o tifylco n plaseaz un icon n zona de notificare din system
tray. Iconul reprezint o scurttur pentru procesele care lucreaz n
background.
* Controlul rspunde la evenimente (C lick, D o u b le c lic k ) i admite un
meniu contextual.
F o n tu ri
Exemplu:
Setm fontul afiat de ctre o etichet:
Stilurile Fonturilor
Aplicaia FontStyleExample
Proiectul introduce stilurile Bold, Italic, Underline, ntr-un control
RichTextBox:
{
Font vechiulFont, noulFont;
Observaie:
> Codul prezent n metodele handler verific mai nti dac stilul dorit este
deja prezent. Dac este, l nltur.
> Pentru adugarea sau nlturtarea unui stil nou, fr a afecta celelalte
stiluri prezente, se efectueaz operaii pe bii cu enumerarea F ontS tyle.
( O r logic pe b ir (|) adaug un stil nou, iar A n d logic pe bii', aplicat
negrii noului stil, nltur noul stilul dintre cele prezente. Exemple:
Fonturile instalate
using System.Drawing.Text;
InstalledFontCollection fnt = new InstalledFontCollection();
Desenarea fonturilor
unei forme, atunci cel mai bun moment pentru desenare este acela al desenrii
formei i vom trata evenimentul P a in t al formei.
Aplicaia FontDrawingExampIe
Proiectul de fa determin fonturile instalate n sistem i populeaz un
combobox cu numele acestora. La selectarea unui font din list, numele fontului se
va deseneaz pe suprafaa formei.
iBUBtreaimai
Jokerman LET
Kartika
LaB am b d LET
Latha
Lucid Console
Lucida S n s Unicode
Mangal______________
TabC ontroI
P rop rie t i :
C apitolul 7. C ontroalele W indows F orm s 209
Metode:
Evenimente:
Aplicaia TabControlExample
Aplicaia pe care o propunem utilizeaz un TabControl pentru afiarea
imaginilor. 7ab-urile controlului se adaug runtime, n momentul n care se ncarc
o imagine de pe disc. Operaiile se execut ia apsarea butoanelor unui control
ToolStrip. Acestea sunt:
Urmai paii:
1. Creai un nou proiect de tip W indow s F o rm s A p p lic a tio n , cu numele
TabControlExample.
Insert y Image
i
ImageAndText
Select
Cut
// ncrcm n p i c t n r e b o x imaginea
pB.Image = Image.FromFile(fullPath);
p B .SetBounds(
(tabControll.Width/2) - p B .I m age.Width / 2),
(tabControll.Height/2)- (pB.Image.Height/2),
p B .Image.W i d t h , p B .I m age.Height);
II Adugm pb pe tab
tP.Controls.Add(pB);
10. Tratrn evenimentul C lick pentru butonul Close. Facei dublu click pe
buton. n metoda de tratare, scriei codul evideniat n B old:
private void toolStripButton4_Click (object sender,
EventArgs e)
{
// Dac mai exist pagini (tab-uri)
if (tabControll.TabPages.Count > 0)
{
/ / O tergem pe cea selectat
tabControll.TabPages.RemoveAt(
tabControll.Selectedlndex);
}
C apitolul 7. Controalele W indows F orm s 213
11. Tratrn evenimentul C lick pentru butonul C/ose Ml. Facei dublu click pe
buton. n metoda de tratare, scriei codul evideniat n B old:
La rulare, cu Add Image se pot ncrca mai multe imagini n pagini diferite, cu
butoanele Next i Prev se parcurg tag-urile deschise, cu Close se nchide tab-
ul selectat, iar cu Close AII se nchid toate paginile.
Probleme propuse
1. Realizai o aplicaie care utilizeaz un T a b C o n tro l care preia comenzile
clienilor la o pizzerie. Paginile controlului trebuie s conin controale de
tip T extB ox, C om boB ox, C heckBox, R a d io B u tto n i B utto n . La finalul
comenzii, aplicaia afieaz ntr-un dialog ntreaga comanda, mpreun cu
preul final.
: liitBoxl
l~~l Use date bound ten
Enter the strings in the collection (one per line):
Unbound M ode
' Corine
Edit Items 1 Aiinuta
: Viorel
, Maricel
Ghtocd
| OK |1 Cancftl |
Listele pot prelua itemi. Sursele de date pot fi tablouri, colecii, DataSet-uri.
E xem plu:
stringf] copii = { "Ionel", "Viorel , "Alinei", "Dorel" };
checkedListBox.DataSource = copii;
Clasele specifice acestor liste au desigur i alte metode i proprieti utile. Vom
face un mic proiect, pentru introducere n lucrul cu controalele de tip list.
Aplicaia TestListControl
3. Sub primele dou controale de tip list plasai cte un buton. Sub controlul
de tip checkListBox plasai dou butoane. Stabilii valorile proprietilor
Name ale butoanelor astfel: listButton, comboButton,
checkListButtonl i checkListButton2, iar valorile proprietilor
Text, aa cum se vede n figur:
216 Partea a Il-a . Program are W indow s cu V isual C # Express E dition
class Elev
{
private string nume;
public Elev(string n) { nume = n; }
public string Nume
{
get { return nume; }
}
>
6. Tratm evenimentul C lick pentru butonul lis tB u tto n . Acionai dublu click
pe acesta. Introducei acest cod n metoda de tratare:
C apitolul 7. C ontroalele W indows F orm s 217
1UNU 1
i DOI j [ j ] Viorel
Itemul 0 Ai
: TREI
1temui 1 i O A,inel
! Nelutu !
Itemul 2 j| | Dorel
? |
Itemul 3 ~
- - Itemul 4 'J.'f - fHnuM
Itemul 5
| Incarca ListBox | ! ( Incarca o lista ]
Itemul 6
i Itemul 7 V.
| Incarca alta lista ]
TrackBar
TrackBar.
0 ------------
NumericUpDown
NumericUpDown: ill
D om ainU pD ow n
D o m a in U p D o w n : j P r S 'i t e m p i
Este similar cu un L istB o x n aceea c ofer o list de opiuni ntre care utilizatorul
poate alege. Diferena fa de L is tB o x este c un singur item este vizibil la un
moment dat, iar utilizatorul poate naviga n list doar acionnd sgeile Up i
Down ale controlului. Pentru crearea coleciilor de obiecte care vor alctui lista, se
utilizeaz metodele Add(), la fel ca pentru celelalte controale de tip list.
Aplicaia Opacity
Vom utiliza controalele TrackBar, NumericUpDown i D om ainU pD ow n
pentru a regla opacitatea unei forme. Evident, unul singur dintre cele trei controale
ar fi fost suficient, ns scopul nostru este de a nva s le utilizm pe toate.
1. Creai un nou proiect de tip W indow s F o rm s A p p lic a tio n , cu numele
Opacity.
I Revenire J
NumeiicUpDown: 10
TfackBar:
iti cafipion : 3
k_j im age Test
a iDion 2 C4
O Im agineAudioEuIulia
Q Dion 2Q C 5
Revenire
a ipion 2 0 0 6
O JAVA 1.3
ffl Q '1PIN 200?
O pic-o 2 0 0 8
- t ^ -j AV A Tutorial SUN
i NumeiicUpDowi:
avadc-c
ffi D G
JavaE'/erriple ->2
o C<
DomainUpOown: Opacilate SQZ
00 cp
; javaxml
C!
yjjbuildet'
S Q
:domainUpDov*T];,
--tr-a TiackBdi:
ffl _ ' ' ' Zj'jD BC '
e? jie.
Bl i e .
V Ojdb'
a P3SP
gard X jw t ........
Aplicaia Transparency
Atunci cnd dorii ca anumite poriuni ale formei s fie transparente i
aciunea mouse-ului pe suprafaa transparent s se transfere ferestrelor de sub
form, utilizai proprietatea T ra n sp a re n cy a formelor.
222 P artea a Il-a . Program are W indow s cu V isual C # E xpress E dition
Controlul ProgressBar
Controlul nu permite nici o aciune a utilizatorului. Este destinat s indice n
mod vizual progresul unei aplicaii care decurge lent, aa cum sunt printarea unor
documente, copierea unui numr mare de fiiere, scanarea unui disc.
Stilul de afiare al controlului este determinat de proprietatea s t y l e . Exist
trei stiluri:
O bar continu care se umple de la stnga la dreapta
Blocuri segmentate care progreseaz de la stnga la dreapta.
Blocuri care oscileaz.
C ontrolul Tim er
1. Primul, este definit de clasa S ystem s.W indow s.F orm s.T im er. Se
utilizeaz n aplicaii de tip Windows Forms. El apare n mod implicit n
T o o lb o x i trebuie afiat ntr-o fereastr. Se utilizeaz numai n medii cu
un singur thread. Acurateea este de aproximativ 55 milisecunde.
2. Al doilea, definit de clasa S ystem .T im ers.T im er, este mai performant.
Poate fi folosit n medii muitithread. Nu se gsete n mod implicit n
T o o lb o x, ns poate fi adus acolo, aa cum vom vedea.
Aplicaia Timer.ExampIe
lbell
[ buUon 2
lbeI4 1abe!S
!abel5
C apitolul 7. C ontroalele W indows F orm s 225
iii
System.Windows.Forms.Timer
label2 Incrementare la 2 tecunde Slarl j
1 1 1 Stop j
Iabel5
.ifee rintln *. M jj
6. n dialogul Choose Toolbox Items, alegei din .r&Me'rm**.aWfctA' I
tab-ul .N E T Framework Components, clasa 1i1Getxrel ~
ij
T im e r din spaiul de nume S ystem .Tim ers. There ere no u m Mb controls h th*s p o u t . Dreg 1j
n item onto tft* text to add * to t i * toobox. j'
Un icon tip ceas apare n partea de jos n
T oolbar. :Q
; show a i
;<!.ChocK* *...
7. Tragei noul T im e r pe suprafaa formei. n
designer tray, selectai referina timerl. n
panoul P rope rtie s, schimbai numele referinei la systemTimer, setai
226 Partea a Il-a . P rogram are W indow s cu V isual C # E xpress E dition
11. Tratm evenimentul C lick pentru butonul Start. Facei dublu click pe buton.
Introducei codul:
12. Tratm evenimentul C lick pentru butonul Stop. Facei dublu click pe buton.
Introducei codul:
C apitolul 7. C ontroalele W indows F orm s 227
I i i
System. W indows. Forms.Timer
12 Incrementare la 2 secunde Start
Stop
14:00:31
aDei i :
r D o ............ o.............o
G roupB ox . - , ,
P. ' V t
j OK ~| I Canei I
C apitolul 7. Controalele W indows F orm s 229
> BackgroundlmageLayout
Are valorile posibile: None, Tile, Center, Strech i Zoom. De exemplu,
mai sus, pentru CheckBox, i RadioButton am ales C e n te r, iar pentru
G rupB o x valoarea Tile.
> ImageAllign
Label-urile nu suport Backgroundlmage deci utilizai Image pentru
afiare, iar pentru modul de afiare, alegei dintre valorile disponibile n
panoul Properties, pentru proprietatea ImageAllign.
> AutoSize
Pentru /abe/-uri, checkbox-un i radiobutoane trebuie s setai aceast
proprietate la valoarea false, altminteri nu vei reui s redimensionai
suprafeele controalelor, astfel nct s potriveasc imaginile.
> TextAllign
Aceast proprietate v permite s stabilii poziia i alinierea textului n
raport cu suprafaa controlului.
Clasa Image
.NET definete clasa im age n spaiul de nume S yste m .D ra w in g , pentru
lucrul cu imagini.
Clasa este abstract, deci nu se pot crea obiecte de acest tip. n schimb, imaginile
se citesc din fiiere cu metoda static FromFile ( ) :
Exem plu:
Image im = Image.FromFile(
Path.Combine(Application.StartupPath, "foto.gif"));
Labei lbl = new lbl L a b e i (); // Creeaz o etichet
lbl.Image = im; // Afieaz imaginea n control
Codul de mai sus ncarc imaginea din fiierul " f o t o . g i f " aflat n foiderul n care
se gsete fiierul assembly (exe) al aplicaiei. Metoda nu recunoate dect
formatele .GIF i .BMP. Eticheta l b l afieaz imaginea ncrcat.
Clasa are proprieti i metode pentru manipularea imaginilor. Metoda
FromStream() ncarc imagini de diferite tipuri nu numai n formatele standard
.GIF sau .BMP. Creaz un stream din care putei descrca imaginea. Sfream-ul
poate s fie de conectat la orice dispozitiv de intrare, de exemplu la o adres de
Internet:
Controlul PictureBox
P roprieti
Image Se seteaz pentru afiarea design time sau run time a
imaginilor
SizeMode Specific modul de afiare a imaginii. Are valorile:
Strechlmage, Centerlmage, Normal,Zoom.
ClientSize Permite modificarea dimensiunii imaginii n timpul rulrii.
ImageLocation Reprezint calea sau URL-ul spre imaginea care se afieaz
n P ictureB ox.
Metode
L o a d () Afieaz imaginea specificat de proprietatea
ImageLocation. Are dou versiuni.
SetBounds() Seteaz limitele controlului, la o anumit locaie, i la
dimensiunile specificate.
Evenim ente
Click Se declaneaz la click pe control
Paint Se declaneaz cnd controlul trebuie redesenat
ClientSizeChanged Se declaneaz cnd proprietatea C lientS ize se modific
Aplicaia ImageResourceExample
18. Selectai pe rnd cele dou butoane i stabilii pentru proprietatea Text,
valorile Zoomin, respectiv Zoom O ut
Form1
Images Q r i+ 2
Build Events
im Icons Ctrl+3
Files Ctrl+5 [
Resources
J Other CM +6
Settings
232 Partea a II-a. Program are W indow s cu V isual C # Express E dition
Application Im a g e s 7 J A d d R e so u rc e
1 A d d Existing F ile , .. - , .:
Build .------------------ -1 ....-.............. ..
A d d N e w String
: Build E v e n ts
N e w Im age
R e so u rc e s*
Application I 3 Im ages J Add Resou rce * ; M "\ \ ^ So lu tio n Im ageExam ple (1 project)
: ........ ' ' v. ; ,, Q ^5] im a g e E x a m p ie
Build E ve n ts 3 caS SS S S
actori.bmp
D e b ug a i] Form l .t;s
^ Form l.D esign er.e s
R e so u rc e s* - vt) F o rm l.re sx
actori
2 Program .cs
Settings
24. Tratm evenimentul C lick pentru butonul cu textul Zoomln. Acionai dublu
click asupra lui. Se deschide Editorul de Cod. Scriei codul evideniat cu
Bold, n handler-ul de eveniment:
De retinut:
Resursele se acceseaz uor din cod, deoarece mediul integrat creaz o ,?F
clas Resources, aflat n spaiul de nume Properties, iar acesta din urm se C
gsete n interiorul spaiului de nume al aplicaiei. n clasa Resources, toate
resursele se acceseaz simplu, ca oricare membru public.
lat de exemplu cum putei atribui ru n tim e unui control o alt imagine din 3 *
resursele proiectului: |j
Resursa pisica este un tip nou creat, pe baza unei imagini obinute dintr-un fiier
care se numea de exemplu pisica.bmp. v
Clasa Im ageList
Proprieti r.
Metode
Aplicaia ImageListExample
.: a Z ImageUst Tasks
' ! ; V # imageListl :....................... v~ z
; | ......................... Image Si2e 32,^32
f i
M Bl girafa.jpg
I2 s a
i l E
gorila.jpg
pisica.jpg
0
| sa
* tfgru.jpg
^ 'i i i
i: .Hotnt caine.jpg
ja,,
I 5s a urs.jpg
\ 6 a s veverita.jpg
vultur.jpg
i2 J E 2
ia
Cancel
10. Vom trata evenimentul C lick pentru buton. Acionai dublu click pe
suprafaa lui. Scriei codul evideniat cu B old, n handler-ul de eveniment:
De reinut:
fi C ontrolu l L istV ie w
L istV iew este un control complex, destinat afirii unei liste de itemi.
Panoul din dreapta al aplicaiei Windows Explorer implementeaz un
ListV iew . Control Panel este un alt exemplu cunoscut de ctre toat lumea.
Pentru fiecare item din list controlul afieaz un text i un icon.
Itemii se pot afia n cinci moduri diferite. Cele cinci moduri sunt determinate
de valorile pe care le poate avea proprietatea View, a clasei L istV iew .
IMPORTANT !
Fiecare item ntr-un control ListView, este o instan a clasei ListViewltem.
P roprieti:
Items - Depoziteaz colecia de obiecte de tip ListViewltem
care reprezint subitemii.
Collumns - Returneaz colecia de obiecte de tip ColumnHeader
care sunt afiate n ListViewControl.
View - Permite specificarea modului de afiare a itemilor n list
LargeImageLi s t - Indic obiectul imageList care conine iconurile folosite
la afiarea itemilor, atunci cnd proprietatea View are
valoarea Largelcon .
SmallImageList - Indic obiectul ImageList care conine iconurile folosite
atunci cnd proprietatea View are oricare alt valoare n
afar de Largelcon %
MultiSelect - Cnd este setat true, se pot selecta mai muli itemi odat
Metode: J
C l e a r {) - nltur toti itemii din control
BeginUpdate() - Prima metod suspend redesenarea controlului
EndUpdate() ListView la fiecare adugare a unui item n situaia n
care se adaug un mare numr de itemi.
- Se apeleaz a doua metod dup terminarea operaiei de
update, pentru a permite controlului s se redeseneze.
C apitolul 7. C ontroalele W indows F orm s 239
Evenim ente:
C o lu m n C lic k - Se declaneaz la click pe header-ul unei coloane
SelectedlndexChanged - Se declaneaz cnd utilizatorul selecteaz sau
deselecteaz un item
Aplicaia ListViewExample
Proiectul afieaz o list titluri de cri, n toate modurile de afiare:
Largelcon, Smalllcon, List, Tile, Detail. n modul Detail, fiecare item (carte) are cte
doi itemi suplimentari, afiai n coloana a doua i a treia: numele autorului i
editura care a publicat cartea. De asemenea, tot n modul Detail este disponibil
opiunea de Grid.
O "Wi: . ; ...0
I
j] Modufi Afiare
I O Large icons
I O Tie
O Sm al icons
? O u*t
O Detai
5 O 2n d
j lere ]
.....
Q p im a g e L is t l j & im age U stZ (
j Im a g e Size
j Im a g e Bit D e p th j D e p th 32 B it
&ror'lst
6. Adugai aceleai imagini n ambele obiecte de tip Im ageList, acionnd
Choose images.
// Textul itemului
itl.Text = "C# 2008 Code Book";
listViewl.View = View.Tile;
checkBoxl.Enabled = false;
10. Acionai dublu ciick pe radio butonul cu eticheta Small Icons. n corpul
handler-ului de eveniment, scriei codul:'
listViewl.View = View.Smalllcon;
checkBoxl.Enabled = false;
11. Acionai dublu ciick pe radio butonul cu eticheta List. n corpul handler-ului
de eveniment, scriei:
242 Partea a Il-a . P rogram are W indow s cu V isual C # E xpress E dition
listViewl.View = View.Tile;
checkBoxl.Enabled = false;
13. Acionai dublu click pe butonul Ieire. Tratm evenimentul C lick. n corpul
metodei de tratare, scriei:
La rulare, se obine:
Vedere Large Icons:
83CariiC# [ IU
Moduri Afiare
C# 2008 CodeBeginnino Ctt C# 3.0 Urdeashed
Bock 2008 Large Icons
O T0e
O Small Icons
O List
O Detaii
Ieire
Observaii:
t
I <* I n ci
n panoul din dreapta, selectai Subitems i apsai butonul din dreapta. n dialogul
ListViewSubitem Collection Editor, adugai pe rnd subitemii necesari pentru
fiecare item:
B M ise
BackColor | i W in d ow
S Font M ic ro s o ft S a n s Serif;
ForeColor m W in d o w T e x t
, Name L is tV ie w S u b Ite m 3
Text B e g in n in g C # 2 0 0 8
|~ Add j | Remove |
[~ OK ) j~ Cancel j
De retinut:
> Dac implementai afiarea Detail, atunci este nevoie s adugai coloane
(obiecte de tip ColumHeader).
> Itemii sunt obiecte diferite de tip ListViewltem.
> Numrul subitemiior trebuie s coincid cu numrul coloanelor.
C apitolul 7. Controalele W indows F orm s 245
Probleme propuse
1. Aducei urmtoarea facilitate aplicaiei ListViewExample: la apsarea unui
buton, se activeaz opiunea de selectare a ntregului rnd, atunci cnd
utilizatorul face click pe un item n modul Dtail.
4. Creai o aplicaie care permite editarea etichetelor itemilor unui L istV iew .
C ontro lu l TreeView
Crearea ierarhiilor
// Instaniem un TreeView
TreeView tw = new TreeView();
// Stabilim poziia pe form i dimensiunea controlului:
tw.Location = new System.Drawing.Point(12, 12);
tw.Size = new System.Dra w i n g .S i z e (153, 133);
8|'||'|"7
a P E ia a
Q Marius
Profesie
Hobby
I Valenlin
1 - Fete
! Alina
j Teodora
Important:
Metoda A d d () returneaz ntotdeauna o referin ia nodul nou creat.
Aceasta nlesnete adugarea de noduri child.
// Instaniem un T r e e V i e w
T r e e V i e w t w = n e w T r e e V i e w ();
La execuie se obine :
I 0 Marius
i Ocupaie
j Hobby
j 3 - Valentin
I - Varsta
! Scoala
Proprieti :
Nodes - Depoziteaz colecia de obiecte de tip T r e e N o d e a
controlului. Fiecare nod are la rndului lui proprietatea
Nodes, care gzduiete propriile noduri child.
LabelEdit - Stabilete dac eticheta text a unui nod poate fi editat
CheckBoxes - Stabilete dac se afieaz un checkbox lng etichetele
nodurilor
SelectedNode - Returneaz sau modific nodul selectat.
PathSeparator - Returneaz sau seteaz stringul separator folosit In calea
spre noduri. Calea spre un nod este un set de etichete de
noduri separate prin delimitatorul P a t h S e p a r a t o r .
C apitolul 7. Controalele W indows F orm s 249
Metode:
E venim ente:
Uneori trebuie s vizitai toate nodurile unui T reeV iew pentru o prelucrare
oarecare. Amiritii-v c un TreeView este o structur de date arborescent. Vei
nelege din ce cauz parcurgerea unei asemenea structuri se face cu o metod
algoritmic. Propunem o parcurgere n adncime:
*
p r i v a t e v o i d P a r c u r g T r e e V i e w ( T r e e N o d e C o l l e c t i o n noduri)
{
foreach ( T r e e N o d e n o d in n o d u r i )
{
PrelucrezNod(nod);
ParcurgTreeView(nod.N o d e s ) ;
}
}
p r i v a t e v o i d b u t t o n l _ C l i c k (ob j e c t s e n d e r , EventArgs e)
{
//
ParcurgTreeView(treeViewl.Nodes);
}
250 P a rtea a I l-a . P r o g r a m a r e W in d o w s cu V isu a l C # E x p re ss E d itio n
De reinut:
treviewi .Nodes reprezint colecia de noduri rdcin n arbore.
Fiecare nod din aceast colecie are la rndul lui proprietatea Nodes, care
refer nodurile de pe al doilea nivel, etc.
T r e e N o d e C o lle c tio n este un tip de date care reprezint o colecie de
obiecte T re e N o d e .
Aplicaia TreeViewExample
Proiectul pe care l propunem utilizeaz un combobox pentru selectarea
dr/Ve-urilor sistemului. n funcie de discul selectat, ntr-un control T r e e V ie w se
afieaz structura arborescent de directoare discului.
E le m e n te d e n o u ta te :
Obinerea informaiilor despre discuri cu metoda:
Drivelnfo.GetDrives()
Obinerea numelor subdirectorilor unui director specificat, cu metoda:
Directory.GetDirectories O
Parcurgerea recursiv a structurii de directoare a unui disc, n scopul
populrii controlului TreeView.
Urmai paii:
4. Adugai directiva u s in g S y s te m . 1 0 ;
Application.Exit{);
La rulare obinei:
Observaie:
Cu metoda recursiv se parcurge ntreaga structur de director a drive-ului
curent. Din aceast cauz, actualizarea controlului T reeV iew este ient pentru un
disc ncrcat.
De reinut:
Clasa D i r e c t o r y din spaiul de nume S ystem .IO furnizeaz metode
statice pentru creare, copiere, mutarea, redenumire de directori.
Clasa D r i v e l n f o din spaiul de nume S ystem .lO conine metode i
proprieti pentru determinarea informaiilor referitoare la drive-uri.
Metoda t r e e V ie w l. N o d e s . C le a r () ; terge toate nodurile din
colecie.
C apitolul 7. C ontroalele W indows F orm s 253
Probleme propuse
Aplicaia WebBrowserExample
La rulare, aplicaia ncarc n mod automat pagina stabilit design time prin
proprietatea u r l . n fereastra de navigare putei introduce oricarea alt adres:
Observaii:
>
Suntem siguri c v-ai ntrebat dac este greu s implementai player-e video
sau audio. Nu este uor. ns exist exist o cale mai simpl de a avea toate
acestea, prin integrarea componentei COM, W in d o w sM e d ia P la ye r n aplicaia
dumneavoastr.
Ca s vedei cum se procedeaz, vom face urmtorul proiect:
Aplicaia WindowsMecfiaPiayerExampie
Observaie:
Controalele adugate manual au aceleai funcii cu cele ale butoanelor
implicite. A fost un exerciiu pentru cazul n care vrei s mascai bara standard i
s utilizai propriile controale pentru manevrarea player-ului.
260 Partea a Il-a . P rogram are W indow s cu V isual C # E xpress E dition
C apitolul 8
Clasa G raphics
Clasa definete o suprafa de desenare GDI+. Metodele sale deseneaz pe
aceast suprafa, iar biblioteca GDI+ tie s trimit imaginea pe dispozitivul grafic
(monitor, imprimant, sau altceva).
Clasa nu rspunde la evenimente findc nu are membri de tip event. Dar folosete
evenimentul P aint al controalelor pentru a desena pe suprafaa lor.
Cazul 1.
Creai un proiect nou de tip Windows Forms. Tratm evenimentul P aint al
formei. Selectai forma i Tn fereastra P roperties acionai dublu click pe
evenimentul Paint. Scriei codul:
IM P O R T A N T !
Pentru desenarea liniilor i a curbelor, avei nevoie de un obiect de tip
G raphics i un obiect de tip Pen (peni). Obiectul G raphics furnizeaz metodele
care deseneaz, iar obiectele de tip Pen depoziteaz atribute ale liniei, cum ar fi
culoarea, grosimea i stilul.
262 Partea a I l-a . P rogram are W indow s cu V isual C# Express Edition
Cazul 2.
Metoda C r e a t e G r a p h i c s ( ) , se regsete n toate clasele derivate din
C o ntro l. Retumeaz un obiect de tip G raphics. Este nevoie de aceast metod
cnd nu dorii s foloii un eveniment P aint pentru a desena.
Realizai un nou proiect de tip Windows Forms. Pe form plasai un buton.
Acionai dublu click pe buton pentru tratarea evenimentului C lick.
n handier-ul evenimentului introducei secvena de cod evideniat cu B old:
// Fabricm o peni
Pen p = n e w Pen(Color.Red, 3);
// Desenm o linie
g .D r a w L i n e ( p , n e w P o i n t ( 2 0 , 30), new Point(280, 30));
p . D i s p o s e () ;
}
Deseneaz
Observaii
Un arc este o poriune a unei elipse. Ca s desenai o elips, apelai
metoda D r a w E l l i p s e () . Parametrii metodei D r a w A r c O sunt
aceeiai cu cei ai metodei D r a w E l l i p s e () , cu diferena c
D r a w A r c O necesit un unghi de start i unul de baleiere, lat cum
desenai o elips:
G r a p h i c s g = t h i s . C r e a t e G r a p h i c s ();
P e n p = n e w P e n ( C o l o r .Red, 3) ;
Rectangle r = new Rectangle(new Point(50, 50),
new Size(200, 100));
g.DrawEllipse(p, r ) ;
p.Dispose();
Poligoane
; Desenarea unui poligon se face foarte simplu, prin apelul metodei
- D r a w P o l y g o n Q . Metoda are ca parametri un obiect de tip P e n i un tablou de
puncte:
G r a p h i c s g = t h i s .C r e a t e G r a p h i c s ();
P e n p = n e w P e n ( C o l o r .Red, 3);
j P o i n t f ] p t = { n e w P o i n t ( 1 9 0 , 90), n e w P o i n t ( 1 4 0 , 130),
I n e w P o i n t ( 1 5 0 , 20 0 ) , n e w P o i n t ( 6 0 , 100) };
// Deseneaz un poligon cu patru vrfuri
g.DrawPolygon(p, p t ) ;
j p.Dispose();
264 Partea a Il-a . Program are W indow s cu V isual C # E xpress Edition
Urmai paii:
using System.Drawing.Drawing2D;
C apitolul 8. D esenare n .N E T c u Visual C# 265
y = 120;
r = new Rectangle(x, y, width, height);
// Crem o pensul de haurare
HatchBrush h =
new HatchBrush(HatchStyle.DiagonalCross,
Color.Azure, C o l o r .B lack);
y = 230;
r = new Rectangle(x, y, width, height);
La rulare, avem:
Observaii:
f
D esenarea te x tu lu i
Aplicaia DrawStringExample
Ca s desenai cu metodele Drawstring () trebuie s pregtii un font i o
pensul. Aplicaia testeaz dou dintre metodele D r a w S t r i n g O . Prima scrie un
text la o locaie specificat de un punct, iar a doua scrie un text ncadrat ntr-un
dreptunghi.
C apitolul 8. D esenare n .N E T cu V isual C# 267
Urmai paii:
// Deseneaz stringul
e .G r a p h i c s . D r a w s t r i n g (s , f, b, pt) ;
p . D i s p o s e ();
La rulare, obinei:
268 Partea a H -a. Program are W indow s cu V isual C # E xpress E dition
Dau im regat
pentru un cal
Observaii:
t
De reinut:
Probieme propuse
Capitolul 9
X M L cu C#
Sintaxa X M L
Spre deosebire de HTML, XML este destinat depozitrii i transportului
datelor i nu afirii datelor. Tag-urile XML nu sunt predefinite. Trebuie s definii
dumneavoastr aceste tag-uri. Un fiier XML este un fiier cu text.
<biblioteca>
<carte>
<titlu>Iarna vrajbei noastre</carte>
< / titlu>
</biblioteca>
C lase .N E T p e n tru X m l
Un document XML poate ndeplini rolul unei baze de date pentru aplicaia
dumneavoastr. Aplicaiile citesc deseori informaii din asemenea fiiere XML. Este
important, pentru c dac dorii s modificai acele informaii, schimbai coninutul
fiierului XML i nu e nevoie de refacei aplicaia.
Aplicaiile .NET pot s i scrie n fiiere .xml. De exemplu, dac setrile pe
care le face utilizatorul n aplicaie trebuie fie persistente, atunci e o idee bun s le
salvai ntr-un document XML.
Elevi
: Informaii
i
; coala:!
i Clasa: j
i Profil: i""
3. Vom edita fiierul XML. Mediul integrat include un editor de fiiere XML.
Acesta se invoc acionnd click drept n S o lu tio n E x p lo re r pe titlul
proiectului, apoi Add, i N ew Item... n dialogul care apare, alegei din
panoul Template, iconul XML File. Completai cmpul Name cu Elevi.xml.
n editor scriei urmtorul document:
<elev>
<nume>Costea Andrei</nume>
<scoala>C.N. Andrei Muresanu</scoala>
<clasa>a IX-a C</clasa>
<profil>stintele naturii</proil>
</elev>
C apitolul 9. X M L cuC # 273
<alev>
<nume>Nicoara Alina</nume>
< s c o a l a > G r . Sc. I n d u s t r i a l n r l < / s c o a l a >
<clasa>a Xl-a B</clasa>
<profil>telecomunicatii</profil>
</elev>
< /ab 3o l v e n ti>
using System.Xml;
F o rm l
Elevi
i . Clasa: |aXII-aA !
'
Profil: matematica-informatica 1
t i
i
Important!
D escrcarea fi ie re lo r X M L de pe In te rn e t
n ultimii ani, multe site-uri i bloguri expun clienilor un format XML cunoscut
sub numele RSS (Really Simple Syndication), n scopul distribuirii de coninut care
se schimb frecvent (tiri, sumarul coninutului unui site sau ntregul coninut,
posturi pe blog, etc).
Un furnizor de coninut (site, blog) public de regul un link (feed link) la care
utilizatorii subscriu cu ajutorul unor programe specializate (feed reader).
Subscrierea se face simplu, copiind link-ul din Web brow ser n feed reader. Mai
departe, coninuturile noi se descarc n mod automat, iar utilizatorul este ntiinat
cnd acest lucru se petrece. Practic, se descarc fiiere XML.
Cu .NET putei crea propriul feed reader (agregator). Nu vom face acest
lucru aici, ci vom arta ct de simplu putei descrca un fiier XML de pe Internet
sau un feed RSS.
Aplicaia DownloadXml
Urmai paii:
u s i n g S y s t e m . Xml;
u s i n g System.Net;
Observaie:
Pe numeroase site-uri i blog-uri vei gsi feed link-uri pentru subscriere. Iat
cteva link-uri alese aleatoriu:
http://www.preferredjobs.com/rss/rss2.asp
http://sourceforge.net/export/rss2_sfnews.php?feed
http://newsrss.bbc.c o .uk/rss/newsonline_uk_edition/world/rss.
x m l
using System;
using System.Xml;
class Program
1
s t a t i c v o i d M a i n ( s t r i n g [] args)
{
// Crem un r e a d e r (instan a clasei) i
// ncrcm fiierul
XmITextReader reader =
new XmITextReader ("crti.xml");
De reinut:
Metoda R e a d () a clasei x m ir e x tR e a d e r citete i returneaz
urmtorul nod din stream.
Proprietatea N o d e T y p e a clasei x m l N o d e este o enumerare ai crei
membri reprezint tipurile de noduri din document. Studiai aceast
enumerare pentru a vedea c exist mai multe tipuri de noduri dect n
acest exemplu.
Cu ajutorul clasei x m l T e x t R e a d e r obinei coninutul XML dintr-un fiier
sau dintr-un stream. n plus, are calitatea c v permite s analizai i s
prelucrai acest coninut.
C apitolul 9. X M L cu C# 279
Crearea c o n in u tu lu i X M L cu X m IT e x tW rite r
$
Aplicaia XmITextWriterExample
u s i n g System;
using System.IO;
using System.X m l ;
// Titlul crii
w r i t e r .W r i t e S t a r t E l e m e n t (" T i t l u " );
writer.WriteString("Amintiri din copilrie");
w r i t e r . W r i t e E n d E l e m e n t ();
C o n s o l e .R e a d L i n e ();
} // M a i n ()
}
De retinut:
Probleme propuse
Partea a III - a
Baze de date
Scopul acestei pri a lucrrii este acela de a v ajuta s accesai bazele de date
relaionale cu C#.
Capitolul 10
In stru m en te de lucru
S G D B -u ri - n o iu n i generale
Calitile
i SGDBR-urilor
n tre in e datele.
Un SGDB ine evidena fiecrui fragment de informaie. Utilizatorii nu
trebuie s se preocupe acest aspect.
Previne in co n s is te n a datelor.
284 P artea a III - a. B aze de date
A s ig u r a to m icita te a o p e ra iilo r.
Operaiile elementare, dar i grupurile de operaii (tranzaciile) se
garanteaz fie c vor fi complet executate, fie c nu vor avea nici un
efect. n oricare dintre situaii, baza de date rmne ntr-o stare
consistent.
Exist i alte firme ale cror sisteme de gestiune a bazelor de date au un segment
de pia bine delimitat, dar mult mai restrns dect a celor menionate.
In acest punct trebuie s adugm rolul tot mai important pe care l are n
acest moment SGDB-ul MySQL. Se utilizeaz ca free software, sub GNU General
Public Licence (GPL). Este foarte popular ndeosebi pentru aplicaii Web, fiind
disponibil pentru mai multe sisteme de operare.
Tehnologia A D O .N E T - introducere
2. integrarea XML.
ADO .NET este strns legat de XML. XML este folosit intern de ADO.NET ca
s menin datele n cfafasef-uri i s rein relaiile i constrngerile ntre tabele.
Mai mult, suportul pentru XML este integrat in ADO.NET. Se pot produce scheme
XML, se pot transmite date cu ajutorul documentelor XML.
A rh ite c tu ra A D O .N E T
1. Furnizorii de date
Un furnizor de date (data provider) asigur conectarea la o surs de date
(data source). Sursa de date poate fi un fiier text, un document XML, o baz de
date, etc. Totodat un furnizor de date suport accesul la date i manipularea
286 P artea a III - a. Baze de date
Interfaa cu utilizatorul
- D a t a P r o v id e r
Data Reader
Data Adapter
Command
Connection
** T.
XML v,
Baza de date :,
, f >; L v
Pentru a nelege cum sunt definite n .NET aceste clase, vom lista numele acestor
clase pentru doi furnizori de date: S q l S e rve r i O LE DB .NET. Reamintim c n
spaiul de nume S ystem .D ata.S qlC lient sunt clasele furnizorului de date S q l
S erver, iar n spaiul de nume System .Data.O leD b sunt cele ale furnizorului de
date, OLE DB.
Clasele specifice celor doi data provider-'t sunt:
S y s t e m . D a t a .S q l C l i e n t .S q l D a t a R e a d e r
S y s t e m .D a t a .O l e D b .O l e D b D a t a R e a d e r
S y s t e m . D a t a . O d b c .O d b c D a t a R e a d e r
O r a c l e .O r a c l e C l i e n t .O r a c l e D a t a R e a d e r
2. Seturile de date
Dataset-ul este o component major a arhitecturii .NET. D a t a S e t este
clasa care definete un dataset. Un dataset este o colecie de obiecte D a t a T a b l e
care pot fi legate ntre ele cu obiecte de tip D a t a R e l a t i o n . Dafasef-urile preiau
de la data provider-i informaiile necesare din sursa de date sub forma unei cbpii
reduse a bazei de date. Prin urmare, un dataset poate include o baz de date
relaional cu tabele, relaii, vederi. Utilzatorul opereaz asupra tabelelor din
dataset, care sunt practic o copie a tabelelor reale din baza de date. Deoarece un
dataset este un obiect, cahe-u\ pentru datele sale este n memorie.
Dafaset-urile implementeaz modelul de lucru deconectat de baza de date.
Cnd este necesar, cfafasef-urile transmit bazei de date modificrile operate
asupra datelor.
Clasa D a taSet, ca i celelalte clase care lucreaz cu un dataset se gsesc n
spaiul de nume System .Data. Tabelul urmtor descrie aceste clase:
288 P artea a III - a. B aze de date
DataSet Obiectele sale descriu schema ntregii baze de date sau a unei
submulimi a sa. Conine tabele i relaiile ntre ele.
DataTable Obiectele reprezint o singur tabel din baza de date. Conine
rnduri i coloane.
DataRow Reprezint un singur rnd ntr-o tabel.
DataColuran Reprezint o coloan ntr-o tabel.
DataView Obiectele sorteaz datele. Nu sunt incluse ntr-un D a t a T a b l e
DataRowView Obiectele reprezint un singur rnd ntr-un DataView.
DataRelation Reprezint o relaie ntre tabele. De exemplu, o relaie de cheie
p rim a r -ch e ie strin
Constraint Descrie o constrngere n tabel, cum ar f i unicitatea valorilor ntr-o
coloan cheie primar.
Twnptatss:
V isu al S tu d io in s t a lle d t e m p la t e s
cO
ip
About Sox Appcaon Application Assembly Class Code Fe DataSet Debugger
Configurai... ManifestFe Informai... Visua2 r
i ti m
Interface U N Q to 5QL local MOI Parent Resources Fe Settings Fe Text Fe
Classes Database Form
i u
User Control User Control Windows Form XM l Fe
(WPF)
An empty SQ L Server database for service-based data access
Mame: : Scoala.mdf
C apitolul 10. B aze de date i A D O .N E T . N o iu n i introductive 289
! The database you selected is new or does not contain any objects. Click Finish to create an empty dataset. ;
: Once database objects are added to the database open th e empty dataset in the Dataset Designer to j
i reconfigure the dataset. j
DataSet name:
{WtatJ&e Explorer B Q
; c \ j i Data Connections
i 3 U j Scoala.mcff
* C il Database Diagrams
a pEES
| -t Views !, . AcfdMewTaWe
| + C il S to re d
Mew Query
* 1 Funciei
ti _1 Synoni 2 ] Refresh
; * CCi Types
Properties
ZA Asseml ' a
290 P artea a III - a. B aze de date
: Insert Column
: Delete Column
Relationships..,
.J-
'1 Column Name Data Type Allow Nulls
ll IdElev int
ii Nume nvarchar(30)
|j Prenume nvarchar(30) 0
j ! W Versta 33 -V."1 0
-i ':1' -
i ' nt Ea
i " " money
1:
! il nchar(lO)
9. Salvai proiectul i tabela apsnd butonul Save AII. n dialogul Choose Narne
introducei numele tabelei: Elevi.
10. Pentru a nsera (design time) cteva rnduri cu date n tabel, expandai
nodul Tables n D atabase E xplorer. Click dreapta pe tabela E l e v i i
selectai Show Table Data.
3 N Add N ew Trigger
N ew Q u ery
. ^
O pen Table Definition
_i Views j
ic ZI Stored Pr S h o w T ab le D a ta
PuTW+ivVid c
11. S-a deschis Query Designer. AiPi putei introduce manual date n tabel i
putei efectua interogri. Completai cteva rnduri, ca mai jos. Observai c pe
coloana i d E l e v serverul nu v permite s introducei valori, deoarece este
coloan Id e n tity i aceasta nseamn c SQL S erver ii atribuie valori n mod
automat:
m * IM ' [S * 3 _. : ^ ^ _3.
Elevi: Q uery(...L E\SC O L A .M D F) d b a fle v i: J ^ X ^ C O A t A ^
Pascu loan 18
9 Nedelcu Valentin 17
3 Pop Andrei 19
4 Ilie loan 18
* i NULL NULL NULL
292 P artea a III - a. B aze de date
12. Dac dorii s adugai i alte tabele bazei de date coala, de pild tabelele
Clase, Pr o f e s o r i , M a t erii, e foarte simplu: facei click dreapta pe Tables
n Database E x p lo re r i alegei New Table., apoi repetai paii 6...11.
Nu vei face b u ild acestui proiect, pentru c aplicaia nu execut nimic. Vom vedea
n seciunile urmtoare cum ne conectm la baza de date i cum o interogm
programatic.
De reinut:
O cheie prim ar (p rim a ry key) identific n mod unic fiecare rnd ntr-o
tabel. Cheia primar include o coloan sau o combinaie de coloane. Nu
pot exista dou rnduri distincte ntr-o tabel care s aib aceeai valoare
(sau combinaie de valori) n aceste coloane.
O co lo a n id e n tita te (Id e n tity colum n) identific n mod unic fiecare rnd
ntr-o tabel, iar valorile sale sunt generate de ctre baza de date. Deseori
o coloan identitate e desemnat i cheie primar.
v a r c h a r (n ) este un tip de dat specific SGDB-urilor, care reine un set
de caractere de lungime variabil, dar care nu depete n. Pentru SQL
Server 2005, n poate fi maxim 8000 bytes.
Butoanele
panourilor
m .s S = ! 3
Q u e ry 4: Q uery...E \S C O A LA .M D F) start Page
(All Columns)
plldE lev Diagram
0N um e
b/j Prenume
0 Varsta
Show Result
Pane
Executarea in te ro g rii
Pentru executare acionai click pe butonul Execute SQL (butonul cu semnul
exclamrii) sau de la tastatur Ctrl + R.
n panoul de rezultate, se afieaz:
Comanda SELECT
SELECT este utilizat pentru selecatrea datelor dintr-o tabel. Rezultatul
este retumat ntr-o form tabelar, numit result set.
Sintax:
E xem plu:
Introducei n SQL Pane comanda urmtoare, dup care o executai cu un
click pe butonul Execute SQL:
Putei face acest lucru manual, sau bifai n Diagram Pane coloanele
corespunztoare.
Sortare
Ca s introducei criterii de sortare n comanda SELECT, utilizai Panoul
Criteriilor (selectai o opiune din coloana Sort Type) sau le introducei manual.
Exemplu:
Introducei n SQL Pane comanda:
Rezultat:
Nume Prenume
Ilie loan
Nedelcu Valentin
Pascu loan
Pop Andrei
Clauza W HERE
E xem plu:
Introducei n SQL Pane comanda:
Rezultat:
Sintax:
I N S E R T I N T O nume_tabel
V A L U E S valoarel, valoare2, ...
Exemplu:
; Introducei n SQL Pane:
i
INSERT INTO Elevi (Nume, P r e n u m e , V a r s t a )
V A L U E S ('Florea', ' C o n s t a n t i n ' , 99)
Rezultat:
jj Pentru a vedea rezultatul, avem nevoie de un result set ntors de o
d instruciune s e l e c t . Introducei interogarea:
11 Pascu loan 18
I2 Nedelcu Valentin 17
h Pop Andrei 19
j4 Ilie loan 18
{7 Florea Constantin 99
Comanda UPDATE
Comanda este utilizat pentru modificarea datelor ntr-o tabel.
296 P artea a III - a. B aze de date
Sintax:
UPDATE nume_tabel
SET c o l o a n l = v a l o a r e l , coloan2 = v a lo a re 2 , ...
WHERE coloan = v a lo a re
E x e m p lu :
Introducei n SQL Pane:
UPDATE Elevi
S E T V a r s t a = 104
W H E R E P r e n u m e = 'loan'
R e z u lta t:
Pentru a vizualiza rezultatul introducei n SQL Pane interogarea:
3 Pop Andrei 19
4 Ilie loan 104
2 Florea Constantin 99
Comanda DELETE
Comanda este utilizat pentru tergerea rndurilor dintr-o tabel.
Sintax:
E x e m p lu :
Introducei n SQL Pane comanda urmtoare, dup care executai-o cu click
pe butonul Execute SQL:
R e z u lta t:
Pentru a vizualiza rezultatul introducei n SQL Pane interogarea:
C apitolul 10. B a ze de date i A D O .N E T . N o iu n i introductive 297
2 Nedelcu V aentin 17
|:3 Pop A ra x i 19
Sintax:
E xem plu:
Lucrm cu aceeai baz de date, coala. Introducei n SQL Pane
comanda urmtoare, dup care executai cu un click pe butonul Execute SQL:
Sintax:
Exemplu:
Introducei n SQL Pane comanda urmtoare, dup care o executai cu un
click pe butonul Execute SQL:
Rezultat:
n Database Explorer acionai click drept asupra numelui clasei i selectai
Open Table Definition:
Exemplu:
Introducei n SQL Pane comanda pentru tergerea coloanei D i r i g i n t e :
A L T E R T A B L E Clase
D R O P C O L U M N Diriginte
Rezultat:
Sintax:
Exemplu:
Vom terge tabela Clase. Introducei n SQL Pane comanda urmtoare,
dup care o executai cu un click pe butonul Execute SQL:
Rezultat:
C apitolul 10. B aze de date i A D O .N E T . N o iu n i introductive 299
Controlul DataGridView
Aplicaia DataGridViewExample
Realizm un proiect de tip consol, cate conine o baz de date cu o singur
tabel. Informaiile din tabel se vor afia ntr-un control D ataG ridV iew n
momentul pornirii aplicaiei. Urmai paii:
IlM illL :
Cursor Default
DataMember
I(none)
Defau
* m r
Dock 3 {J J Other Data Sources
EditMc 9 ( S Project Data Sources
Enable 3 \|] SportDataSet
Enable 3 Sportivi
Gener, S - 2 1 Forml List Instances
GridCd
La rulare obinei:
V arianta a 2-a
Procedai dup cum urmeaz:
Paii 1, 2, 3, 4 sunt identici cu cei specificai anterior. Continuai astfel:
Start I
SportDataSet
j rjj Add New Data Source...
| bi 0 ' - ^ Tables
i 0 ZD Sportivi
i 0 1 ^ 3 Views
| 0 U rjJ Stored Procedures
8. Facei B u ild i rulai cu F5. Vei obine popularea controlului cu datele din
tabel.
V arianta a 3-a
Procedai astfel:
Paii 1, 2, 3, 4 sunt identici cu cei ai aplicaiei anterioare. Continuai astfel:
i B i j | J D a t a C o n n e c tio n s i Sportivi . B M Ia l
B 0t Sport.mdf
IdSportiv
B Q | Database Diagrams
3 GJ Tabtes Nume
S 5 3 Sportivi Prenume
33 IdSportiv DataNasterii
3] Nume Sportufracticat
T] Prenume
53 DataNasterii
lai Fi.GetData ()
,53 SportuIPracticat ;l
ffi G 2 Views I!
Observaii:
> Toate cele trei variante de populare a controlului D ataG ridV iew realizeaz o
le g a re a controlului la sursa de date printr-un obiect de tip BindingSource.
> Despre clasele DataSet, BindingSource, Table Adapter, dar i despre
modul n care populai programatic un control D ataG ridV iew , vom discuta n
seciunile urmtoare.
1. n Form D esiger acionai click pe sgeata din colul dreapta sus al controlului
D ataG ridV iew , apoi alegei Edit Columns.
Ed* Columns...
Edit Columns
:
Add Column...
: (Name)
. Indfcates the nane uswi in code to identify the
; object.
I c* !
304 Partea a III - a. B aze de date
Capitolul 11
11 Nedelcu Valentin 17
Executm dou operaii asupra tabelei E le v : inserarea unui rnd nou i selectarea
rndurilor.
Urmai paii:
u si n g System;
using System.Data.SqlClient;
C apitolul 11. A p lica ii cu baze d e date n m o d elu l con ectat 305
namespace ConsoleAoplicationl
{
class SQLDataProvider
{
static voicl Main (string [] args)
1
// Construim stringul de conectare
// (cozmectioa string)
string connString =
server = .\sqlexpress;
Database=Scoa.la.mdf ;
trusted_connection=True;
AttachDbFileName =
C :\DatabaseExample\DatabaseExample\bin\Debug\Scoala.m d f " ;
// Pregtim interogrile
string sqll = @"SELECT * FROM Elevi";
string sql2 = 0"INSERT INTO Elevi
(Nume, Prenume, Varsta)
VALOES
('Axente', 'Mihai', 20)";
// nchidem reader-ul
II pentru a putea fi refolosit
reader.Close ();
reader = c m d .ExecuteReader();
_iJ
Executarea interogrii
// cod ...
Este uor de remarcat similitudinea ntre clasele furnizorului OLE DB i cele ale
SQL S erver 2005. Metodele acestor clase sunt de asemenea similare.
Aplicaia OleDbProviderWinApp
E3MicrosoftAccess
: Eiier d ta r e V g u a b a re ' In se ra re In strj/n e n te
; ft Persoane :* Tabel
Nume cmp I Tip de date I
9 ID AutoNumerotre
Nume Text
Prenume Text
DataNasteni Dat/Or
// Stringul de conectare
string connString =
@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=
C :\teste\Persoane.mdb;";
// Stringul de interogare
string sql = @"select * from Persoane";
// Crem conexiunea
using (conn = new OleDbConnection(connString))
{
Capitolul 11. A p lic a ii cu baze de d a te n m odelu l conectat 311
// Se execut interogarea
OleDbCommand cnd = new OleDbCommand(sql, conn);
reader = cmd.ExecuteReader();
De rein
> ut:
Aplicaia OdbcExcelExample
A | B | C D I
1 IdProdus Denumire Pret Cantitate
2 1 Paine 2 200
3 2 Lapte 3 23
4 3 Iaurt 4 45
5 4 Cola 5 21
6
C apitolul 11. A p lic a ii cu baze de date n m o d elu l con ecta t 313
// Stringul de conectare
string connString =
@"Driver={Microsoft Excel Driver (*.xls)};
Driverld=790;
D b q = C :\teste\Produse.x l s ;
DefaultDir=C:\OdbcExcelExample\OdbcExcelExample\bin\Debug" ;
// Stringul de interogare
// [Foaiel$] poate fi [sheetl$] dup caz
string sql = @"select * fro m [Foaiel$]" ;
// Crem conexiunea
using (conn = new OdbcConnection(connString))
{
conn.Open(); // Deschidem conexiunea
// Se execut interogarea
OdbcCommand cmd = new OdbcCommand(sql, c o nn);
reader = c m d .ExecuteReader();
La rulare obinei:
12 | Lapte |3 ; 23
i3 ; Iaurt 14 45
|4 Cola 121 - :
* 1 i ; y
<
Observaii:
> Stringul de conectare precizeaz driver-ul Excel i ID-ul su. Dbg indic
sursa de date i calea de director, iar DefaultDir este directorul implicit.
> Codul C# este similar cu cel pentru provider-ii OLE DB sau SQL Server.
Aplicaia OdbcMySQL
Scopul acestei aplicaii este acela de a arta modul n care v putei conecta
la o baz de date M ySQ L cu C#, utiliznd provider-ul ODBC.
Diferena estenial fa de modul de conectare al aplicaiei anterioare
const n faptul c vom construi un Data Source Name (DSN) cu ajutorul unui
utilitar Windows. Acest DSN se utilizeaz apoi n stringul de conectare.
Separm tema n trei seciuni:
User DSN JSystem DSN j Fite DSNl| Drivers j Treeing j Connection Pooling | About j
Driver Add...
Name I V
Microsoft Paradox Driver .db ) 4
Microsoft Paradox-Treibe f.d b I 4
Microsoft Text Driver ( .be; .csv) 4
Microsoft Text-T reiber ('.tit; " csv) 4
Microsoft Visual FoxPro Diver 6
Microsoft Visual FoxPro-T eiber 6
>rmect to
MySQLODBC 351 Driva 3
to you.
SQL Native Client 2 ;
SQLServer 2
<. L >
Help
Finish Cancel
C o n n e c t c r/O D B C
M yS Q L
Password
Database
C) Crearea aplicaiei C#
string connString =
"dsn=ConexiuneMySQL;User=root;Password=iuliuta";
string sql = 0"select * from elevi";
OdbcConnection conn = n u l l ;
OdbcDataReader reader = nu l l ;
La rulare, controlul D ataG ridV iew afieaz datele din tabela E le v i , obinute n
urma interogrii SELECT:
Precizri:
C apitolul 12
DataSet ds = n e w D a t a S e t ();
DataSet ds = n e w D a t a S e t ( " n u m e D a t a S e t " ) ;
// Creeaz d a t a s e t - ul
DataSet ds = new DataSet);
Pentru a ncrca n dataset toate tabelele din baza de date, utilizai alt versiune a
metodei Fiii:
d a .Fiii(ds);
A cc e s a re a ta b e le lo r ntr-un d a ta s et
Un dataset poate s conin mai multe tabele. Acestea sunt obiecte de tip'
DataTable care se pot accesa indexat, ncepnd cu indexul 0. de exemplu :
Rndurile unui unui obiect DataTable se obin din proprietatea Rows, care
suport indexarea :
A doua versiune actualizeaz baza de date opernd toate modificrile care s-au
fcut n tabela transmis ca argument:
// Creeaz datasei-ul
DataSet ds = new DataSet();
...
// Se modific datele n dataset
n
Aplicaia UpdateDatabase
/J i ifc___
- j j librarieD ataS et
i ^ Carb r Cod
iti\ Cod T*Ju
Jtel Titlu
A U Ol
bei Autor
Pre
ti Pre
Prin aceast aciune am cerut ajutorul mediului integrat, care a generat pentru
noi O clas CartiTableAdapter. Aceast clas conine un obiect de tip
SqlDataAdapter, un obiect de tip SqlConnection i un obiect de tip
SqlCommand, astfel nct nu mai trebuie s ne procupm de deschiderea
manual a unei conexiuni la server.
// Declaram o referin la d a t a s e t
private Li b r a r i e D a t a S e t libDataSet = n u l i ;
// Crem ur. d a t a s e t
l i b D a t a S e t = new L i b r a r i e D a t a S e t ();
0 rnduri afectate
< >
Observaii:
* Mediul VCSE creeaz cele dou fiiere ale bazei de date (.mdf i .LDF) n
folderul de baz al aplicaiei, la un loc cu fiierul .csproj. n momentul n
care facei B u ild cu F5 (modul depanare), se face o copie a celor dou
fiiere n folderul \Bin\Debug, iar aplicaia se lanseaz i lucreaz cu
aceste copii. La noi rulri cu F5, nu se mai face B u ild dac nu ai adus
modificri n cod, ci numai lansri n execuie. Constatai c baza de date
din \Bin\Debug se actualizeaz. Dac ai operat modificri n cod, atunci la
un F5 se face i B uild i baza de date original se copiaz peste cea din
\Bin\Debug.
* Stringul de conectare se genereaz n mod automat la crearea bazei de
date cu ajutorul mediului integrat. Se poate vizualiza astfel: n Solution
Explorer, click dreapta pe fiierul app.config i selectai Open. Vei
constata informaiile de conectare se pstreaz n format XML.
Atribuirea dataGridViewl.DataSource = b s ; leag controlul de
dataset, astfel nct orice modificare operat in celulele controlului, se
transmite n mod automat tabelei din dataset.
D ataset-u rile i X M L
d s . W r i t e X m l ( @ " C :\ d a t e .xml");
d3.ReadXML("C:\date.xml");
Exemplu:
Ne ntoarcem la aplicaia UpdateDatabase, realizat anterior. Introducei ca
ultim linie n corpul metodei de tratare a evenimentului C lick pentru butonul
Sa/veaza, apelul:
C ontroalele i legarea d a te lo r
Aplicaia SimpleDataBinding
public F o r m l ()
{
InitializeComponent();
// Legm proprietatea Text a butonului (primul
// parametru) de proprietatea Text a text box-ului
buttonl.DataBindings .Add("Text", textBoxl, "Text");
}
5. Rulai cu F5.
Facei click pe buton, apoi un click n text box ca s primeasc focusul. n text box
se afieaz Salutare! . Dac introducei text n textbox, eticheta butonului se
modific corespunztor.
328 P artea a III - a. B aze de date
Salutarei
jSalutaref
Aplicai acest tip de legare atunci cnd vrei s afiai o list de valori din
sursa de date. Controalele care suport legarea complex sunt DataG ridView ,
ListB ox, C om boB ox, C h e cke dL istB o x. Aceste controale au de proprietatile
DataSource i DataMember, cu ajutorul crora le putei lega la tabela unei baze de
date, astfel:
dataGridViewl.DataSource = librarieDataSet;
dataGridViewl.DataMember = "crti";
^ JjIDConcert I in t
TipConcert n varchar(20) 0
SustinutDe nvarchar(50)
Data datetime
Locaie nvarchar(20) 0
Completai cteva rnduri cu date n tabel.
; ' --
rj g?) SpectacoieDataSet
;t ,-J E S 3 v
g DataGridView
; ItetBox
; 23 Dfaite
V )., U1 n J IP, I -
7. Rulai cu F5.
Vei obine:
ncercai s in g u ri:
n proiectul anterior, tergei din designer tray apsnd tasta delete toate
referinele. tergei i gridul de pe form. n fereastra Data S o u rc e s , selectai
Details, apoi tragei cu mouse-ul tabela pe suprafaa formei. Pe suprafaa formei
vor aprea patru controale de tip T e xtB o x i un D ateTim ePicker. Fiecare control
este legat la una dintre coloanele tabelei.
H r n r a j f f ' ~ "W w m fnm
1 H + j 2 of 4
IDConcert: :|2
Locaie: | Bucureti
-- - ------------------------------1
Toate controalele indic acelai rnd din tabel. Navigarea de la un rnd la altul se
face cu ajutorul butoanelor sgeat din controlul T o o lS trip din partea de sus a
formei.
f ID C o nce rt
TipC oncert
S ustinutD e
D ata
Locaie
i l
O-
O o
O'
tJ-- A 1 -1
(Name) bindingSourcel 't . z *
AllowNew True :S (ApplicationSettings)
DataMember 1 (Name) b in d in g S o u rc e l
(none) ! AllowNew True
BataMember:;v*WJ3f I Concerte
B i j J Other Data Sources C None
S i j j ] Project Data Sources ASSESS
?] SoectacoleDataSet
10. Selectai controlul T extB o x cel mai de sus. In fereastra P ro p e rtie s, expandai
itemul Data B in d in g s i setai proprietatea Text la valoarea SustinutDe :
;B (DataBindings)
(Advanced)
Tag (none)
(none) V
if] IDConcert
[H TipConcert
jO SustinutDe
11. Executai aceleai operaii de la pasul 10, pentru urmtoarele trei textbox-uh,
cu diferena c vei lega proprietatea Text la celelalte coloane ale tabelei.
12. La ncrcarea formei, vom umple dataset-u!. Dublu click pe suprafaa formei,
n Editorul de Cod scriei:
Se obine:
334 P artea a III - a. B aze de date
H Q
1
| Metallica [Eminem j
| Mickey Olivei j Hip Hop j
: Martina McBride ------- !
i j Bucureti i
04.37.2003 - 1
1
La click n list box, textele se modific n controalele text box n mod automat,
astfel nct toate controalele de pe form indic acelai rnd din tabel. Valorile
celulelor tabelei se pot edita din text box-uri, iar modificrile n baza de date sunt
persistente.
C apitolul 13. R elaii ntre tabele 335
C ap itolul 13
n tabela clase avem un cmp clasa, care reprezint numele clasei (ex.
Xll-B). l setm cheie primar. n tabela Elevi introducem un cmp cu acelai
nume. Nu dorim s existe elevi pentru care cmpul clasa are o valoare care nu
exist n tabela Clase. Impunem o constrngere de tip foreign key-prim ary key.
Este o constrngere referenial. Clase este tabela printe, iar Elevi, tabela
copil. Un rnd al tabelei printe poate s refere multiple rnduri n tabela copil.
Aplicaia coala
Aplicaia creeaz baza de date i tabelele precizate mai sus, impunnd o
constrngere de cheie strin-cheie primar. Dac un rnd n tabela clase se
terge, atunci dorim s se tearg toate rndurile corespunztoare din tabela
Elevi pentru a pstra integritatea datelor. Vom seta regula de tergere pentru
aceast relaie: N CASCAD.
Atentie
t !
V sugerm s nu ocolii acest proiect, deoarece pe structura lui vom lucra
n temele urmtoare, unde va fi dezvoltat i completat.
I Clasa nvarchar(50)
NrElevi int
Diriginte nvarchar(50) 0
336 P artea a III - a. Baze de date
Tabela E l e v i
Column Name Data Type Allow Nulls
; K? IdElev int
i Nume nvarchar(50) 0
: Media real 0
Dup completarea schemei, introducei cteva rnduri n fiecare tabel.
Clase m a o m m
! V Clasa 9 IdElev
! NrElevi Nume
' Diriginte Media
Clasa
Relationship name:
Lass*ss_
Primary key table: Foreign key table:
i Clase Elevi
Clasa Clasa
11. Din fereastra Data Sources, tragei cu mouse-ul tabela Clase peste gridul din
stnga al formei, apoi tragei tabela Elevi peste gridul din dreapta.
La rulare, se obine:
m im saB S S^m
[ . h O a s e . ^ a ^ ^ l a i w a r ^ 5^ ' ' x * C '. - - ' * . j
l< > ~
St
< . >'
71
338 P artea a III - a. B aze de date
Interogri. P ro c e d u ri stocate.
Continum s dezvoltm proiectul coala, nceput anterior. Opiunile din
meniuri nu sunt nc funcionale. Ca s fie, trebuie s interogm baza de date.
Dac vrem s introducem noi clase sau elevi, avem nevoie de comanda SQL
i n s e r t .Cnd vom dori s tergem din baza de date o clas sau un elev, aplicm
d e l e t e ,iar cnd modificm datele ne trebuie u p d a t e .
O ntrebare fireasc ar fi: cum trimitem aceste interogri serverului de baze
de date, din codul nostru C# ? O prim variant este s manevrm clasele
SqlConnection, SqlCommand, SqlDataAdapter. Este laborios dac Scriem tot
codul necesar.
Din fericire, mediul integrat ne ajut mult n aceast privin. Vom genera n
mod automat metode C# pentru clasele claseTableAdapter i
EleviTableAdapter. Aceste metode ncapsuleaz interogrile SQL sau
proceduri stocate. In continuare adugm interogri aplicaiei coala.
0 Use SQL s ta te m e n ts
Specfy a SELECT statement, and the wizard will generate a new stored procedure to select records.
C apitolul 13. R ela ii ntre tabele 339
C h o o se a Q u ery Type
Choose the type of Query to be generated
t t
W hat typ e o f SQL query would you like to use?
O SELECT w h ic h re tu rn s a s in g le va lu e
Returns a single value (for example, Sum, Count, or a ry other aggregate function),
O UPDATE
Changes existing data in a table.
O d elete
I INSERT INTO [d b o ].[Clase] ([Clasa], [NrElevi], [D irigirte]) VALUES (Clasa, NrElevi, Diriginte); 1
; SELECT Clasa, NrElevi, Diriginte FROM Clase WHERE (Clasa - Clasa)
[ Query Builder..
jil
* (All Columns)
t+jdasa
f+jNrElevi
1+)Diriginte
v.:
Y.
New Value A
Column
; Clasa @Clasa
NrElevi @NrE!evi V
Clasa
Nf elevi : !
Dirig ;___________ j
I Adauga j
claseTableAdapterl.Inserc{textBoxl.Text,
i n t .P a r s e (textBox2.T e x t ) , textBox3.T e x t ) ;
Close () ;
}
9,99 IX J
v.
!IX 23 Vemescu 7,75 XII
j Adauga j
'
342 P artea a III - a. B aze de date
mm
Choose a Command Type
TableAdapter q ue ry uses SQL statements or a stored procedure.
Type your SQL statem ent or use the Query Builder to c o n tru c t it. W hat d ata should be loaded Into the table?
W hat d ata should the table load?
SELECT COUNTS) FROM Clase - - - ">
WHERE Clasa @Clasa[ j
S
SET NOCOUNT ON;
SELECT C O U N T (*) FROH Clase
UHERE Clasa Clas;
int intreg = O ;
if (!int.TryParse(textBox2.Text, out intreg))
{
MessageBox.S h o w (
"Nr elevi trebuie s fie numr intreg!);
return;
}
i f ( (int)claseTableAdapterl.MaiExistaClasa(
textBoxl.Text) == 1)
{
MessageBox.S h o w ("Clasa exista deja!");
return;
}
claseTableAdapterl.I nsert(textBoxl.T e x t ,
i n t .P a rse(textBox2.T e x t ) , textBox3.T ext);
C l o s e ();
>
IM P O R TA N T! . . _
Metoda I n s e r t , ca dealtfel toate metodele care conin interogri, pot s
arunce excepii. De aceea, trebuie incluse n blocuri try-catch.
Noi nu am fcut-o aici, pentru claritate.
Tem de lucru:
Implementai facilitatea de adugare a unui nou elev n baza de date la
selectarea opiunii Adauga elev din meniul Elevi. Trebuie s creeai o funcie
suplimentar care interogheaz baza de date determinnd dac valoarea pe care
o introduce utilizatorul pentru cmpul Clasa exist sau nu n tabela clase.
Pentru a terge o clas din baza de date, este nevoie de o funcie care
ncapsuleaz comanda SQL DELETE. Procedm astfel:
I FormDeleteClasa ^ (
( terge j
__________________________
C apitolul 13. R e ia i ntre tabele 345
12. n primul dialog, selectai Use SQL tatem ents. Apsai Next. n al doilea
dialog, selectai DELETE. n Query Bufder, editai interogarea astfel:
DELETE F R O M Clase
WHERE (Clasa = @Original_Clasa)
La execuie vei constata c atunci cnd tergei o clas, se terg i toate rndurile
orfane din tabela Elevi, conform regulii de tergere n cascad pe care am impus-o
pentru meninerea integritii datelor la crearea constrngerii de cheie strin.
346 P artea a III - a. B aze de date
Tem de lucru:
Implementai facilitatea de tergere a unui elev, la selectarea opiunii terge
elev din meniul Elevi. Elevul va fi cutat dup cmpul id E le v .
; :* (All Columns)
v Claia
I .MrElevi
j v j Diriginte
0
Column Alias
j Diriginte Clase
Clasa Clase 0
3 / , J V v>. :'
j i Data Connections
ii coala.mdf IdElev
Clasa
4r _ J Database Diagram: ' NrEievi Nume
I J Tables Diriginte Media
t: J 3 Oase Clasa
+ I U Elevi *. Wr-ri *4SV f|
Views I f ti Fill.CetData () j &
i Q j ViewDirigClase. sau DeleteClasa (@Origiral_Oasa) p a FiB,GetData Q
Diriginte Clasa av I
H I ? IX
; Colcer X
: Vaida XI
: Berende ^XII
V
*
< >
5. n View Designer, selectnd opiunile din figura de mai jos, vei obine
interogarea necesar:
C apitolul 13. R elaii ntre tabele 349
<
12. Acionai dublu click pe opiunea Media pe clase din meniul Rapoarte, aflat pe
F o rm l. n corpul metodei de tratare scriei:
8. Rulai cu F5.
350 P artea a III - a. B aze de date
3 H M W F p
I Clasa Diriginte MediaCla sei A I
Vmescu j 9,989999
77111 l
;X ; Colcer 17,204933 92370 t
jXII IBerende : 7,75
* ! ! j V
Probleme propuse
2. Creai o aplicaie care ntreine o baz de date cu numele Firm a. Baza de date
conine dou tabele: Clieni si Comenzi. Tabelele vor defini cel puin
urmtoarele coloane: Clieni: (IDCIient, Nume, Prenume, Telefon) si Comenzi:
(IDCIient, Data, ValoareComanda). Aplicaia va implementa operaii de
adugare de Clieni si de Comenzi. Va permite de asemenea afiarea tuturor
clienilor, iar pentru fiecare client, se va afia valoarea total a comenzilor
sale.
Bibliografie
[1] Ecma T e ch n ica l C om m ittee 39 Task G roup
C# Language Specification 4-th Edition, june 2006
[2] Jesse Liberty. Programming Cff. 2-nd Edition, O Reilly 2002.
[3] A n d re w Troelsen . Pro C# 2CC8 and the .Net 3.5 Platform. 4-th Edition.
Apress 2008.
[4] M ic ro s o ft MSDN E xpress L ib ra ry 2008