pv 7 c# · 2015-02-09 · in acest cod, data curenta (todaydate) evidentiata pe calendar este...

33
1 Proiect Vom construi o aplicatie care va folosi controlul MonthCalendar si alte controale noi. Controlul MonthCalendar Controlul MonthCalendar permite vizualizarea sau setarea informaţiilor de tip data. Este un obiect de clasă MonthCalendar. Câteva proprietăţi specifice ar fi: CalendarDimensions – stabileşte dimensiunile controlului de tip Calendar; FirstDayOfWeek – stabileşte prima zi din săptămână. Implicit este duminică; MaxDate – marchează ultima dată reprezentabilă pe calendar; MinDate – marchează prima dată reprezentabilă pe calendar; SelectionRange – marchează numărul maxim de zile ce pot fi selectate în control. Start – furnizează data de început a zonei selectate în control. ShowToday – precizează dacă data curentă este sau nu afişată în partea de jos a controlului. TodayDate – furnizează data curentă. Ce este interesant de remarcat, ca proprietăţile de tip dată, sunt manipulate prin intermediul unor obiecte de clasă DateTime. Câteva proprietăţi ale acestei clase, mai des utilizate sunt: Date – furnizează data conţinută în instanţa curentă a obiectului; Day – furnizează numărul zilei din lună conţinută în instanţa curentă a obiectului; DayOfWeek – furnizează numărul zilei din săptămână conţinută în instanţa curentă a obiectului; DayOfYear – furnizează numărul zilei din an conţinută în instanţa curentă a obiectului; Hour – furnizează ora conţinută în instanţa curentă a obiectului; Minute – furnizează minutul conţinută în instanţa curentă a obiectului; Month – furnizează luna conţinută în instanţa curentă a obiectului; Now – furnizează un obiect care conţine data si ora curentă a computerului, setate la nodul de reprezentare locală. Second – furnizează secunda conţinută în instanţa curentă a obiectului; Today – furnizează data curentă; Year – furnizează anul conţinut în instanţa curentă a obiectului; Câteva evenimente produde controlul MonthCalendar sunt: DateChanged – se produce la schimbarea datei din calendar; DateSelected – se produce atunci când utilizatorul realizează o selecţie explicită cu mouse-ul a unor date; Sa incepem: Creati un nou proiect Windows Forms cu numele AplicatieComplexa Pentru forma care se deschide setati urmatoarele proprietati: o (Name) : mainForm o BackColor : CornSilk (Web) o Font: Bold o ForeColor: Navy o FormBorderStyle: FixedDialog o MaximizeBox: False o MinimizeBox: False o Size: 700, 330 o StartPosition: CenterScreen o Text: O aplicatie complexa Trageti pe forma un control MonthCalendar si setati urmatoarele proprietati: o (Name) : myCalendar

Upload: others

Post on 14-Mar-2020

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

1

Proiect Vom construi o aplicatie care va folosi controlul MonthCalendar si alte controale noi.

Controlul MonthCalendar Controlul MonthCalendar permite vizualizarea sau setarea informaţiilor de tip data. Este un obiect de clasă MonthCalendar. Câteva proprietăţi specifice ar fi:

CalendarDimensions – stabileşte dimensiunile controlului de tip Calendar; FirstDayOfWeek – stabileşte prima zi din săptămână. Implicit este duminică; MaxDate – marchează ultima dată reprezentabilă pe calendar; MinDate – marchează prima dată reprezentabilă pe calendar; SelectionRange – marchează numărul maxim de zile ce pot fi selectate în control. Start – furnizează data de început a zonei selectate în control. ShowToday – precizează dacă data curentă este sau nu afişată în partea de jos a

controlului. TodayDate – furnizează data curentă. Ce este interesant de remarcat, ca proprietăţile de tip dată, sunt manipulate prin intermediul

unor obiecte de clasă DateTime. Câteva proprietăţi ale acestei clase, mai des utilizate sunt: Date – furnizează data conţinută în instanţa curentă a obiectului; Day – furnizează numărul zilei din lună conţinută în instanţa curentă a obiectului; DayOfWeek – furnizează numărul zilei din săptămână conţinută în instanţa curentă a

obiectului; DayOfYear – furnizează numărul zilei din an conţinută în instanţa curentă a obiectului; Hour – furnizează ora conţinută în instanţa curentă a obiectului; Minute – furnizează minutul conţinută în instanţa curentă a obiectului; Month – furnizează luna conţinută în instanţa curentă a obiectului; Now – furnizează un obiect care conţine data si ora curentă a computerului, setate la

nodul de reprezentare locală. Second – furnizează secunda conţinută în instanţa curentă a obiectului; Today – furnizează data curentă; Year – furnizează anul conţinut în instanţa curentă a obiectului; Câteva evenimente produde controlul MonthCalendar sunt: DateChanged – se produce la schimbarea datei din calendar; DateSelected – se produce atunci când utilizatorul realizează o selecţie explicită cu

mouse-ul a unor date; Sa incepem:

Creati un nou proiect Windows Forms cu numele AplicatieComplexa Pentru forma care se deschide setati urmatoarele proprietati:

o (Name) : mainForm o BackColor : CornSilk (Web) o Font: Bold o ForeColor: Navy o FormBorderStyle: FixedDialog o MaximizeBox: False o MinimizeBox: False o Size: 700, 330 o StartPosition: CenterScreen o Text: O aplicatie complexa

Trageti pe forma un control MonthCalendar si setati urmatoarele proprietati: o (Name) : myCalendar

Page 2: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

2

o BackColor : Plum (Web) o Location : 4, 4 o ShowToday : False

Trageti pe forma un control Label si setati urmatoarele proprietati : o (Name) : dateLabel o Font : Papyrus, 12, Bold Italic o ForeColor : Red o Location : 0, 168

Dorim ca data selectată pe controlul MonthCalendar, să apară în limba română înscrisă în controlul Label. Să ne reamintim că evenimentul produs la fiecare schimbare a datei în controlul MonthCalendar este DateChanged.

Facem dublu-clic pe calendar pentru a crea administratorul implicit si scriem codul in rosu :

private void myCalendar_DateChanged(object sender, DateRangeEventArgs e) { myCalendar.TodayDate = e.Start; CompleteazaData(); } In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a obiectului e de tip data calendaristica). Functia CompleteazaData() va afisa in eticheta dateLabel in limba romana data selectata de utilizator si are urmatorul cod : private void CompleteazaData() { string d; switch (myCalendar.TodayDate.DayOfWeek) { case DayOfWeek.Sunday: dateLabel.Text = "Duminica "; break; case DayOfWeek.Monday: dateLabel.Text = "Luni "; break; case DayOfWeek.Tuesday: dateLabel.Text = "Marti "; break; case DayOfWeek.Wednesday: dateLabel.Text = "Miercuri "; break; case DayOfWeek.Thursday: dateLabel.Text = "Joi "; break; case DayOfWeek.Friday: dateLabel.Text = "Vineri "; break; case DayOfWeek.Saturday: dateLabel.Text = "Sambata "; break; } d = myCalendar.TodayDate.Day.ToString(); dateLabel.Text += d; switch (myCalendar.TodayDate.Month) { case 1: dateLabel.Text += " Ianuarie "; break; case 2: dateLabel.Text += " Februarie "; break; case 3: dateLabel.Text += " Martie "; break; case 4: dateLabel.Text += " Aprilie "; break; case 5: dateLabel.Text += " Mai "; break; case 6: dateLabel.Text += " Iunie "; break; case 7: dateLabel.Text += " Iulie "; break; case 8: dateLabel.Text += " August "; break; case 9: dateLabel.Text += " Septembrie "; break; case 10: dateLabel.Text += " Octombrie "; break; case 11: dateLabel.Text += " Noiembrie "; break; case 12: dateLabel.Text += " Decembrie "; break; } d = myCalendar.TodayDate.Year.ToString();

Page 3: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

3

dateLabel.Text += d; } Functia extrage din data curenta selectata (TodayDate) ziua din saptamana (DayOfWeek) si adauga in sirul d denumirea zilei in limba romana. Extrage apoi ziua (TodayDate.Day) si luna (TodayDate.Month) si le adauga in stringul d, in cazul lunii inlocuind numarul de ordine al acesteia cu denumirea in limba romana. Sirul obtinut este afisat cu proprietatea Text a etichetei dateLabel. În forma actuală a programului, data curentă este afişată de de dateLaabel doar dacă se face o schimbare de dată în controlul myCalendar. Dar în mod normal ea trebuie afişată de la început. Pentru a realiza acest lucru:

Faceti dublu-clic pe fereastra mainForm pentru a crea administratorul implicit (Load) Scrieti codul in rosu:

private void mainForm_Load(object sender, EventArgs e) { CompleteazaData(); PopuleazaAn(); PopuleazaLunaInceput(startMonthComboBox); PopuleazaLunaSfarsit(); SeteazaIntervalTimp(myCalendar.TodayDate.Year, startMonthComboBox.SelectedIndex+1, endMonthComboBox.SelectedIndex+1); a++; } Restul functiilor din administratorul Load le vom adauga pe parcurs. Compilaţi şi executaţi programul. Ce ne deranjează? Faptul că datele pe care le poate reprezenta calendarul nu sunt limitate la un interval dorit de noi. Să încercăm să realizăm acest lucru. Dar pentru aceasta, vom folosi un alt control. Controlul ComboBox Acest control combină în fapt mai multe controale. În acest control vom regăsi un control TextBox, prezentat anterior şi respectiv un control ListBox despre care vom vorbi puţin mai tîrziu. Controlul ComboBox apare ca un TextBox având în partea stângă un buton cu săgeată. Dacă se apasă pe acesta, controlul se deschide, prezentând o listă de elemente. Orice astfel de control este un obiect de clasă ComboBox. Proprietăţi ale acestui control sunt:

DropDownStyle - stilul în care este afişat controlul la deschiderea listei. o DropDown – utilizatorul poate edita partea de TextBox a controlului şi trebuie să

apese butonul săgeată pentru a deschide partea de ListBox. o Simple – la fel ca şi DropDown, cu excepţia faptului că partea de ListBox a

controlului este tot timpul vizibilă. o DropDownList – utilizatorul nu poate edita partea de TextBox a controlului şi

trebuie să apese butonul săgeată pentru a deschide partea de ListBox. o DroppedDown – Indică dacă partea de listă a controlului este deschisă sau nu.

Items – este reprezentată sub forma unei colecţii care stochează obiectele conţinute de ComboBox.

MaxLength – prin setarea acestei proprietăţi la o valoare diferită de 0, se specifică numărul maxim de caractere ce pot fi introduse în partea de TextBox a controlului.

SelectedIndex – indică indexul obiectului curent selctat în lista controlului. Obiectele sunt ordonate în listă pe baza unui index bazat pe 0.

SelectedItem – indică obiectul curent selectat în listă. SelectionStart – indică indexul primului obiect selctat în lista asociată controlului. SelectionLength – lungimea textului selectată în partea de TextBox asociată

controlului.

Page 4: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

4

Sorted – dacă această proprietate este true, elementele din lista asociată controlului vor fi sortate în ordine alfabetică.

Câteva evenimente sunt:

DropDown – se produce când partea de ListBox a controlului se deschide. SelectedIndexChanged – se produce la schimbarea selecţiei în zona de listă a

controlului. KeyDown – se produce când o tastă este apăsată în zona de TextBox a controlului. KeyUp - se produce când o tastă este eliberată în zona de TextBox a controlului. TextChanged – se produce la schimbarea textului din partea de TextBox a controlului.

Dorim să stabilim prin intermediul unor controale ComboBox, anul reprezentat pe

MonthCalendar, luna de început şi luna de sfârşit a intervalului de timp prezentat. Trageti pe forma un control GroupBox si setati urmatoarele proprietati:

o (Name): selectionGroupBox o Dock: Bottom o Size: 694, 60 (numai inaltimea 60 o pteti edita) o Text: Selectare interval

Trageti in GroupBox trei controale ComboBox si setati, in ordine urmatoarele proprietati:

o (Name): yearComboBox, startMonthComboBox, endMonthComboBox o DropDownStyle: DropDownList o Location: (47, 24); (290, 24), (533, 24)

Trageti in GroupBox trei controale Label si setati, in ordine, urmatoarele proprietati: o (Name): yearLabel, startMonthLabel, endMonthLabel o Location: (12, 28); (192, 28); (441, 28) o Text: An, Luna inceput, Luna sfarsit

Trebuie sa completam cele trei ComboBox cu itemii corespunzatori. Pentru aceasta vom scrie urmatoarele functii: private void PopuleazaAn() { yearComboBox.Items.Add(myCalendar.TodayDate.Year); yearComboBox.Items.Add(myCalendar.TodayDate.Year + 1); yearComboBox.Items.Add(myCalendar.TodayDate.Year + 2); yearComboBox.Items.Add(myCalendar.TodayDate.Year + 3); yearComboBox.SelectedIndex = 0; } private void PopuleazaLunaInceput(ComboBox cb) { cb.Items.Add("Ianuarie"); cb.Items.Add("Februarie"); cb.Items.Add("Martie"); cb.Items.Add("Aprilie"); cb.Items.Add("Mai"); cb.Items.Add("Iunie"); cb.Items.Add("Iulie"); cb.Items.Add("August"); cb.Items.Add("Septembrie"); cb.Items.Add("Octombrie"); cb.Items.Add("Noiembrie"); cb.Items.Add("Decembrie"); cb.SelectedIndex = 0; }

Page 5: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

5

private void PopuleazaLunaSfarsit() { PopuleazaLunaInceput(endMonthComboBox); endMonthComboBox.SelectedIndex = 11; } Functia PopuleazaAn() adauga in primul ComboBox anul curent si urmatorii trei ani si selecteaza (pentru a fi afisat) anul curent. Functia PopuleazaLunaInceput() adauga in al doilea ComboBox toate lunile anului si selecteaza, pentru afisare, luna Ianuarie care are indexul 0. Functia PopuleazaLunaSfarsit() apeleaza functia anterioara pentru a adauga toate lunile anului si selecteaza, pentru afisare, ultima luna din an (luna Decembrie care are indexul 11). Aceste functii vor fi apelate tot din administratorul Load care se executa la incarcarea si afisarea initiala a formei: private void mainForm_Load(object sender, EventArgs e) { CompleteazaData(); PopuleazaAn(); PopuleazaLunaInceput(startMonthComboBox); PopuleazaLunaSfarsit(); SeteazaIntervalTimp(myCalendar.TodayDate.Year, startMonthComboBox.SelectedIndex+1, endMonthComboBox.SelectedIndex+1); a++; } Compilaţi şi executaţi programul. Ce n-am făcut încă? Pe baza datelor implicite, încă nu am limitat intervalul de timp prezentat de calendar. Va trebui ca la modificarea selecţiei în controalele de tip ComboBox, valorile selectate să se aplice în calculul datelor minimă şi mximă reprezenztabilă pe calendar. Adică, să interceptăm evenimentul SelectedItemChanged produs de cele trei controale ComboBox. Deaorece se realizeaza aceleasi operatii, vom scrie un administrator generic care va fi utilizat de toate cele trei ComboBox.

Selectati un ComboBox si faceti dublu-clic pe el pentru a genera administratorul implicit Modificati acest administrator ca mai jos (codul in rosu):

private void selectionComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (a == 0) return; int an = Convert.ToInt32(yearComboBox.SelectedItem.ToString()); int start = startMonthComboBox.SelectedIndex + 1; int end = endMonthComboBox.SelectedIndex +1; SeteazaIntervalTimp(an, start, end); }

Selectati primul ComboBox, in fereastra Properties selectati tabul Events (fulgerul galben), selectati evenimentul SelectedIndexChanged si alegeti din lista selectionComboBox_SelectedIndexChanged

Repetati operatia si pentru celelalte doua ComboBox. Codul de mai sus memoreaza in variabila an anul selectat in controlul yearComboBox, in variabila start luna de inceput a intervalului reprezentat in calendar selectata in controlul startMonthComboBox si in variabila end luna de sfarsit a intervalului selectat de utilizator in controlul endMonthComboBox. Cele trei valori sunt utilizate pentru a apela functia SeteazaIntervalTimp() prezentata in continuare: private void SeteazaIntervalTimp(int an, int start, int end) { int d = 0; switch (end)

Page 6: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

6

{ case 1: d = 31; break; case 2: if (an % 4 == 0) d = 29; else d = 28; break; case 3: d = 31; break; case 4: d = 30; break; case 5: d = 31; break; case 6: d = 30; break; case 7: d = 31; break; case 8: d = 31; break; case 9: d = 30; break; case 10: d = 31; break; case 11: d = 30; break; case 12: d = 31; break; } myCalendar.MaxDate = new DateTime(an, end, d, 23, 59, 59); myCalendar.MinDate = new DateTime(an, start, 1, 0, 0, 0); } Aceasta functie foloseste luna de sfarsit a perioadei (parametrul end) pentru a determina in d numarul de zile din luna. Este apoi setata data maxima reprezentata in MyCalendar (MaxDate) cu ajutorul unui obiect de tip DateTime initializat cu valorile an, end, d (ultima zi din luna) si 23 59 59 (ore minute secunde). Data minima reprezentata in calendar este setata cu un alt obiect DateTime initializat cu valorile an, start, 1 (prima zi din luna respectiva) si 0 0 0 (ore, minute si secunde). Aceasta functie trebuie apelata si la incarcarea formei pentru a seta anul curent si lunile Ianuarie, respectiv Decembrie ca interval de timp prestabilit. Vom adauga in Load codul scris n rosu: private void mainForm_Load(object sender, EventArgs e) { CompleteazaData(); PopuleazaAn(); PopuleazaLunaInceput(startMonthComboBox); PopuleazaLunaSfarsit(); SeteazaIntervalTimp(myCalendar.TodayDate.Year, startMonthComboBox.SelectedIndex+1, endMonthComboBox.SelectedIndex+1); a++; } Ne reamintim ca functia PopuleazaAn() seteaza indexul la valoarea 0 (anul curent), PopuleazaLunaInceput() seteaza indexul la valoarea 0 (Iuna Ianuarie), iar PopuleazaLunaSfarsit() seteaza indexul la valoarea 11 (luna Decembrie). Acesti indici sunt folositi pentru a apela functia SeteazaInterval() pentru a seta intervalul prestabilit afisat la deschiderea formei si care se limiteaza la anul curent. Deoarece nu dorim ca setarea initiala a celor trei indici sa fie interpretata ca un eveniment SelectedIndexChanged, am folosit variabila globala a declarata inaintea administratorului myCalendar_DateChanged(): int a = 0; Dupa initializarea celor trei indici si setarea intervalului initial, variabila a este incrementata in administratorul Load(). In administratorul selectionComboBox_SelectedIndexChanged, daca a are valoarea 0 (la incarcarea formei) administratorul se incheie (cu return) fara a seta un alt interval de timp.

Page 7: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

7

Forma initiala:

Respectiv dupa selectarea unui alt interval:

Controlul TabControl Controlul TabControl furnizează un mod elegant de organizare a unei interfeţe în componente logice, accesibile prin intermediul unor taburi localizate în partea superioară a controlului. Controlul TabControl este organizat în pagini (TabPages) care operează de o manieră oarecum similară controlului GroupBox, dar într-o modalitate mai complexă. Câteva din proprietăţile controlului sunt:

Alignment – precizează poziţia taburilor. Implicit, acestea sunt afişate în partea superioară a controlului.

Appearance – Precizează modul de afişare al taburilor. Acestea pot fi afişate ca butoane normale sau bidimensionale.

HotTrack – dacă această proprietate este true, modul de afişare al taburilor se schimbă la trecerea prompterului mouse-lui pe deasupra lor.

Multiline – dacă această proprietate este true, se pot insera mai multe linii de text in tab-uri.

Page 8: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

8

RowCount – conţine numarul de linii al taburilor care sunt afişate în mod curent. SelectedIndex – conţine indexul tab-ului curent selectat. TabCount – conţine numărul curent de taburi conţinut de control. TabPages – conţine sub forma unei colecţii paginile din TabControl.

În cele ce urmează, vom dezvolta o aplicaţie mai complexă, componentele acesteia fiind

găzduite de paginile unui control TabControl. Trageti pe forma, in spatiul din dreapta calendarului, un control TabControl (din

sectiunea Containers) si setati urmatoarele proprietati: o (Name): myTabControl o Appearance: Buttons o Dock: Right o HotTrack: True o Size: 514, 238 (numai prima dimensiune o puteti edita din cauza proprietatii

Dock Right) Dorim ca acest TabControl sa contina patru pagini. Pentru a adauga si seta aceste pagini procedam astfel:

Selectati myTabControl si in fereastra Properties selectati TabPages Faceti clic pe caseta cu trei puncte din dreapta proprietatii pentru a deschide editorul

TabPage Collection Editor. Mai intai apasati de doua ori butonul Add pentru a aduga controlului inca doua pagini Selectati in stanga prima pagina (numita generic tabpage1) si in panoul din dreapata

setati (de sus in jos ) urmatoarele proprietati: o Text: Setari o (Name): setariTabPage

Selectati pagina tabPage2 si setati urmatoarele proprietati: o Text: Calculator o (Name): calculatorTabPage

Selectati tabPage3 si setati: o Text: Editor texte o (Name): editorTabPage

Selectati tabPage4 si setati: o Text: Agenda o (Name): agendaTabPage

Page 9: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

9

Cand ati terminat apasati butonul OK pentru a inchide editorul. Interfata ar trebui sa arate astfel:

Controalele ListBox şi CheckedListBox Controalele de acest tip sunt utilizate pentru a afişa un set de stringuri, din care unul sau mai multe pot fi selectate la un moment dat. Clasa ListBox oferă funcţionalitate atât controlului ListBox cât controlului ComboBox. Clasa CheckedListBox este derivată din aceasta şi adaugă fiecărui string din listă un control de tip CheckBox, utilizat pentru selectare. Câtve din proprietăţile furnizate de clasa ListBox sunt:

SelectedIndex – indică indicele bazat pe 0 a elementului selctat în listă, sau a primului element selctat în lista, în cazul selecţiei multiple.

ColumnWidth – specifică lăţimea coloanelor, în listele cu coloane multiple. Items – conţne sub forma unei colecţii toate elementele stocate în listă. Multicolumn – specifică numărul de coloane din listă. SelectedIndices – o colecţie care conţine toţi indicii elementelor selectate din listă. SelectedItem – această proprietate conţine elementul selectat în listă dacă selecţia este

simplă, respectiv primul elemen selectat din listă în cazul selecţiei multiple. SelectedItems – o colecţie care conţine elementele selectate din listă. Sorted – dacă această proprietate este true, elementele vor fi afişate în listă în ordine

alfabetică. CheckOnClick – dacă această proprietate este true, starea unui element se schimbă

când asupra lui se efectuează click.

Câteva din metodele clasei: ClearSelected() – şterge toate selecţiile (nu elementele selectate!) din listă. FindString() – caută primul string care începe cu şirul specificat ca parametru în listă. GetSelected() – returnează o valoare care specifică dacă un element este selectat. SetSelected() – setează sau şterge selectarea unui element. GetItemChecked() – returnează o valoare care indică faptul că checkbox-ul asociat unui

element este bifat (doar pentru CheckedListBox). GetItemCheckState() – returnează o valoare care indică starea casetei checkbox

sociată elementului (doar pentru CheckedListBox). SetItemChecked() – setează starea casetei checkbox a elementului specificat într-una

din stările posibile (doar pentru CheckedListBox).

Page 10: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

10

SetItemCheckState() – Setează starea unui element(doar pentru CheckedListBox). Câteva evenimente:

ItemCheck – se produce când starea de check a unui element se schimbă. SelectedItemChanged – se produce la schimbarea indexului elementelor selectate.

Vom continua dezvoltarea aplicatiei astfel:

Selectati pagina Setari din myTabControl Trageti pe aceasta pagina doua controale CheckedListBox si setati, in ordne de la

stanga la dreapta, urmatoarele proprietati: o (Name): totalChkListBox, existentChkListBox o BackColor: CornSilk o CheckOnClick: True o ForeColor: Navy o Location: (30, 50); (345, 50) o Size: 130, 92

Trageti in pagina doua controale Button (intre cele doua CheckedListBox) si setati, in ordine de sus in jos, urmatoarele proprietati:

o (Name): adaugaButton, stergeButton o BackColor: CornSilk o Location: (198, 50); (198, 111) o Size: 115, 30 o Text: Adauga , Sterge

Pagina ar trebui sa arate astfel:

Dorim ca la apăsarea butonului adaugaButton, elementele selectate din lista

totalChkListBox să fie copiate în lista existentChkListBox, în prima listă fiind deselectate toate elementele. La apăsarea butonului stergeButton, toate elementele selectate din lista existentChkListBox vor fi şterse. Pentru început, vom popula prima listă. Vom adauga functia: private void CompleteazaListaTotal() { totalChkListBox.Items.Add("Calculator"); totalChkListBox.Items.Add("Editor texte"); totalChkListBox.Items.Add("Agenda"); }

Page 11: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

11

Aceasta functie trebuie scrisa in Form1.cs, dupa functia SeteazaIntervalTimp() si va fi apelata din evenimentul Load() al formei: private void mainForm_Load(object sender, EventArgs e) { CompleteazaData(); PopuleazaAn(); PopuleazaLunaInceput(startMonthComboBox); PopuleazaLunaSfarsit(); SeteazaIntervalTimp(myCalendar.TodayDate.Year, startMonthComboBox.SelectedIndex+1, endMonthComboBox.SelectedIndex+1); a++; CompleteazaListaTotal(); } Vom adauga acum functionalitate celor doua butoane din pagina.

Faceti dublu-clc pe butonul Adauga si scrieti codul in rosu: private void adaugaButton_Click(object sender, EventArgs e) { if (totalChkListBox.CheckedItems.Count > 0) //sunt selectati itemi in lista { existentChkListBox.Items.Clear(); //stergem toti itemii din a doua lista foreach (string item in totalChkListBox.CheckedItems) { existentChkListBox.Items.Add(item.ToString()); //am adaugat in a doua lista itemii selectati in prima lista } for (int i = 0; i < totalChkListBox.Items.Count; i++) { totalChkListBox.SetItemChecked(i, false); //deselectam toti itemii din prima lista } } }

Faceti dublu-clic pe butonul Sterge si scrieti codul in rosu: private void stergeButton_Click(object sender, EventArgs e) { for (int i = existentChkListBox.Items.Count - 1; i >= 0; i--) //parcurge toti itemii din a doua lista { if (existentChkListBox.GetItemCheckState(i).ToString() == "Checked") //daca itemul a fost bifat existentChkListBox.Items.RemoveAt(i); //este sters din lista } }

Este nevoie ca ciclul de stergere se fie descendent, deoarece odată cu ştergerea unui obiect indicii acestora se reaşează. Într-un ciclu ascendent, va rămâne întotdeauna ultimul item din lista neşters.

Rulati aplicatia si verificati functionalitatea acestei pagini.

Page 12: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

12

In pagina a doua a controlullui myTabControl vom construi un calculator. Pentru aceasta vom adauga diverse controale astfel incat sa obtinem urmatoarea interfata:

Selectati pagina Calculator din myTabControl Trageti in pagina un control GroupBox si setati urmatoarele proprietati:

o (Name): myGroupBox o BackColor: CornSilk o Dock: Right o Size: 316, 211

Trageti in GroupBox un control TextBox si setati urmatoarele proprietati: o (Name): introTextBox o BackColor: Cyan (Web) o Dock: Top o ForeColor: Navy o ReadOnly: True o Text:

Trageti sub TextBox un control ListBox si setati urmatoarele proprietati: o (Name): afisareListBox o BackColor: Cyan o ForeColor: Navy o Location: 3, 43 o Size: 310, 43

Trageti in partea stanga patru controale Button si setati, in ordine de sus in jos, urmatoarele proprietati:

o (Name): storeButton, callButton, clearButton, egalButton o BackColor: Fuchsia (Web) o Location: (0, 93); (0, 122); (0, 151); (0, 180) o Size: 75, 23 o Text: MS (memory store), MC (memory call), C (clear), =

Trageti in partea dreapta a GroupBox-ului patru controale Button si setati, in ordne de sus in jos, urmatoarele proprietati:

o (Name); plusButton, minusButton, oriButton, divButton o BackColor: Fuchsia o Location: (273, 93); (273, 122); (273, 151); (273, 180) o Size: 40, 23 o Text: +, -, *, /

Page 13: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

13

Trageti in spatiul ramas un control Button si setati-i dimensiunea la 30, 23, apoi faceti clic-dreapta, alegeti Copy si faceti Paste pentru a copia butonul in spatiul ramas. Repetati aceasta operatie pana cand aveti in spatiul din mijloc 12 butoane aranjate aproximativ ca in figura de mai sus.

Selectati, in ordine de la stanga la dreapta si de sus in jos, fiecare buton si setati urmatoarele proprietati:

o (Name): unuButton, doiButton, treiButton, patruButton, cinciButton, saseButton, sapteButton, optButton, nouaButton, semnButton, zeroBotton, virgulaButton

o BackColor: Cyan o Location: (111, 93); (163, 93); (208, 93); (111, 122); (163, 122); (208, 122); (111,

151); (163, 151); (208, 151); (111, 180); (163, 180); (208, 160) o Text: +/-; 0; , (virgula zecimala)

Calculatorul trebuie sa fie inactiv la deschiderea formei. El devine activ atunci cand aplicatia Calculator este selectata in lista totalChkListBox din pagina Setari si redevine inactiv cand aplicatia este stearsa din lista existentChListBox. Vom scrie doua functii: una dezactiveaza tastele calculatorului, iar cealalta le activeaza. Codul lor (din Form1.cs) este: private void DezactiveazaCalculator() { unuButton.Enabled = false; doiButton.Enabled = false; treiButton.Enabled = false; patruButton.Enabled = false; cinciButton.Enabled = false; saseButton.Enabled = false; sapteButton.Enabled = false; optButton.Enabled = false; nouaButton.Enabled = false; zeroButton.Enabled = false; } private void ActiveazaCalculator() { unuButton.Enabled = true; doiButton.Enabled = true; treiButton.Enabled = true; patruButton.Enabled = true; cinciButton.Enabled = true; saseButton.Enabled = true; sapteButton.Enabled = true; optButton.Enabled = true; nouaButton.Enabled = true; zeroButton.Enabled = true; } Deoarece la incarcarea formei calculatorul trebuie sa fie inactiv, vom apela functia DezactiveazaCalculator() in administratorul Load() al formei: private void mainForm_Load(object sender, EventArgs e) { ....... CompleteazaListaTotal(); DezactiveazaCalculator(); } La inserarea numelui Calculator in lista existentChkListBox, calculatorul trebuie sa se activeze. Vom adauga in administratorul butonului Adauga (din pagina Setari) codul in rosu:

Page 14: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

14

private void adaugaButton_Click(object sender, EventArgs e) { ........ foreach (string item in totalChkListBox.CheckedItems) { existentChkListBox.Items.Add(item.ToString()); //am adaugat in a doua lista itemii selectati din prima lista if (item.ToString() == "Calculator") //aplicatia a fost selectata ActiveazaCalculator(); //calculatorul este activat }

....... } } Cand aplicatia Calculator este stearsa din lista existentChkListBox, calculatorul trebuie dezactivat. Vom adauga in administratorul butonului Sterge codul in rosu: private void stergeButton_Click(object sender, EventArgs e) { foreach (string item in existentChkListBox.CheckedItems) { if (item.ToString() == "Calculator") DezactiveazaCalculator(); } ........ } Rulati aplicatia si verificati daca calculatorul se activeaza/dezactiveaza la adaugarea/stergerea aplicatiei Calculator in lista existentChkListBox din pagina Setari. Vom crea acum un administrator generic pentru butoanele calculatorului.

Faceti dublu-clic pe orice buton al calculatorului si redenumiti administratorul creat astfel: private void calculatorButton_Click(object sender, EventArgs e) { }

Selectati pe rand, fiecare din cele douzeci de butoane ale calculatorului, in fereastra Properties selectati tabul Events, selectati evenimentul Click si din lista care se deschide alegeti administratorul calculatorButton_Click.

Inainte de implementa codul administratorului generic, in Form1.cs vom adauga urmatoarele declaratii:

public partial class mainForm : Form { public mainForm() { InitializeComponent(); } int a = 0; string snr1 = "", snr2 = ""; double rezultat, memory; int op; bool prim = true; ....... Variabilele nr1 şi nr2 reprezintă cei 2 operanzi. Sirul nr1 va fi completat cu primul operand, la prima introducere şi în plus, va menţine tot timpul rezultatul operaţiilor efectuate. Sirul nr2 va conţine întotdeauna cel de-al doilea operand. Sunt variabile de tip string, deci valorile lor vor

Page 15: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

15

trebui convertite la double pentru efectuarea operaţiilor. Cum întotdeauna prima introducere de date se face referitor la nr1 şi apoi toate celelalte la nr2, vom avea nevoie de o variabilă care să specifice faptul că valoarea introdusă este primul operand, sau al doilea. Aceasta este prim, care va lua valoarea true înainte de prima introducere, odată cu introducerea primului operand ea fiind facuta false. Rezultatul fiecărei operaţii, în format double va fi stocat în rez, iar valoarea memorată la apăsarea butonului MC va fi stocată în memory. Pentru a putea identifica operaţiile executate asupra operanzilor, va trebui să le codificăm. Vom codifica operaţiile astfel: adunare: 1, scădere:2, înmulţire:3 şi respectiv împărţire:4.

Completam administratorul generic cu codul in rosu: private void calculatorButton_Click(object sender, EventArgs e) { if (sender == unuButton) CitesteButon("1"); if (sender == doiButton) CitesteButon("2"); if (sender == treiButton) CitesteButon("3"); if (sender == patruButton) CitesteButon("4"); if (sender == cinciButton) CitesteButon("5"); if (sender == saseButton) CitesteButon("6"); if (sender == sapteButton) CitesteButon("7"); if (sender == optButton) CitesteButon("8"); if (sender == nouaButton) CitesteButon("9"); if (sender == zeroButton) CitesteButon("0"); if (sender == virgulaButton) CitesteButon(","); if (sender == semnButton) //semnul operandului trebuie schimbat { if (prim) //este semnul pentru primul operand { if (nr1.Length == 0) nr1 += "-"; //semnul este primul caracter dintr-un sir vid else if (nr1[0] != '-' && nr1[0] != '+') //numarul nu are semn deci era pozitiv nr1 = nr1.Insert(0, "-"); //adaugam semnul minus else //schimbam semnul primului operand if (nr1[0] == '-') nr1 = nr1.Replace('-', '+'); else nr1 = nr1.Replace('+', '-'); } else //este semnul pentru al doilea operand { if (nr2.Length == 0) nr2 += "-"; else if (nr2[0] != '-' && nr2[0] != '+') nr2 = nr2.Insert(0, "-"); else if (nr2[0] == '-') nr2 = nr2.Replace('-', '+'); else nr2 = nr2.Replace('+', '-'); } } if (sender == plusButton) Operatie("+", 1); if (sender == minusButton) Operatie("-", 2); if (sender == oriButton) Operatie("*", 3); if (sender == divButton) Operatie("/", 4); if (sender == egalButton) {

Page 16: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

16

switch (op) { case 1: rezultat = Convert.ToDouble(nr1) + Convert.ToDouble(nr2); break; case 2: rezultat = Convert.ToDouble(nr1) – Convert.ToDouble(nr2); break; case 3: rezultat = Convert.ToDouble(nr1) * Convert.ToDouble(nr2); break; case 4: rezultat = Convert.ToDouble(nr1) / Convert.ToDouble(nr2); break; } afisareListBox.Items.Add(nr2); nr2 = ""; nr1 = Convert.ToString(rezultat); afisareListBox.Items.Add("-------"); afisareListBox.Items.Add(nr1); op = 0; } if (sender == clearButton) //sunt anulate valorile introduse { nr1 = ""; rezultat = 0; prim = true; introTextBox.Clear(); afisareListBox.Items.Clear(); } if (sender == storeButton) //se stocheaza in memorie rezultatul partial obtinut { memory = rezultat; if (memory == 0) storeButton.Image = Image.FromFile("D:/Imagini/dot.jpg"); else storeButton.Image = Image.FromFile("D:/Imagini/dot2.jpg"); } if (sender == callButton) //se extrage din memorie rezultatul partial { if (prim) nr1 = Convert.ToString(memory); else nr2 = Convert.ToString(memory); if ((sender == plusButton) || (sender == minusButton) || (sender == oriButton) || (sender == divButton) || (sender == egalButton) || prim) introTextBox.Text = nr1; else introTextBox.Text = nr2; memory=0; storeButton.Image = Image.FromFile("D:/Imagini/dot.jpg"); } } Inante de a explica functia de mai sus vom implementa si functiile CitesteButon() si Operatie():

Page 17: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

17

private void CitesteButon(string s) { if (prim) nr1 += s; else nr2 += s; } private void Operatie(string s, int oper) { if (prim) prim = false; else { switch (op) { case 1: rezultat = Convert.ToDouble(nr1) + Convert.ToDouble(nr2); break; case 2: rezultat = Convert.ToDouble(nr1) – Convert.ToDouble(nr2); break; case 3: rezultat = Convert.ToDouble(nr1) * Convert.ToDouble(nr2); break; case 4: rezultat = Convert.ToDouble(nr1) / Convert.ToDouble(nr2); break; } nr2 = ""; nr1 = Convert.ToString(rezultat); } afisareListBox.Items.Add(nr1 + s); op = oper; } Funcţia CitesteButon() primeşte ca parametru un şir de caractere. Dacă prim==true, îl adaugă la nr1, altfel la nr2. În acest fel, se permite completarea şirurilor de caractere care conţin cei 2 operanzi. Functia Operatie() este lansată în execuţie doar la apăsarea butoanelor care definesc operaţii aritmetice, adică doar după ce cel puţin un operand este introdus. Dacă deja s-a introdus un operand, prim este facut false pentru ca următorul operand să fie stocat în nr2. Apoi se calculează rezultatul (dar doar dacă există ambii operanzi), se stochează şi în nr1 pentru operaţiile următoare şi se salvează în op codul operaţiei. Operaţia ce se va executa este întotdeauna cea stocată în op. De asemenea, rezultatul şi semnul operaţiei (primit ca şi parametru) este afişat în controlul listă. Şi acum să trecem la funcţia lansată la apăsarea butoanelor (calculatorButton_Click). Dacă butonul care a lansat-o este un buton numeric, valoarea acestuia se adaugă la nr1 sau nr2, în funcţie de valoarea lui prim. Dacă butonul este semn, se adaugă – sau + în faţa lui nr1 sau nr2, în funcţie de valoarea lui prim. Dacă şirul este gol sau nu există semn, se adaugă pe prima poziţie -, altfel se schimbă semnul existent cu cel complementar. Dacă butonul care a lansat în execuţie funcţia este un buton de operaţie aritmetică, se memorează codul operaţiei şi se execută operaţia anterioară, conform funcţiei Operatie(). Dacă butonul este =, se execută ultima operaţie, se afişează rezultatul în controlul ListBox şi se actualizează nr1 cu valoarea rezultatului pentru operaţii ulterioare. De asemnea, op este setat la o valoare care nu reprezintă o operaţie aritmetică, pentru ca operaţia să se efectueze doar după introducerea următorului operand. Dacă butonul este clear, se marchează prim=true pentru ca toate operaţiunile să fie reiniţializate şi se şterge rezultatul şi şirul nr1, pentru a-l pregăti să primească un nou operand. Dacă butonul este storeButton, se salvează rezultatul în variabila tampon memory. De asemenea, se schimbă pictograma de pe buton în cerc verde, pentru a marca faptul că în

Page 18: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

18

memorie există o valoare utilizabilă. Stocarea în memorie a valorii 0 este echivalentă cu ştergerea memorie, deci va fi afişată din nou pictograma cerc roşu. Dacă butonul este callButton, valoarea stocată în memorie va fi încărcată (după conversie) în nr1 sau nr2, în funcţie de valoarea lui prim. Compilaţi şi executaţi programul. Controlul RichTextBox Este un control asemănător cu controlul TextBox, dar permite afişarea de texte formatate. Câteva din proprietăţile acestui control sunt:

CanRedo – această proprietate este true dacă a fost executată o acţiune undo în interiorul controlului.

CanUndo – această proprietate este true dacă în interiorul controlului se poate executa o acţiune undo.

RedoActionName – proprietatea stochează numele acţiunii care a fost utilizată pentru a executa redo asupra a ceva care a fost făcut undo.

DetectUrls – dacă această proprietate este true, controlul este capabil să detecteze url-uri şi să le formateze (să le sublinieze, la fel ca şi în browser)

Rtf – este echivalentă cu proprietatea Text din TextBox, dar conţine un text formatat. SelectedRtf – această proprietate poate fi utilizată pentru a prelua sau a introduce text

formatat din/în control. Dacă de exemplu textul preluat va fi introdus în MsWord, îşi va păstra formatul.

SelectedText – la fel ca şi proprietatea anterioară, dar textul este neformatat, deci orice informaţii asupra formatului acestuia se vor pierde.

SelectionAlignment – reprezintă alinierea textului selectat. Poate fi Left, Center sau Right.

SelectionBullet – proprietatea poate fi utilizată dacă textul este formatat cu bullets sau poate fi utilizată pentru adăugarea sau ştergerea unei asemenea formatări.

BulletIndent – specifică numărul de pixeli până la bullet, de la marginea stângă a controlului.

SelectionColor – permite schimbarea culorii textului selectat. SelectionFont – permite schimbarea fonturilor textului selctat. SelectionLength – permite setarea sau obţinerea lungimii textului selectat. SelectionType – conţine informaţii cu privire la tipul obiectelor selectate. ShowSelectionMargin – dacă această proprietate este true, o margine va fi afişată în

stânga controlului pentru a uşura selectarea textului. UndoActionName – precizează numele acţiunii ce se va efectua dacă utilizatorul

execută un undo. SelectionProtected – permite specificarea căror părţi din text să nu poată fi schimbate,

prin setarea la true a acestei proprietăţi. Controlul poate genera o serie de evenimente, dintre care putem aminti: LinkedClick – este generat când utilizatorul face click pe un link din text. Protected – este generat atunci când utilizatorul încearcă să modifice un text care a fost

protejat. SelectionChanged – este generat când textul selectat în interiorul controlului se

schimbă. Vom folosi acest control pentru a proiecta pagina Editor texte din myTabControl.

Selectati pagina Editor texte Adaugati in pagina in partea de sus zece controale Button pentru care setati, in ordine

de la stanga la dreapta, urmatoarele proprietati: o (Name): openButton, saveButton, boldButton, italicButton, underlineButton,

leftButton, centerButton, rightButton, fontButton

Page 19: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

19

o Location: (11, 4); (47, 4); (83, 4); (119, 4); (155, 4); (191, 4); (227, 4); (263, 4); (300, 4); (398, 4)

o Size: 30, 30 pentru primele butoane si 60, 30 pentru ultimul buton din dreapta

o Text: nimic, nimic, B, I (font italic), U (font underline), nimic, nimic, nimic, nimic, Font

Pentru butoanele open, save, left, center, right si color vom folosi pictograme. Cautati pe net pictograme pentru aceste operatii care sa aiba cca 32 x 32 pixeli si salvati aceste imagini in folderul Imagini creat anterior pe discul D cu nume sugestive.

Selectati butonul openButton si in fereastra Properties alegeti BackgroundImage. Apasati pe caseta cu trei puncte si in fereastra Select Resource bifati butonul Local resource si apoi apasati butonul Import pentru a selecta pictograma dorita. Cand ati terminat apasati butonul OK

Repetati aceste operatii pentru fiecare din butoanele saveButton, leftButton, centerButton, rightButton , colorButton si adaugati-le pictograme sugestive.

Trageti pe forma un control RichTextBox si setati urmatoarele proprietati: o (Name): myRichTextBox o Dock: Bottom o Font: 10 Regular o Size: 506, 171

Pagina ar trebui sa arate astfel:

Ca si calculatorul, editorul de texte trebuie sa fie inactiv la incarcarea formei, sa devina activ la adaugarea textului corespunzator in lista existentChkListBox din pagina Setari si sa redevina inactiv la stergerea sirului din lista. Pentru a realiza aceasta functionalitate vom scrie doua functii care dezactiveaza respectiv activeaza controalele din pagina. private void DezactiveazaEditor() { openButton.Enabled = false; saveButton.Enabled = false; boldButton.Enabled = false; italicButton.Enabled = false; underlineButton.Enabled = false; leftbutton.Enabled = false; centerButton.Enabled = false; rightButton.Enabled = false; colorButton.Enabled = false; fontButton.Enabled = false; myRichTextBox.Enabled = false;

Page 20: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

20

} private void ActiveazaEditor() { openButton.Enabled = true; saveButton.Enabled = true; boldButton.Enabled = true; italicButton.Enabled = true; underlineButton.Enabled = true; leftbutton.Enabled = true; centerButton.Enabled = true; rightButton.Enabled = true; colorButton.Enabled = true; fontButton.Enabled = true; myRichTextBox.Enabled = true; } Functia DezactiveazaEditor() o vom apela prima data in administratorul Load() al formei: private void mainForm_Load(object sender, EventArgs e) { ....... DezactiveazaCalculator(); DezactiveazaEditor(); } O vom apela si in administratorul butonului Sterge din pagina Setari: private void stergeButton_Click(object sender, EventArgs e) { foreach (string item in existentChkListBox.CheckedItems) { if (item.ToString() == "Calculator") DezactiveazaCalculator(); if (item.ToString() == "Editor texte") DezactiveazaEditor(); } ....................... } Functia ActiveazaEditor() o vom apela in administratorul butonului Adauga din pagina Setari: private void adaugaButton_Click(object sender, EventArgs e) { if (totalChkListBox.CheckedItems.Count > 0) { existentChkListBox.Items.Clear(); foreach (string item in totalChkListBox.CheckedItems) { existentChkListBox.Items.Add(item.ToString()); //am adaugat in a doua lista itemii selectati din prima lista if (item.ToString() == "Calculator") //aplicatia a fost selectata ActiveazaCalculator(); //calculatorul este activat if (item.ToString() == "Editor texte") //aplicatia a fost selectata ActiveazaEditor(); //editorul este activat } ......... }

Compilati si rulati aplicatia pentru a verifica functionalitatea de mai sus.

Page 21: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

21

Vom scrie mai intai administratorii pentru butoanele de formatare bold, italic si underline pentru ca sunt asemanatoare si mai usor de inteles.

Faceti dublu-clic pe butonul bold si scrieti codul in rosu: private void boldButton_Click(object sender, EventArgs e) { Font oldFont, newFont; oldFont = myRichTextBox.SelectionFont; //fontul textului selectat newFont = new Font(oldFont, oldFont.Style ^ FontStyle.Bold); myRichTextBox.SelectionFont = newFont; myRichTextBox.Focus(); }

Faceti dublu-clic pe butonul italic si scrieti codul in rosu: private void italicButton_Click(object sender, EventArgs e) { Font oldFont, newFont; oldFont = myRichTextBox.SelectionFont; newFont = new Font(oldFont, oldFont.Style ^ FontStyle.Italic); myRichTextBox.SelectionFont = newFont; myRichTextBox.Focus(); }

Faceti dublu-clic pe butonul underline si scrieti codul in rosu: private void underlineButton_Click(object sender, EventArgs e) { Font oldFont, newFont; oldFont = myRichTextBox.SelectionFont; newFont = new Font(oldFont, oldFont.Style ^ FontStyle.Underline); myRichTextBox.SelectionFont = newFont; myRichTextBox.Focus(); } Cele trei funcţii sunt similare. Întâi, definesc doua obiecte de clasă Font, oldFont şi respectiv newFont. În obiectul oldFont se salvează fontul implicit din zona de text selectată. Apoi, se crează un nou font, care se încarcă în obiectul newFont. Contructorul clasei Font are prototipul

Font(Famile de fonturi, Stilul fontului) Se observă că în constructor se păstrează aceeaşi familie ca şi fontul din textul selctat (cu alte cuvinte nu se schimbă fontul) dar, stilul vechiului font este supus unei operaţii ^ (SAU exclusiv) cu stilul corespunzător funcţiei (Bold, Italic respectiv Underline). Prin SAU exclusiv, dacă stilurile sunt identice, se şterge stilul, iar dacă stilurile sunt diferite, se aplică stilul. Adică dacă textul selectat este normal şi se apasă de exemplu Bold, textul va fi făcut bold. Dar dacă textul selectat era bold, acest stil se şterge şi textul redevine normal. Apoi, fontul nou este aplicat textului selectat şi focusul este redat controlului. Tot relativ simplu sunt de implementat şi funcţiile care aliniază textul.

Faceti dublu-clic pe butonul left si scrieti codul in rosu: private void leftbutton_Click(object sender, EventArgs e) { myRichTextBox.SelectionAlignment = HorizontalAlignment.Left; myRichTextBox.Focus(); }

Faceti dublu-clic pe butonul center si scrieti codul in rosu: private void centerButton_Click(object sender, EventArgs e) { myRichTextBox.SelectionAlignment = HorizontalAlignment.Center; myRichTextBox.Focus(); }

Faceti dublu-clic pe butonul right si scrieti codul in rosu: private void rightButton_Click(object sender, EventArgs e)

Page 22: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

22

{ myRichTextBox.SelectionAlignment = HorizontalAlignment.Right; myRichTextBox.Focus(); } Compilati si rulati aplicatia pentru a verifica functionalitatea butoanelor care au fost implementate. Scrieti un text in myRichTextBox, selectati o portiune de text sau tot textul si formatati-l cu ajutorul butoanelor bold, italic, underline, left, center si right. Casete de dialog Casetele de dialog sunt ferestre care sunt afişate în contextul altor ferestre. Sunt utilizate în general atunci când programul necesită un set de informaţii suplimentare de la utilizator. Pentru a afişa un astfel de control, se va utiliza metoda ShowDialog(), după cum se va vedea în continuare. La reântoarcerea în fereastra principală, caseta de dialog va returna un cod, care în general poate fi DialogResult.OK dacă modificările făcute în caseta de dialog se confirmă, respectiv DialogResult.Cancel dacă acestea se anulează.

FontDialog Caseta de dialog FontDialog este prezentată în figura de mai sus. Se poate observa că prin intermediul ei se poate alege tipul de font, dimensiunea fontului precum şi stilul fontului. Această casetă dorim s-o lansăm la apăsarea butonului fontButton.

Faceti dublu-clic pe butonul Font si scrieti codul in rosu: private void fontButton_Click(object sender, EventArgs e) { FontDialog fd = new FontDialog(); //creaza un dialog if (fd.ShowDialog() == DialogResult.OK) //a fost apasat OK myRichTextBox.SelectionFont = fd.Font; //se aplica selectiei fontul ales myRichTextBox.Focus(); } Funcţia creează un obiect FontDialog, numit fd. Apoi, îl afişează cu ajutorul funcţiei ShowDialog(). Aceasta va implementa în totalitate funcţionalitatea casetei de dialog. Dacă la ieşire a fost apăsat butonul OK, textului selectat i se schimbă fontul în cel ales şi returnat de caseta de dialog. ColorDialog Caseta de dialog ColorDialog este prezentată în figura de mai sus. Ea permite alegerea culorilor dintr-un set predefinit, sau definirea de culori utilizator. Modul de manifestare este similar casetei de dialog precedente.

Faceti dublu-clic pe butonul color si scrieti codul in rosu:

Page 23: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

23

private void colorButton_Click(object sender, EventArgs e) { ColorDialog cd = new ColorDialog(); if (cd.ShowDialog() == DialogResult.OK) myRichTextBox.SelectionColor = cd.Color; myRichTextBox.Focus(); } Singura deosebire faţă de funcţia anterioară este faptul că nu se schimbă fontul textului selectat, ci culoarea returnată la ieşirea din caseta de dialog.

OpenFileDialog Infrastructura C# oferă casete de dialog pentru manipularea numelor de fişiere. O astfel de casetă este OpenFileDialog:

În această casetă se poate căuta numele unui fişier existent sau adăuga un nou nume. De aseemenea, se permite specificarea tipului de fişier care urmează să fie încărcat. Pentru specificarea tipurilor de fişiere acceptate, trebuie construit un filtru, după următorul mecanism:

“mesaj1 | tip1 fişier | mesaj2 | tip2 fisier | … | mesajn | tipn fişier” Acest filtru trebuie aplicat casetei de dialog după creare cu instrucţiunea new, dar înainte de afişare cu funcţia ShowDialog(). Permite utilizarea aşa numitelor wildcards (semnele ? , respectiv *). Caseta de dialog oferă o serie de proprietăţi utile pentru utilizator. Câteva din acestea sunt:

Title – permite modificarea textului afişat în bara de titlu a casetei de dialog; FileName – numele fişierului (fişierelor) selectate; Deoarece fişierele sunt entităţi externe

programului, încercarea de accesare a unui fişier cu nume eronat poate duce la erori în cadrul programului, respectiv la oprirea lui forţată de către sistemul de operare. De aceea, înainte de a implementa funcţia care se execută la apăsarea butonului open, mai trebuie să vorbim despre

Excepţii

Complexitatea aplicaţiilor actuale, în special a celor orientate pe obiecte, presupune o modularizare pe nivele ierarhice. Această situaţie impune tratarea deosebit de riguroasă a situaţiilor deosebite, în special a erorilor care pot să apară la nivelul diferitelor componente ale unui proiect. În cele ce urmează, vom înţelege prin excepţie o situaţie deosebită care poate să apară pe parcursul execuţiei unei componente soft parte a unei aplicaţii. Erorile pot fi privite ca şi un caz particular de excepţii, dar în general nu toate excepţiile sunt erori.

Page 24: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

24

Excepţiile se împart în două categorii: excepţii sincrone şi excepţii asincrone. Excepţiile sincrone sunt excepţii a căror apariţie poate fi prevăzută de programator (de exemplu, un fişier care se doreşte a fi prelucrat nu se află în directorul aşteptat). Excepţiile asincrone sunt excepţii a căror apariţie nu poate fi prevăzută în momentul implementării programului (de exemplu, defectarea accidentală a hard-disk-ului). Mecanismul de tratare a excepţiilor ia în considerare numai situaţia excepţiilor sincrone.

Problema se pune astfel: în faza de programare, se poate presupune că un modul de program va detecta în anumite situaţii o excepţie, dar nu va putea oferi o soluţie generală de tratare a acesteia, în timp ce un alt modul al aplicaţiei poate oferi o soluţie de tratare a excepţiei, dar nu poate detecta singur apariţia excepţiilor. Exemple tipice de excepţii: împărţire cu 0, accesul la un fişier inexistent, operaţii cu o unitate logică nefuncţională, etc. Uzual, la pariţia unei excepţii, sistemul de operare va opri forţat execuţia modului de program în care excepţia s-a produs, pentru ca acesta să nu afecteze buna funcţionare a celorlalte programe. De multe ori însă este necesar ca excepţia apărută să nu fie transmisă sistemului de operare, ci să fie “prinsă” şi tratată în interiorul modulului care a generat-o. Acest lucru este posibil prin intermediul unui mecanism bazat pe 2 instrucţiuni: try şi catch. Mecanismul este următorul: zona critică, adică zona de cod în care programatorul prevede posibilitatea apariţiei unei excepţii este scrisă într-un bloc try. Blocul try este urmat de unul su mai multe blocuri catch, cîte unul pentru fiecare tip de execepţie ce poate să apară. Execuţia programelor în acest caz este prezentată în fig. a şi b. Fig. a prezintă situaţia normală de execuţie, când în secţiunea critică nu apare excepţie. În acest caz, se execută în succesiune normală toate instrucţiunile din secţiunea critică, după care, următoarea instrucţiune executată este prima de după blocul catch, acesta fiind neglijat.

Fig. b prezintă situaţia apariţiei unei excepţii. În acest caz, următoarea unstrucţiune executată după cea care a generat excepţia este prima din blocul catch, în acesta urmând a fi tratată excepţia. După execuţia instrucţiunilor din blocul catch, se continuă în secvenţă normală, cu prima instrucţiune de după acesta. Marea majoritate a claselor care lucrează cu entităţi externe memoriei generează excepţii, pentru ca posibilele erori să poată fi tratate încă din faza de programare. Este şi cazul claselor care lucrează cu fişiere şi este indicat ca toate operaţiile făcute asupra fişierelor să fie tratate prin mecanismul try-catch. Cu aceasta, putem implementa funcţia openButton_Click(): private void openButton_Click(object sender, EventArgs e) { OpenFileDialog of = new OpenFileDialog(); of.Title = "Deschide fisier"; of.Filter = "Rich text |*.rtf"; if (of.ShowDialog() == DialogResult.OK)

Page 25: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

25

{ try { myRichTextBox.LoadFile(of.FileName); } catch(SystemException err) { MessageBox.Show(err.ToString()); } } } La început se creează o nouă caseta OpenFileDialog, numită of. Acesteia i se schimbă titlul în Deschide fisier şi se creează un filtru, astfel încât să se poată selecta fişiere de tip *.rtf. Apoi caseta este dechisă şi se verifică revenirea cu OK. Dacă s-a revenit cu OK, se încarcă fişierul cu numele returnat de of în proprietatea FileName, dar într-o secvenţă critică. Orice eroare va genera o excepţie de clasă SystemException, care este “prinsă” în blocul catch şi este afişat mesajul asociat erorii, generat de obiectul de clasă SystemException. SaveFileDialog

Aceasta permite salvarea cu un nume ales sau dat a unui fişier. Modul de lucru cu această casetă de dialog este absolut similar casetei OpenFileDialog. Deci, funcţia care se execută la apăsarea butonului saveButton va fi: private void saveButton_Click(object sender, EventArgs e) { SaveFileDialog sf = new SaveFileDialog(); sf.Title = "Salveaza fisierul"; sf.Filter = "Rich text|*.rtf|Plain text|*.txt"; if (sf.ShowDialog() == DialogResult.OK) { try { myRichTextBox.SaveFile(sf.FileName); } catch (SystemException err) { MessageBox.Show(err.ToString()); } } }

Page 26: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

26

List View Control Mai avem de implementat agenda. Pentru aceasta, vom studia controlul numit ListView. Acest control este uzual folosit pentru a permite utilizatorului să aibă control asupra detaliilor şi stilului de prezentare. Datele pot fi prezentate tabelar, pe linii şi coloane, sub forma de grilă, într-o singură coloană sau având asociate diferite pictograme (ImageList control). Similar celorlalte controale, ListView oferă un set de proprietăţi, metode şi evenimente. Cîteva din proprietăţi sunt:

Activation – pe baza acestei proprietăţi, utilizatorul poate controla modul de activare al unui element de listă. Valorile posibile sunt:

o Standard – mod de activare standard. o OneClick – un click asupra elementului de listă are ca efect activarea lui. o TwoClick - dublu click asupra elementului de listă are ca efect activarea lui.

Alignment – specifică alinierea elementelor de listă. Sunt posibile 4 valori: o Default – dacă utilizatorul efectuează un drag-and-drop asupra unui element de

listă, el rămâne acolo unde a fost pus de utilizator. o Left – elementele sunt aliniate spre stânfa în control. o Top – elementele sunt aliniate spre partea de sus a controlului. o SnapToGrid – elementele sunt aliniate în interiorul unei grile invizibile.

AllowColumnReorder – dacă această proprietate este true, ordinea coloanelor în listă poate fi schimbată în timpul execuţiei programului. În acest caz trebuie acordată o atenţie sporită funcţiilor care inserează elemente în ListView, pentru ca inserarea să se facă în coloana potrivită.

Autoarrange – dacă această proprietate este true, elementele de listă se vor aranja singure conform valorii din proprietatea Alignment. Acesată proprietate funcţionează doar dacă proprietatea View este LargeIcon sau SmallIcon.

CheckBoxes – dacă această proprietate este true, fiecare element de listă va avea un checkbox în stânga. Funcţionează doar dacă proprietatea View este Details sau List.

CheckedIndices, CheckedItems – aceste proprietăţi reprezintă colecţii care stochează indicii elementelor, respectiv elementele care sunt bifate în listă.

Columns – permite accesul la o colecţie de coloane din listă, permiţând ştergerea sau adăugarea de coloane.

FocusedItem – menţine elementul care are focusul în interiorul listei. FullRowSelect – dacă această proprietate este true, la selectarea unui element se

selectează întreaga linie din care face parte. Dacă este false, se selectează doar elementul asupra căruia s-a făcut click.

GridLines - dacă această proprietate este true, controlul va afişa o grilă de demarcare a liniilor şi coloanelor. Funcţionează doar dacă proprietatea View este Details

HeaderStyle – permite specificarea modului de afişare a capetelor de coloane. Poate avea valorile:

o Clickable – capetele de tabel funcţionează ca şi nişte butoane o NonClickable – capetele de tabel nu răspund la apăsarea butonului mousului. o None – capetele de tabel nu sunt afişate.

Items – colecţia de elemente de listă. LabelEdit – dacă este true, utilizatorul poate edita conţinutul primei coloane într-o listă

cu View pus pe Details. LargeImageList – proprietatea stochează ImageList care stochează la rândul ei

imaginile. Funcţionează dacă View este LargeIcon. MultiSelect – dacă este true, este permisă selectarea simultană a mai multor elemente

de listă. Scrollable – dacă este true, se afişează bare de defilare. SelectedIndices, SelectedItems - aceste proprietăţi reprezintă colecţii care stochează

indicii elementelor, respectiv elementele selectate în listă.

Page 27: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

27

SmallImageList - proprietatea stochează ImageList care stochează la rândul ei imaginile. Funcţionează dacă View este SmallIcon.

Sorting – controlul poate sorta elementele de listă înainte de afişare. Poate fi: o Ascending o Descending o None

TopItem – returnează elementul din capul listei. View – precizează modul de afişare a elementelor în listă. Poate fi:

o LargeIcon – toate elementele sunt afişate cu o pictogramă mare (32x32 pixeli) şi o etichetă.

o SmallIcon - toate elementele sunt afişate cu o pictogramă mică (16x16 pixeli) şi o etichetă.

o List – afişarea se face pe o singură coloană, care poate conţine o pictogramă şi o etichetă.

o Details – afişarea se poate face pe oricâte coloane, dar doar prima coloană poate conţine pictograme.

Câteva din metodele ce pot fi executate de control sunt:

Add() – adaugă elemente de listă. BeginUpdate() – prin apelarea acestei metode, controlul ListView va înceta desenarea

liniilor actualizate până când va fi apelată metoda EndUpdate(). Această metodă evită pâlpâirea ecranului atunci când sunt inserate mai multe elemnte simultan şi creşte viteza de actualizare a listei.

Clear() – şterge toate elementele listei. EndUpdate() – termină actualizarea listei şi toate elementele sunt afişate.

Câteva din evenimentele mai semnificative generate de control:

ColumnClick – este generat atunci când se face click pe o coloana. ItemActivate – este generat etunci când un element de listă este activat

Vom construi agenda pe baza celor prezentate mai sus.

Selectati pagina Agenda Trageti in pagina un control ListView si setati urmatoarele proprietati

o (Name): agendaListView o Dock: Fill (elementul va ocupa tot spatiul disponibil) o ForeColor: Navy o GridLines: True o View: Details

Cautati in Toolbox in sectiunea Components elementul ImageList. Pentru al adauga proiectului faceti dublu-clic pe el. Elementul va fi afisat sub forma. Selectati elementul si setati urmatoarele proprietati:

o (Name): myImageList o Cautati pe net doua pictograme de cca 32 x 32 pixeli reprezentand un semn de

intrebare, respectiv o exclamatie si salvati-le in directorul Imagini creat anterior in discul D sub numele question.jpg, respectiv exclamation.jpg

o Reventi la myImageList si faceti clic pe caseta cu trei puncte din dreapta proprietatii Images

o In fereastra Image Collection Editor care se deschide apasati tasta Add si adaugati prima pictograma si inca odata Add pentru a adauga a doua pictograma. Cand ati terminat apasati OK

Page 28: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

28

Reveniti la agendaListView, selectati proprietatea SmallImageList si din lista care se

deschide selectati myImageList. In acest fel, agenda va folosi ca pictograme cele doua imagini incarcate in myImageList.

Ca si pentru paginile anterior create, va trebui sa activam, respectiv sa dezactivam agenda conform selectiilor facute in pagina Setari. Vom adauga in Form1.cs codul celor doua functii: private void DezactiveazaAgenda() { agendaListView.Enabled = false; } private void ActiveazaAgenda() { agendaListView.Enabled = true; } Vom adauga apelurile in Load(), adaugaButton_Click si stergeButton_Click asa cum am procedat si pentru celelalte pagini: private void mainForm_Load(object sender, EventArgs e) { ........ DezactiveazaEditor(); DezactiveazaAgenda(); } ........ private void adaugaButton_Click(object sender, EventArgs e) { if (totalChkListBox.CheckedItems.Count > 0) //sunt selectati itemi in lista { existentChkListBox.Items.Clear(); //stergem toti itemii din a doua lista foreach (string item in totalChkListBox.CheckedItems) { existentChkListBox.Items.Add(item.ToString()); //am adaugat in a doua lista itemii selectati din prima lista if (item.ToString() == "Calculator") //aplicatia a fost selectata

Page 29: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

29

ActiveazaCalculator(); //calculatorul este activat if (item.ToString() == "Editor texte") ActiveazaEditor(); //editorul este activat if (item.ToString() == "Agenda") //aplicatia a fost selectata ActiveazaAgenda(); //agenda este activata } ....... } } ........ private void stergeButton_Click(object sender, EventArgs e) { foreach (string item in existentChkListBox.CheckedItems) { if (item.ToString() == "Calculator") DezactiveazaCalculator(); if (item.ToString() == "Editor texte") DezactiveazaEditor(); if (item.ToString() == "Agenda") DezactiveazaAgenda(); } ........ } Acum urmează să implementăm o funcţie care defineşte capul de tabel şi populează cu intervale orare prima coloană a listei. Vom numi această funcţie GenereazaOre() şi va avea implementarea de mai jos. private void GenereazaOre() { agendaListView.Items.Clear(); //sterge toti itemii din lista ColumnHeader capLista; //declara o coloana tip header capLista = new ColumnHeader(); //creeaza coloana capLista.Text = "Orele"; //titlul coloanei capLista.Width = 70; //latimea coloanei capLista.TextAlign = HorizontalAlignment.Center; //alinierea textului din coloana agendaListView.Columns.Add(capLista); //adauga coloana in lista capLista = new ColumnHeader(); //creeaza o noua coloana capLista.Text = "Activitate"; capLista.Width = 70; capLista.TextAlign = HorizontalAlignment.Center; agendaListView.Columns.Add(capLista); //adauga in lista coloana ListViewItem ore; //declara un item pentru lista agendaListView.BeginUpdate(); //incepe actualizarea listei try { for (int i = 8; i <= 20; i += 2) { ore = new ListViewItem(); //creeaza o noua linie pentru lista ore.Text = Convert.ToString(i) + "-" + Convert.ToString(i + 2); ore.ImageIndex = 0; agendaListView.Items.Add(ore); //adauga linia in lista }

Page 30: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

30

} catch(Exception err) { MessageBox.Show("Eroare: " + err.ToString()); } agendaListView.EndUpdate(); //se incheie actualizarea listei } Funcţia începe prin a şterge complet toate elementele din listă. Apoi începe construcţia capului de listă, prin definirea unor capete de coloană, care sunt obiecte de clasă ColumnHeader. Fiecare apel new ColumnHeader() va defini o nouă coloană.Adaugarea efectivă a fiecărei coloane în listă se face prin apelul funcţiei agendaListView.Columns.Add(capLista). Acum urmează popularea primei coloane din listă. Vom declara un obiect de clasă ListViewItem, adică element de listă. Vom marca începutul populării listei, ceea ce va avea ca efect blocarea afişării elementelor până la sfârşitul populării (vezi funcţia BeginUpdate()). Apoi, vom popula cu intervele orare de 2 ore, începând cu ora 8 şi terminând cu ora 22. Fiecare nouă linie în listă se defineşte prin new ListViewItem(). Practic, prin inserarea unui element în prima coloană a listei, se va creea automat câte o linie nouă pentru fiecare element în parte. Toate elementele de pe celelalte coloane, vor fi definite ca subelemente (SubItems) ale elementelor de pe prima coloană, linia pe care sunt inserate fiind definită de elementul cărora le sunt asociate. Pentru fiecare element nou introdus, se transformă intervalul orar în text şi i se atribuie imaginea de index=0 din myImageList (în cazul nostru imaginea stocată în fişierul question.jpg). Inserarea efectivă a fiecărui element (respectiv deschiderea unei noi linii în listă) se face prin apelul agendaListView.Items.Add(). Tot mecanismul este inserat în blocuri try-catch, pentru a intercepta posibilele excepţii ce apar la crearea listei. La crearea listei se poate genera o excepţie de clasă Exception care este interceptată şi mesajul aferent este afişat. Funcţia GenereazaOre(), va trebui apelată la iniţializarea formei, pentru a completa prima coloană şi ori de câte ori se schimbă data în controlul MonthCalendar. Vom insera apelul acestei funcţii astfel: private void mainForm_Load(object sender, EventArgs e) { ......... DezactiveazaAgenda(); GenereazaOre(); } si: private void myCalendar_DateChanged(object sender, DateRangeEventArgs e) { myCalendar.TodayDate = e.Start; CompleteazaData(); GenereazaOre(); } Compilaţi şi executaţi programul. Se poate observa modul de afişare a listei. În mod normal, inserarea unei activităţi în agendă se face prin apăsarea dublu-click asupra elementului care reprezintă intervalul orar. Un dublu-click asupra unui element de listă, va genera evenimentul ItemActivate. Acest eveniment va trebui să-l interceptăm şi să-i asociem o funcţie. Pentru a crea acest administrator:

Selectati controlul agendaListView din pagina, selectati in fereastra Properties tabul Events, cautati evenimentul ItemActivate si faceti dublu-clic pe el pentru a crea administratorul corespunzator.

private void agendaListView_ItemActivate(object sender, EventArgs e) {

Page 31: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

31

} Acest handler, după cum ştim deja, la fecare dublu-click asupra unui element de listă, va lansa în execuţie funcţia agendaListView_ItemActivate(). În mod normal, introducerea textului nu se face direct în listă, ci într-o nouă formă, ce va fi lansată ca un DialogBox utilizator, pentru a se putea face validarea sau invalidarea textului introdus. Deci, înainte de a implementa funcţia, să vedem cum putem construi o nouă formă pe care s-o definim ca DialogBox. Adăugarea unui DialogBox utilizator Pentru definirea unui DialogBox particularizat, va trebui întâi să adăugăm proiectului o nouă formă.

Alegeti din meniul C# optiunea ProjectAdd Windows Forms In fereastra care se deschide numiti noua forma ActivityForm si apasati butonul Add Pentru noua forma care se deschide setati urmatoarele proprietati:

o BackColor: LightGray (Web) o Font: Bold o ForeColor: Navy o FormBorderStyle: FixedDialog o MaximizeBox: False o MinimizeBox: False o Size: 580, 135 o Text: Adauga o activitate in agenda

Trageti pe forma, in partea stanga, trei controale Label si setati, in ordine de sus in jos, urmatoarele proprietati:

o (Name): dateLabel, hourLabel, messageLabel o Location: (42, 18); (42, 44); (42, 73) o Text: Data, Ora, Mesaj

Trageti pe forma trei controale TextBox, cate una in dreapta fiecarei etichete si setati urmatoarele proprietati:

o (Name): dateTextBox, hourTextBox, messageTextBox o Location: (94, 12); (94, 38); (94, 73) o ReadOnly: True (numai pentru primele doua casete de text) o Size: (115, 20); (115, 20); (450, 20)

Trageti pa forma doua controale Button, in partea dreapta a formei, si setati, de sus in jos, urmatoarele proprietati:

o (Name): okButton, cancelButton o DialogResult: Ok, Cancel o Location: (435, 12); (435, 44) o Size: 85, 23 o Text: OK, Cancel

Forma ar trebui sa arate astfel:

Dorim ca la lansarea formei, în dateTextBox.Text să fie scrisă data selectată în controlul MonthCalendar din forma principală, iar în hourTextBox.Text să fie trecut intervalul orar din

Page 32: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

32

agendaListView. De asemenea, la revenirea din DialogBox, să trecem în agendaListView, la intervalul orar corespunzător, conţinutul messageTextBox.Text. Problema apare datorită faptului că obiectele şi proprietăţile obiectelor sunt declarate private în fiecare formă, adică nu vom putea accesa direct obiecte si proprietăţi din mainForm în ActivityForm şi reciproc. Pentru a rezolva aceasta problema, in ActivityForm vom implementa functii publice de lucru cu controalele. Astfel, vom avea 2 funcţii SetData(String text) şi SetOra(String text), care vor înscrie în proprietatea Text a controalelor textul primit ca argument şi, respectiv GetMessage(), care va returna conţinutul proprietăţii Text a controlului messageTextBox. Pentru a le implementa, vom intra în zona de cod a ActivityForm apasand tasta F7. public void SetData(String s) { dateTextBox.Text = s; } public void SetOra(String s) { hourTextBox.Text = s; } public String GetMessage() { return messageTextBox.Text; } Cu aceasta definirea formei de dialog este completa. Revenim in maiForm in pagina Agenda si completam administratorul ItemActivate: private void agendaListView_ItemActivate(object sender, EventArgs e) { ActivityForm fr = new ActivityForm(); //creaza o forma de dialog fr.SetData(dateLabel.Text); //completeaza caseta cu data selectata in calendar ListView.SelectedIndexCollection indici = agendaListView.SelectedIndices; //memoreaza itemii selectati in agenda agendaListView.BeginUpdate(); foreach (int index in indici) { fr.SetOra(agendaListView.Items[index].Text); //completeaza caseta cu ora selectat in agenda agendaListView.Items[index].ImageIndex = 1; //modifica pictograma afisata in agenda } if (fr.ShowDialog() == DialogResult.OK) //a fost apasat butonul OK { ListViewItem.ListViewSubItem mesaj; //se creeaza un subitem pentru agenda mesaj = new ListViewItem.ListViewSubItem(); mesaj.Text = fr.GetMessage(); //preia mesajul introdus in forma de dialog ListView.SelectedListViewItemCollection items = agendaListView.SelectedItems; //memoram itemii selectati in agenda foreach (ListViewItem item in items) //pentru fiecare item selectat in agenda { item.SubItems.Add(mesaj); //adauga mesajul preluat din forma de dialog }

Page 33: PV 7 C# · 2015-02-09 · In acest cod, data curenta (TodayDate) evidentiata pe calendar este setata la data de inceput a intervalului selectat de utilizator (proprietatea Start a

33

} agendaListView.EndUpdate(); } Ce face funcţia? La început construieşte un nou obiect ActivityForm, numit fr. Pentru acest obiect, apelează fr.SetData() pentru a completa fr.dateTextBox.Text cu data selectată. Declară apoi un obiect de clasă ListView.SelectedIndexCollection, care reprezintă o colecţie de elemente de indici ai elementelor de listă selectate şi populează această listă cu indicii elementelor selectate în agendaListView (în cazul nostru, doar indicele elementului pe care s-a făcut dublu click). Marchează apoi începutul actualizării listei. Pentru toate elementele cu indicii salvaţi în colecţie, setează ora din fr.hourTextBox.Text la valoarea proprietăţii Text a elementelor de listă selectate şi respectiv schimbă imaginea la indexul 1 din myImageList (fişierul exclamation.jpg). Să ne reamintim că în listă există doar indicele elementului pe care s-a făcut dublu click. Apoi, lansează caseta DialogBox fr. Dacă din aceasta se revine prin apăsarea butonului OK, creează un obiect de tip SubItem al unui element de listă (să ne reamintim că statutul de Item îl au doar elementele din prima coloană, toate celelalte fiind SubItem). Pentru obiectul nou creeat completează proprietatea Text cu textul din fr.messageTextBox.Text. Urmează ca acest SubItem să fie aşezat în coloana a doua, pe linia definită de Item-ul corespunzător. Pentru aceasta, declară un obiect ListView.SelectedListViewItemCollection, care reprezintă o colecţie de elemente de listă selectate şi populează această colecţie cu elementul selectat în agendaListView (să ne reamintim din nou, e doar cel pe care s-a făcut dublu click). După care, adaugă elementului selectat subelementul nou format, prin intermediul funcţiei Add(). În final, marchează sfârşitul actualizării listei, pentru a se putea desena conţinutul ei. Cu aceasta, aplicaţia este completă. Compilaţi şi executaţi programul, verificând modul de completare a listei. Dar ce se întâmplă dacă schimbăm data şi apoi revenim la data iniţială? Se observă că tot ce-am introdus, s-a pierdut. Acesta, deoarece informaţiile nu au fost salvate nicăieri. În mod normal, toate aceste informaţii ar fi trebuit să fie salvate într-o bază de date. Dar despre aceasta, într-un curs următor.