Kontrole su komponente koje imaju vidljiv korisnički interfejs i mogu da intereaguju sa korisnikom. Primeri kontrola koje su ugrađene u sam .NET su Button, TextBox, ComboBox itd. Pored ugrađenih kontrola mogu se kreirati sopstvene kontrole koje će obezbediti određenu funkcionalnost aplikaciji. Postoji tri vrste ovih kontrola: kompozitne kontrole, custom kontrole i proširene kontrole. Kompozitne kontrole se kreiraju kombinacijom već postojećih kontrola. Custom kontrole se kreiraju iz početka i obezbeđuju sopstveni kod za iscrtavanje ovih kontrola. Proširene kontrole koje proširuju funkcionalnost postojećih kontrola.
Iz menija Project odabere se opcija Add User Control pri čemu se otvara AddNewItem dijalog prozor. Potrebno je dati ime kontroli i kliknuti na dugme Add.
Kompozitna user kontrola ima sopstveni dizajner koji omogućava dodavanje kontrola sa ToolBoxa. Moguće je dodavati metode, svojstva i događaje u kompozitnu kontrolu.
Kompozitna kontrola je klasa izvedena iz klase UserControl.
Primer kompozitne kontrole
public bool TimeEnabled |
Kompozitna kontrola prikazana na slici kreira se kombinacijom kontrola Label i Timer. Definisano je novo svojstvo ove kontrole TimeEnabled koje dozvoljava omogućavanje ili sprečavanje rada tajmera. U Tick događaju tajmera se na Label kontroli prikazuje tekuće vreme na računaru.
Korišćenje kompozitne kontrole
Nakon kompajliranja projekta koji sadrži kompozitnu kontrolu ona se automatski dodaje u ToolBox i može se prevlačiti na formu. Nakon prevlačenja na formu i selektovanja kontrole u njenom Property prozoru se pored svojstava nasleđenih od kontrola koje je sačinjavaju nalazi i svojstvo koje smo sami definisali. Ako postavimo svojstvo TimeEnabled na True vrši se pokretanje tajmera i na kontroli se prikazuje vreme na sistemu.
[ToolboxBitmap(@"C:SlikeArrow.bmp")] public partial class UserControl1 : UserControl { ..... |
Ukoliko ne definišemo ikonicu za našu korisničku kontrolu Visual Studio će joj automatski dodeliti podrazumevanu sliku. Ukoliko želimo da se na ToolBoxu pored oznake kontrole prikaže neka druga slika to postižemo dodavanjem atributa ToolboxBitmap, klasi koja predstavlja ovu kontrolu. Unutar atributa ToolboxBitmap treba specificirati sliku koja treba da se dodeli korisničkoj kontroli na Toolboxu.
Custom kontrole omogućavaju najveći mogući nivo konfigurabilnosti od svih ostalih kontrola. Custom kontrole nemaju podrazumevani izgled tako da je dizajner prazan sivi prozor. Mogu se dodavati komponente kao što su tajmeri i BackgroundWorkers komponente. Takođe je moguće dodavati i druge kontrole na dizajner ali one neće biti prikazane kao deo custom kontrole. Custom kontrola je izvedena iz klase Control koja obezbeđuje funkcionalnost neophodnu za interakciju kontrole sa ostatkom aplikacije. Npr. obezbeđuje funkcionalnost detektovanja prisustva miša, kao i svojstva kao što su ForeColor, BackColor, Visible, Location itd. Ključni zadatak u razvoju korisničkih kontrola je obezbeđivanje njenog vizuelnog interfejsa. Korisnički interfejs se obezbeđuje implementacijom OnPaint metode koja se izvršava kad god se kontrola renderuje na ekranu.
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = this.CreateGraphics(); } |
Klasa Graphics tj. njena instanca predstavlja površinu za crtanje vizuelnih elemenata kao što je forma ili kontrola. Ova klasa enkapsulira interfejs između sistema za renderovanje grafike i .NET frejmvorka. Pošto Graphics objekat mora biti pridružen vizuelnom elementu on se ne može kreirati direktno. Klase koje su izvedene iz klase Control imaju metodu CreateGraphics koja vraća referencu na Graphics objekat koji je pridružen kontroli. Graphics objekat ima metodu DrawLine koja se koristi za crtanje linije. Metoda DrawRectangle Graphics objekta koristi se za crtanje pravougaonika. Metoda DrawPolygon se koristi za crtanje različitih poligonalnih linija na osnovu tačaka koje ulaze u sastav poligona. Metoda DrawEllipse se koristi za crtanje elipse ili kruga, tj. krug je elipsa kod koga su velika i mala osa jednake. Metoda DrawString se koristi za ispis teksta. U primeru se pomoću metode this.CreateGraphics() pristupa Graphics objektu forme.
// definisanje olovke Pen p = new Pen(Color.Red, 3); |
SolidBrush br = new SolidBrush(Color.Beige); |
Pen objekat (olovka) je neophodan za crtanje linijskih oblika. Pen objekat dozvoljava da definišemo debljinu linije i boju linije. Brush objekat (četka) se koristi za ispunjavanje objekata i za ispis teksta. Iako postoji nekoliko Brush klasa, najčešće korišćena klasa je SolidBrush. Na primeru je prikazan jedan primer kreiranje olovke i četke.
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = this.CreateGraphics(); // definisanje olovke Pen p = new Pen(Color.Red, 3); // definisanje pravougaone oblasti Rectangle rect = new Rectangle(2, 2, 400, 300); // crtanje pravougaonika g.DrawRectangle(p, rect); // menjanje stila linije p.DashStyle = DashStyle.Dash; // crtanje linije g.DrawLine(p, 200, 0, 200, 300); g.DrawLine(p, 0, 150, 400, 150); p.Width = 5; p.DashStyle = DashStyle.Solid; // menjanje oblika kojim linija pocinje i zavrsava se p.StartCap = LineCap.Round; p.EndCap = LineCap.ArrowAnchor; g.DrawLine(p, 395, 3, 200, 150); |
Paint događaj forme se poziva svaki put kada forma treba da se prikaže na ekranu, kada joj se menja veličina, kada forma dobija fokus sa druge forme i sl. U Paint događaju forme se najpre pristupa njenom Graphics objektu. Kreira se instanca klase Pen, u našem primeru to je crvena olovka debljine 3. Zatim se kreira objekat Rectangle a zatim se pomoću metode DrawRectangle Graphics objekta vrši iscrtavanje pravougaonika na formi. Pomoću metode DrawLine vršeno je iscrtavanje linija na formi, pri čemu su definisani različiti oblici kojima linija počinje i završava se.
// definisanje poligona |
Na ovom primeru je nastavak prethodnog koda. Najpre se definiše niz tačaka a zatim se iscrtava poligon koji prolazi kroz te tačke. Definiše se četka kao instanca klase SolidBrush koja će služiti za bojenje unutrašnjosti poligona. Zatim se ponovo definiše olovka koja će se koristiti za iscrtavanje elipse. Pri crtanju elipse moraju se specificirati koordinate gornjeg levog ugla pravougaonika koji je opisan oko elipse, kao i širina i visina tog pravougaonika. Pomoću metode DrawString vrši se ispis teksta na formi , pri čemu se mora definisati, tekst koji se ispisuje, font kojim se vrši ispis teksta, četka koja se koristi za ispis, kao i koordinate tačke odakle ispis počinje.
Na slici vidimo grafičke objekte koji su iscrtani primerom na prethodnim kodovima.
OnPaint metoda sadrži kod neophodan za renderovanje vizuelnog izgleda kontrole. Ova metoda ima jedan parametar PaintEventArgs koji sadrži dva važna svojstva: ClipRectangle i Graphics. ClipRectangle svojstvo daje pravougaonik u kome se iscrtava kontrola. Graphics svojstvo daje Graphics objekat koji će predstavljati površinu za crtanje. Sve metode za iscrtavanje oblika zahtevaju koordinate početka crtanja. Gornji levi ugao kontrole ima koordinate (0,0). X-osa je po horizontali na desno, dok je y-osa po vertikali na dole. Širina kontrole je određena svojstvom Width. Visina kontrole je određena svojstvom Height.
U prozoru Add New Item kao šablon treba odabrati Custom Control. Time se kreira klasa izvedena iz klase Control. Unutar klase je generisan kostur OnPaint metode.
Primer Custom kontrole
public partial class CustomControl1 : Control |
U dizajner custom kontrole je dodat tajmer i njegov tajmerski interval je podešen na 1000 ms.
private void timer1_Tick(object sender, EventArgs e) { // novo iscrtavanje kontrole this.Refresh(); } |
U konstruktoru kontrole startuje se tajmer. U OnPaint metodi kontrole se definiše njen vizuelni izgled. To je u primeru pravougaonik ispunjen bojom u kome se prikazuje tekst koji predstavlja tekuće vreme na računaru. U svakom tajmerskom intervalu poziva se metoda Refresh odnosno vrši se ponovno iscrtavanje kontrole, tako da ona svake sekunde prikazuje tačno vreme.
Prikaz custom kontrole
Posle kompajliranja projekta u kome je kreirana Custom kontrola ona se pojavljuje u Toolboxu zajedno sa ostalim .NET kontrolama. Odatle se ona može prevlačiti na formu. Na slici je prikazana windows forma koja sadrži custom kontrolu koju smo prethodno kreirali.
Proširene (extended) kontrole su korisnički kreirane kontrole koje proširuju neku od postojećih .NET framework kontrola. Proširivanjem kontrole može se zadržati kompletna funkcionalnost kontrole i dodati nova svojstva i metode. Takođe je moguće promeniti i vizuelni izgled kontrole. Proširena kontrola predstavlja klasu koja je izvedena iz klase koja predstavlja odgovarajuću windows kontrolu. Npr. proširiti klasu Button da bi smo kreirali sopstveno dugme. Pored dodavanja novih metoda u proširenu kontrolu može se vršiti i prebrisavanje (overriding) postojećih metoda. Prebrisavanjem OnPaint metode može se promeniti vizuelni izgled kontrole.
Primer kreiranja proširene kontrole
class ClickButton : Button { int brojKlikova =0; public int Klikova { get { return brojKlikova; } } protected override void OnClick(EventArgs e) { brojKlikova++; base.OnClick(e); } } |
Želimo da kreiramo dugme koje će proširiti funkcionalnost klasične Button kontrole. Zato kreiramo klasu koja je izvedena iz klase Button. Unutar ove klase definišemo atribut brojKlikova koji će pamtiti koliko puta je korinik kliknuo na to dugme. Takođe, prebrisaćemo OnClick metodu, tj. metodu koja se izvršava nakon što korisnik klikne na dugme. Unutar ove metode inkrementiramo brojač klikova na dugme.
protected override void OnPaint(PaintEventArgs e) |
Sada želimo da našoj proširenoj kontroli promenimo vizuelni izgled. Zbog toga ćemo prebrisati OnPaint metodu klase Button. Pomoću svojstva ClipRectangle pristupamo pravougaoniku rect1 koji predstavlja prostor na kome će kontrola da se iscrta. Ovaj pravougaonik ćemo obojiti istom bojom kao što je i boja forme tako da on postane nevidljiv. Kreiramo novi pravougaonik rect koji je nešto manji od pravougaonika rect1. On samo služi da se unutar njega upiše elipsa koja će biti obojena nekom bojom. Na ovaj način naše dugme dobija elipsasti oblik. Unutar elipse ispisujemo broj klikova, kao i standardni tekst koji je definisan Text svojstvom dugmeta.
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void clickButton1_Click(object sender, EventArgs e) { Refresh(); } private void clickButton2_Click(object sender, EventArgs e) { Refresh(); } private void Form1_Resize(object sender, EventArgs e) { Refresh(); } private void clickButton3_Click(object sender, EventArgs e) { Refresh(); } } |
Sada ćemo na windows formu tri puta dodati našu proširenu kontrolu. Unutar klik događaja za dugmad pozivamo Refresh metodu da bi se nakon klika na dugme, ponovo izvršilo iscrtavanje dugmeta, tj. pozvala njegova OnPaint metoda.
Upotreba proširenih kontrola - GUI
Vidimo prikazanu windows formu koja sadrži 3 instance proširene kontrole koju smo napravili. Dugmad imaju elipsast oblik i pamte koliko je puta kliknuto na njih.