Web järjestelmän ohjelmointi Kevät 2012 Hans Nieminen



Samankaltaiset tiedostot
Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Web Services tietokantaohjelmoinnin perusteet

C# Windows ohjelmointi perusopas

Olio-ohjelmointi Javalla

14. Poikkeukset 14.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Jypelin käyttöohjeet» Ruutukentän luominen

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Listarakenne (ArrayList-luokka)

Mikä yhteyssuhde on?

Ohjelmoinnin jatkokurssi, kurssikoe

14. Poikkeukset 14.1

Sisällys. 14. Poikkeukset. Johdanto. Johdanto

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

on ohjelmoijan itse tekemä tietotyyppi, joka kuvaa käsitettä

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Rajapinta (interface)

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Microsoft Visual Studio 2005

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Javan perusteita. Janne Käki

1. Omat operaatiot 1.1

Harjoitustyö: virtuaalikone

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

Taulukot. Jukka Harju, Jukka Juslin

KOHDELUOKAN MÄÄRITTELY

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

JUnit ja EasyMock (TilaustenKäsittely)

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

Tietokannat II -kurssin harjoitustyö

Ohjelmoinnin perusteet Y Python

1 Tehtävän kuvaus ja analysointi

Ohjelmoinnin perusteet Y Python

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

ITKP102 Ohjelmointi 1 (6 op)

Periytyminen (inheritance)

Pong-peli, vaihe Aliohjelmakutsu laskureita varten. 2. Laskurin luominen. Muilla kielillä: English Suomi

Ohjelmoinnin perusteet Y Python

9. Periytyminen Javassa 9.1

Kompositio. Mikä komposition on? Kompositio vs. yhteyssuhde Kompositio Javalla Konstruktorit set-ja get-metodit tostring-metodi Pääohjelma

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

Graafisen käyttöliittymän ohjelmointi

15. Ohjelmoinnin tekniikkaa 15.1

Ajokorttimoduuli Moduuli 2. - Laitteenkäyttö ja tiedonhallinta. Harjoitus 1

15. Ohjelmoinnin tekniikkaa 15.1

Haaga-Helia/IltaTiko ict2tcd005: Ohjelmiston suunnittelutaito 1/7 Anne Benson. Tällä opintojaksolla käytämme VS:n kolmen kokonaisuuden luomiseen:

Sähköposti ja uutisryhmät

815338A Ohjelmointikielten periaatteet

A) on käytännöllinen ohjelmointitekniikka. = laajennetaan aikaisemmin tehtyjä luokkia (uudelleenkäytettävyys)

Poikkeustenkäsittely

Ohjelmointi 2 / 2010 Välikoe / 26.3

Sisällys. JAVA-OHJELMOINTI Osa 6: Periytyminen ja näkyvyys. Luokkahierarkia. Periytyminen (inheritance)

Apuja ohjelmointiin» Yleisiä virheitä

Ohjelmoinnin perusteet Y Python

Muistitikun liittäminen tietokoneeseen

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

19. Olio-ohjelmointia Javalla 19.1

Internet Explorer 7 & 8 pop-up asetukset

Interaktiivinen tarinankerronta

5 Näppäimistö. 5.1 Näppäimistön eventit

Olio-ohjelmointi Virhetilanteiden käsittely

10 Lock Lock-lause

Sisällys. 19. Olio-ohjelmointia Javalla. Yleistä. Olioiden esittely ja alustus

Java kahdessa tunnissa. Jyry Suvilehto

YHTEYSSUHDE (assosiation)

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

Java-kielen perusteet

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

UML ja luokkien väliset suhteet

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet

Pong-peli, vaihe Koordinaatistosta. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 2/7. Tämän vaiheen aikana

TimeEdit opiskelijan ohje TimeEdit-instructions for students from this link

Java-kielen perusteet

9. Periytyminen Javassa 9.1

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä

3.3 Kurssin palauttaminen

Ohjelmoinnin perusteet Y Python

Metodit Arvotyyppi. Metodit Arvotyyppi. Metodit Parametrit. Metodit Parametrit. Metodit Kuormittaminen. Metodit Kuormittaminen. Javan perusteet

OpenOffice.org Base 3.1.0

Ohjelmoinnin perusteet Y Python

Harjoitus 3: Flash-komponenttiarkkitehtuuri ( )

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Poikkeukset ja tietovirrat: Virhetilanteiden ja syötevirtojen käsittely

Dialogit. Juha Järvensivu 2008

Wilman käyttöohje huoltajille

4. Luokan testaus ja käyttö olion kautta 4.1

Tukipyyntö-toiminnon ohje

Ohjelmoinnin perusteet Y Python

C# olio-ohjelmointi perusopas

Collector for ArcGIS. Ohje /

HYVÄKSILUKEMISEN TEKEMINEN ILMAN ENNAKKOPÄÄTÖSTÄ

Luokan sisällä on lista

Sisällys. 9. Periytyminen Javassa. Periytymismekanismi Java-kielessä. Periytymismekanismi Java-kielessä

Transkriptio:

Harjoitus 1 Käsiteltävät aiheet: C# kielen kertaus luokat, oliot ja periytyminen poikkeukset ja niiden käsittely tapahtumat ja niiden käsittely C# 3.0 uudet ominaisuudet Visual Studio projektin kansiot Visual Studio 2010 projekteihin liittyvät tiedostot tallentuvat kansioihin, jotka on määriteltävissä käyttäjäkohtaisesti toiminnolla Tools Opons: Projektitiedostojen (.sln ja.suo) sijaintikansio. Projekti Tehdään uusi Windows ohjelma WJOH1. File New Project Valitse Windows Forms Application ja anna nimeksi WJOH1. Tallenna projekti C levyn johonkin kansioon. Anna Solution name: kenttään sama nimi WJOH1. 1

Luokat Lisää nyt Solutioniin WJOH1 uusi projekti, johon toteutetaan harjoituksen luokat. Valitse Solution Explorer ikkunassa Solution WJOH1 ja avaa hiiren oikealla sen pikavalikko. Valitse vaihtoehto Add New Project... Valitse Class Library ja anna nimeksi WJOH1Luokat. 2

Poista WJOH1Luokat projektista sinne oletuksena tehty luokka Class1.cs ( hiiren oikealla pikavalikko, josta Delete). Toteuta WJOH1Luokat projektiin seuraavan luokkakaavion mukaiset luokat Henkilo, Tyontekija ja Osasto. 3

Uusi luokka lisätään projektiin toiminnolla Project Add Class... (tai Solution Explorer ikkunassa pikavalikosta Add Class...): Henkilo luokassa: Luokan näkyvyysmääreenä public. Kenttien näkyvyysmääreenä protected. Ominaisuudet EtuNimi, SukuNimi ja SyntymaAika kapseloivat vastaavat kentät. Ominaisuudessa Ika vain get metodi palauttaen syntymäajan ja kuluvan päivän perusteella lasketun iän vuosina. Konstruktoria ei tarvitse koodata. ToString() ylikirjoitetaan (override) palauttamaan henkilön nimen muodossa etunimi sukunimi. Tyontekija luokassa: Luokan näkyvyysmääreenä public. Periytetään luokasta Henkilo. Kenttien näkyvyysmääreenä private. Ominaisuudet Palkka, PalkkausPvm ja PaattymisPvm kapseloivat vastaavat kentät. Konstruktoreita kaksi: o kolme parametria, joiden arvot sijoitetaan ominaisuuksiin EtuNimi, SukuNimi ja SyntymaAika. o neljä parametria, joiden arvot sijoitetaan ominaisuuksiin EtuNimi, SukuNimi, SyntymaAika ja Palkka. Lisäksi ominaisuuteen PalkkausPvm sijoitetaan arvoksi kuluva päivämäärä. ToString() ylikirjoitetaan (override) palauttamaan työntekijän tiedot muodossa etunimi sukunimi ( syntymäpäivä). Osasto luokassa: Luokan näkyvyysmääreenä public. Ominaisuudet Nimi ja Tyontekijat kapseloivat vastaavat kentät. Ominaisuudessa HenkiloLkm on vain get metodi palauttaen Tyontekijat ominaisuuden sisältämän listan alkioiden määrän. Konstruktori, jonka parametri n sijoitetaan Nimi ominaisuuteen. Lisäksi ominaisuuteen Tyontekijat sijoitetaan uusi List<Tyontekija> olio. 4

ToString() ylikirjoitetaan (override) palauttamaan osaston nimen ja henkilömäärän muodossa nimi (henkilömäärä). Metodi Palkkaa(), jonka parametri h (Tyontekija olio) lisätään ominaisuuden Tyontekijat listalle ja parametri p sijoitetaan parametrin h sisältämän olion ominaisuuteen Palkka. Lisäksi sijoitetaan parametrissa välitetyn Tyontekija olion PalkkausPvm ominaisuuteen kuluva päivä. Metodi Erota(), jonka parametri h (Tyontekija olio) poistetaan ominaisuuden Tyontekijat listalta. Lisäksi sijoitetaan parametrissa välitetyn Tyontekija olion PaattymisPvm ominaisuuteen kuluva päivä. Poikkeusluokka ja poikkeuksen nostaminen Työntekijällä on palkka, jonka tulee olla ei negatiivinen desimaaliluku. Luodaan oma poikkeus NegatiivinenPalkkaException, joka synnytetään, jos palkaksi annetaan negatiivinen arvo. Lisää WJOH1Luokat projektiin luokka, joka periytetään luokasta ApplicationException ja joka sisältää neljä konstruktoria: public class NegatiivinenPalkkaException : ApplicationException public NegatiivinenPalkkaException() public NegatiivinenPalkkaException(string message) public NegatiivinenPalkkaException(string message, System.Exception inner) public NegatiivinenPalkkaException( System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) Muuta Tyontekija luokan Palkka ominaisuuden set metodin logiikka seuraavaksi: Jos uusi palkka on ei negatiivinen, sijoita arvo kenttään _palkka, muuten nosta (throw) NegatiivinenPalkkaException poikkeus luomalla olio konstruktorilla, johon argumentiksi merkkijono Palkka ei saa olla negatiivinen. Tapahtumat Luokkaan Osasto lisätään tapahtuma Palkkaaminen, joka syntyy aina uuden työntekijän palkkaamisen yhteydessä. tapahtuma Erottaminen, joka syntyy aina työntekijän erottamisen yhteydessä. Tavoitteena on mahdollistaa Osasto oliokohtainen reagointi palkkaamiseen ja erottamiseen. Tapahtumien määrittely Tee tiedostoon Osasto.cs seuraavat lisäykset: 5

Ota käyttöön nimiavaruus System.ComponentModel (tarvitaan luokan CancelEventArgs käytön takia). Määrittele ennen luokan Osasto määrittelyä tapahtumien tarvitsemat delegaattityypit näkyvyysmääreellä public: o delegaattityyppi PalkkaaminenHandler, joka määrittelee tapahtumakäsittelijöiden rakenteeksi: paluuarvo: ei ole parametrit: object tyyppinen sender, Tyontekija tyyppinen t ja CancelEventArgstyyppinen e o delegaattityyppi ErottaminenHandler, joka määrittelee tapahtumakäsittelijöiden rakenteeksi: paluuarvo: ei ole parametrit: object tyyppinen sender, Tyontekija tyyppinen t ja EventArgstyyppinen e Määrittele luokkaan Osasto tapahtumat: o Palkkaaminen, jonka tyyppinä on PalkkaaminenEventHandler o Erottaminen, jonka tyyppinä on ErottaminenEventHandler Tapahtumien synnyttäminen Lisää luokan Osasto metodin Palkkaa() olemassa olevan koodin eteen seuraava koodi: Jos tapahtumalla Palkkaaminen on arvo (vertaa arvoon null), o Määrittele paikallinen CancelEventArgs tyyppinen muuttuja ja sijoita sen arvoksi ko. tyypin olio. o Kutsu tapahtumaan sijoitettua metodia viittaamalla tapahtuman nimeen Palkkaaminen ja antamalla argumenteiksi nykyinen Osasto olio (eli merkintä this), palkattava Tyontekija olio (saatu argumenttina metodiin Palkkaa()) ja edellä luotu CancelEventArgs olio. o Jos CancelEventArgs olion ominaisuuden Cancel arvoksi on tullut tosi (true), lopeta metodin Palkkaa() suoritus tähän lauseella return. Tällöin varsinaista palkkaamista ei siis tapahdu. Näin tapahtumakäsittelijä voi estää metodin varsinaisen toiminnan. Lisää luokan Osasto metodin Erota() olemassa olevan koodin eteen seuraava koodi: Jos tapahtumalla Erottaminen on arvo (vertaa arvoon null), o Kutsu tapahtumaan sijoitettua metodia viittaamalla tapahtuman nimeen Erottaminen ja antamalla argumenteiksi nykyinen Osasto olio (eli merkintä this), erotettava Tyontekija olio (saatu argumenttina metodiin Palkkaa()) ja tässä luomasi EventArgs olio. Muokkaa vielä ToString() metodia niin, että sen palauttaman merkkijonon loppuun lisätään merkkijono PI, jos tapahtumalla Palkkaaminen on arvo ja merkkijono EI, jos tapahtumalla Erottaminen on arvo. Käyttöliittymä Lisää projektiin WJOH1 (eli Windows ohjelma) viittaus edellä tehtyyn luokkakirjastoon WJOH1Luokat: Valitse Solution Explorer ikkunassa WJOH1 projektin References kohdan pikavalikosta (hiiren oikea) Add Reference... 6

Valitse Add Reference ikkunassa projekti WJOH1Luokat ja paina OK. Siirry Windows ikkunan muokkaamiseen (välilehti Form1.cs[Design]*). Suurenna ikkunan kokoa vetämällä sitä reunoista ( muuta lisää tarpeen mukaan myöhemmin). 7

Siirry Properties ikkunaan (oletuksena oikessa reunassa) ja vaihda siinä ikkunan ominaisuuden Text arvoksi: Työntekijät Osastot. Tällöin muutos näkyy heti: Siirry sitten Toolbox ikkunaan (oletuksena vasemmassa reunassa). Toolbox ikkunan saa jäämään näkyviin nasta painikkeesta, josta ikkuna voidaan myös poistaa näkyvistä. Vedä ikkunaan seuraavat kontrollit: 8

TextBox Label Button ListBox CheckBox Siirry ikkunaa vastaavaan C# tiedostoon Form1.cs (esimerkiksi valitsemalla Design ikkunassa pikavalikosta View Code). Tarkasteltaessa koodia huomataan, että Windows ikkunaa vastaa Form luokasta (System.Windows.Forms.Form) periytetty luokka Form1. Luokan määrittely on jaettu kahteen eri tiedostoon (partial class): o Toiseen tiedoistoista kirjoitetaan omat koodit (Form1.cs) ja o toiseen muodostaa Visual Studio koodin (Form1.Designer.cs). Konstruktorissa kutsutaan metodia InitializeComponent(), jonka määrittely löytyy luokan toisesta tiedostosta (Form1.Designer.cs). Tutki myös tiedoston Form1.Designer.cs sisältöä. Huomaa, että jokainen lisätty kontrolli on Form1 luokan kenttä. InitializeComponent metodissa luodaan kenttiin oliot ja asetetaan olioiden ominaisuuksia ja tapahtumia. 9

Tarkastele myös Program.cs tiedoston sisältöä. Täältä huomaat, että ohjelman suoritus (= Program luokan staattisen Main metodin suoritus) sisältää muutaman Application luokan metodin kutsumisen, joista viimeistä kutsuttaessa luodaan Form1 olio. Osasto olioiden tapahtumakäsittelijät Ohjelmoi kaksi metodia, joita voidaan käyttää Osasto olioiden tapahtumien Palkkaaminen ja Erottaminen yhteydessä. Tapahtumalle Palkkaaminen mahdollisesti käytettävä metodi (paluuarvo ja parametrit on säädetty delegaattityypillä aiemmin) o_palkkaaminen: Metodin otsikko osa: private void o_palkkaaminen(object sender, Tyontekija h, CancelEventArgs e) Jos työntekijän (parametrissa h) sukunimi on Aaltonen, ei palkkausta suoriteta. Tällöin asetetaan CancelEventArgs olion ominaisuus Cancel arvoon tosi (true), mikä aiheuttaa Tyontekija luokan Palkkaa() metodissa (koodattiin aikaisemmin) toiminnan keskeytymisen. Muuten lisää ilmoitustaululle (ListBox) uusi rivi (Items.Add() metodilla), jossa tekstinä o vakio Osastolle o osaston nimi, joka saadaan metodin parametrista sender (sisältää Osasto olion) o vakio palkattu o henkilön tiedot, jotka saadaan metodin parametrin h (Tyontekija olio) metodilla ToString() Tapahtumalle Erottaminen mahdollisesti käytettävä metodi (paluuarvo ja parametrit on säädetty delegaattityypillä aiemmin) o_palkkaaminen: Metodin otsikko osa: private void o_erottaminen(object sender, Tyontekija h, EventArgs e) Lisää ilmoitustaululle (ListBox) uusi rivi (Items.Add() metodilla), jossa tekstinä o vakio Osastolta o osaston nimi, joka saadaan metodin parametrista sender (sisältää Osasto olion) o vakio erotettu o henkilön tiedot, jotka saadaan metodin parametrin h (Tyontekija olio) metodilla ToString() Ikkunan tapahtumakäsittelijät Windows Forms ohjelmassa itse ikkuna on Form luokasta periytetyn luokan (esim. Form1) olio. Tämä olio sisältää kenttiensä arvoina kaikki siihen sisällytetyt kontrollit. Jokaista kontrollia vastaa siis yksi kenttä ja sen arvona oleva olio. Jokaisella kontrollioliolla on valmiina monia eri tapahtumia, joille voidaan ohjelmoida tarpeen mukaan tapahtumakäsittelijöitä. Esimerkiksi ikkunan painikkeet ovat (System.Windows.Forms.)Button olioita. Button oliolla on Clicktapahtuma, joka syntyy käyttäjän napsauttaessa painiketta. Toteutetaan tapahtumakäsittelijä jokaiseen ikkunan viidestä painikkeesta. Tee Osasto olio Lisää painikkeen Tee Osasto olio Click tapahtumalle käsittelijä kaksoisnapsauttamalla sitä Design ikkunassa. Tällöin Form1.cs tiedostoon ilmestyy uusi metodi: private void button1_click(object sender, EventArgs e) 10

Lisäksi Form1.Designer.cs tiedostoon on button1 kentän sisältämän olion tapahtumalle Click sijoitettu arvoksi edellä mainittu metodi: this.button1.click += new System.EventHandler(this.button1_Click); Ohjelmoi tapahtumakäsittelijään seuraava toiminta: Määrittele paikallinen Osasto tyyppinen muuttuja o ja sijoita sen arvoksi uusi Osasto olio käyttäen konstruktorissa argumenttina TextBox kontrollin ominaisuutta Text (esim. textbox1.text = kontrollissa textbox1 näkyvä teksti). Ole tarkka, että viittaat oikeaan TextBox kontrolliin. Jos vaihtoehto Näytä palkkaukset ilmoitustaululla on valittuna (CheckBox kontrollin ominaisuus Checked), sijoita Osasto olion o tapahtumalle Palkkaaminen arvoksi uusi tapahtumakäsittelijä: o.palkkaaminen += new PalkkaaminenHandler(o_Palkkaaminen); Jos vaihtoehto Näytä erottamiset ilmoitustaululla on valittuna (CheckBox kontrollin ominaisuus Checked), sijoita Osasto olion o tapahtumalle Erottaminen arvoksi uusi tapahtumakäsittelijä: o.erottaminen += new ErottaminenHandler(o_Erottaminen); Lisää Osastot kontrollin (ListBox) Items kokoelmaan uusi olio metodilla Add() (esim. listbox1.items.add(o)). Poista teksti Osaston nimi TextBox kontrollista. Poista valinnat molemmista CheckBox kontrolleista. Tee Tyontekija olio Kaksoisnapsauta jälleen painiketta saadaksesi tapahtumakäsittelijän Click tapahtumalle. Ohjelmoi tapahtumakäsittelijään seuraava toiminta: Koska Tyontekija olion tekemisessä tarvitaan DateTime oliota ja koska arvo annetaan kuitenkin merkkijonona (olisi voitu käyttää myös Calendar kontrollia), voi käyttäjä antaa syntymäajaksi mitä tahansa. Mahdollisen virhetilanteen takia toteuta seuraavat try catch lauseella: o Määrittele paikallinen Tyontekija tyyppinen muuttuja t ja sijoita sen arvoksi uusi Tyontekija olio käyttäen konstruktorissa argumenttina TextBox kontrolleihin Työntekijän etunimi, Työntekijän sukunimi ja Syntymäaika syötettyjä arvoja. Huomaa, että syntymäaika tulee aikaansaada DateTime olioksi metodilla DateTime.Parse(). o Lisää ikkunan Työntekijät kontrollin (ListBox) Items kokoelmaan edellä tehty uusi Tyontekija olio metodilla Add(). o Jos edellisissä tuli jokin virhe (poikkeus), näytä viesti ikkunassa virheilmoituksena teksti Työntekijää ei voida tehdä: ja itse virheen syy. Viesti ikkuna saadaan näytettyä luokan MessageBox luokkametodilla Show antamalla esitettävä teksti argumenttina. Virheen syy saadaan catch osan Exception tyyppisen parametrin ominaisuudesta Message (esim. ex.message). Poista teksti Työntekijän etunimi, Työntekijän sukunimi ja Syntymäaika TextBox kontrolleista. Palkkaa Kaksoisnapsauta jälleen painiketta saadaksesi tapahtumakäsittelijän Click tapahtumalle. 11

Ohjelmoi tapahtumakäsittelijään seuraava toiminta: Määrittele paikallinen Osasto tyyppinen muuttuja o ja aseta sen arvoksi Osastot listalla valittuna oleva osasto, johon pääset käsiksi ListBox kontrollin SelectedItem ominaisuuden kautta. Huomaa, että SelectedItem on object tyyppinen, joten se täytyy tyyppimuuntaa Osasto tyyppiseksi. Määrittele vastaavasti paikallinen Tyontekija tyyppinen muuttuja t ja sen arvoksi Tyontekijat listalla valittuna oleva työntekijä. Koska palkka annetaan TextBox kontrollin avulla, voi käyttäjä jälleen syöttää mitä tahansa. Varaudutaan jälleen virheeseen kirjoittamalla toiminta try catch lauseeseen. try osassa: o kutsu Osasto olion Palkkaa() metodia antamalla argumenteiksi Tyontekija olio ja palkka (TextBox kontrollin Text ominaisuudesta muodostettu double arvo > Double.Parse()). o poista Osastot listalta käsiteltävänä oleva Osasto olio ja lisää se sitten heti takaisin listalle ( näin saadaan Osasto olion työntekijämäärä päivittymään). catch osia on nyt kaksi: o käsittele poikkeus NegatiivinenPalkkaException, joka syntyy yritettäessä sijoittaa Palkkaominaisuuteen negatiivista arvoa (ks. Tyontekija luokka). Käsittelynä tulostetaan viestiikkunaan teksti Palkka ei saa olla negatiivinen.. o käsittele kaikki muut poikkeukset (yleisesti Exception). Käsittelynä tulostetaan viestiikkunaan teksti Palkkaus epäonnistui: ja varsinainen virheen syy (ominaisuus Message). Poista teksti Palkka TextBox kontrollista. Erota Kaksoisnapsauta jälleen painiketta saadaksesi tapahtumakäsittelijän Click tapahtumalle. Ohjelmoi tapahtumakäsittelijään seuraava toiminta: Määrittele paikallinen Osasto tyyppinen muuttuja o ja aseta sen arvoksi Osastot listalla valittuna oleva osasto (samoin kuin painikkeen Palkkaa kohdalla). Määrittele vastaavasti paikallinen Tyontekija tyyppinen muuttuja t ja sen arvoksi Tyontekijat listalla valittuna oleva työntekijä. try osassa: o Jos Osasto olion o Tyontekijat ominaisuuden sisältämässä geneerisessä listassa (List<Tyontekija>) on Tyontekija olio t (o.tyontekijat.contains(t)) kutsu Osasto olion o metodia Erota antamalla argumentiksi Tyontekiija olio t. poista Osastot listalta käsiteltävänä oleva Osasto olio ja lisää se sitten heti takaisin listalle ( näin saadaan Osasto olion työntekijämäärä päivittymään). o Muuten tulosta viesti ikkunaan ilmoitus: Työntekijä x ei ole osastolla y, missä x on Tyontekija olion t metodi ToString() ja y on Osasto olion o ominaisuus Nimi. catch osassa: o käsittele kaikki poikkeukset (yleisesti Exception). Käsittelynä tulostetaan viesti ikkunaan teksti Erottaminen epäonnistui: ja varsinainen virheen syy (ominaisuus Message). Näytä työntekijät Kaksoisnapsauta jälleen painiketta saadaksesi tapahtumakäsittelijän Click tapahtumalle. Ohjelmoi tapahtumakäsittelijään seuraava toiminta: 12

Määrittele paikallinen Osasto tyyppinen muuttuja o ja aseta sen arvoksi Osastot listalla valittuna oleva osasto (samoin kuin edellä). Jos muuttuja sisältää arvon (vertaa arvoon null), o aseta otsikkoteksti Label kontrolliin (Text ominaisuuteen) yhdistämällä vakioteksti Osasto ja Osasto olion metodi ToString(). o Tyhjennä ListBox kontrollin aiempi sisältö kutsumalla Items kokoelman metodia Clear(). o Lisää Osasto olion o sisältämät Tyontekija oliot ListBox kontrolliin. Käytä esimerkiksi foreach lausetta. Ohjelman toiminta Lisää ensin uusi osasto antamalla nimi ja rastimalla molemmat kohdat sekä napsauttamalla lopuksi Tee Osasto olio: Lisää vielä toinen osasto niin, että rastit vain ylemmän vaihtoehdon. Esimerkiksi: Lisää sitten työntekijöitä antamalla nimi ja syntymäaika sekä napsauttamalla lopuksi Tee Työntekijä olio: Tee vielä kolme muuta työntekijää: 13

Palkkaa osastolle työntekijä valitsemalla osasto ja työntekijä sekä antamalla palkka: sekä napsauttamalla Palkkaa, jolloin ilmoitustaululle ilmestyy tieto palkkaamisesta (tapahtuma Palkkaa syntyy ja sen tapahtumakäsittelijä o_palkkaaminen suorittuu): Palkkaa muutkin työntekijät. Anna jonkun työntekijän kohdalla negatiivinen palkka, jolloin tulee virheilmoitus: Näytä osaston työntekijät valitsemalla osasto ja napsauttamalla Näytä työntekijät: Erota sitten lopuksi yksi työntekijä molemmista osastoista valitsemalla osasto ja työntekijä sekä napsauttamalla Erota: 14

Huomaa, että vain toisen osaston erottamiset näkyvät ilmoitustaululla: Toinen Windows ohjelmaprojekti (LinqTesti) Lisää ensin WJOH1Luokat projektin luokkiin Osasto ja Tyontekija konstruktori, jossa ei ole parametreja eikä suoritettavia lauseita. Tämä tehdään C# 3.0:n olion uutta alustustapaa varten. Lisää Solutioniin toinen Windows ohjelma: Valitse Solution Explorer ikkunassa Solution WJOH1 ja avaa hiiren oikealla sen pikavalikko. Valitse vaihtoehto Add New Project... Valitse Windows Forms Application ja anna nimeksi LinqTesti. Aseta tämä Windows ohjelma käynnistyväksi ohjelmaksi valitsemalla Solution Explorer ikkunassa projektin LinqTesti pikavalikosta (hiiren oikea) vaihtoehto Set as Startup Project. 15

Lisää LinqTesti projektin viittauksiin (References) viittaus projektiin WJOH1Luokat. o Valitse Solution Explorer ikkunassa LinqTesti projektin References kohdan pikavalikosta (hiiren oikea) Add Reference... o Valitse Add Reference ikkunassa projekti WJOH1Luokat ja paina OK. Olioiden ja kokoelmien alustus Lisää LinqTesti ohjelmaan Form_Load tapahtumakäsittelijä: Valitse Properties ikkunassa Form1. Valitse sitten Events välilehti. Kaksoisnapsauta Load tapahtuman vieressä olevaa ruutua. Tällöin syntyy Form1_Load tapahtumakäsittelijä (metodi) ja avautuu Form1.cs koodi ikkunaan. Lisää Form1.cs tiedostoon nimiavaruus WJOH1Luokat. Lisää Form1.cs tiedoston luokkaan tyyppiä List<Osasto> oleva kenttä osastot. 16

Kirjoita Form1_Load metodiin seuraava koodi: luo kenttään osastot uusi List<Osasto> olio käyttäen C# 3.0:n olioiden ja kokoelmien alustamistapaa: osastot = new List<Osasto> new Osasto Nimi = "Hallinto", Tyontekijat = new List<Tyontekija> new Tyontekija EtuNimi = "Matti", SukuNimi = "Mainio", Palkka = 2100, SyntymaAika = new DateTime(1965,3,13), PalkkausPvm = new DateTime(1990,7,1), new Tyontekija EtuNimi = "Jussi", SukuNimi = "Juonio", Palkka = 2500, SyntymaAika = new DateTime(1964,9,7), PalkkausPvm = new DateTime(1988,5,1), new Tyontekija EtuNimi = "Matti", SukuNimi = "Meikäläinen", Palkka = 1990, SyntymaAika = new DateTime(1972,3,13), PalkkausPvm = new DateTime(1997,7,1), new Tyontekija EtuNimi = "Jussi", SukuNimi = "Juurela", Palkka = 2500, SyntymaAika = new DateTime(1974,12,29), PalkkausPvm = new DateTime(1997,5,1), new Osasto Nimi = "Varasto", Tyontekijat = new List<Tyontekija> new Tyontekija EtuNimi = "Matti", SukuNimi = "Mattila", Palkka = 1800, SyntymaAika = new DateTime(1958,3,13), PalkkausPvm = new DateTime(1985,7,1), new Tyontekija EtuNimi = "Maija", SukuNimi = "Mattila", Palkka = 1850, SyntymaAika = new DateTime(1961,9,7), PalkkausPvm = new DateTime(1983,5,1), 17

; new Tyontekija EtuNimi = "Matti-Pekka", SukuNimi = "Mattila", Palkka = 1690, SyntymaAika = new DateTime(1981,3,13), PalkkausPvm = new DateTime(2005,9,1), new Tyontekija EtuNimi = "Kaija", SukuNimi = "Mattila", Palkka = 1500, SyntymaAika = new DateTime(1983,12,29), PalkkausPvm = new DateTime(2008,1,1), new Tyontekija EtuNimi = "Pentti", SukuNimi = "Pekkala", Palkka = 1850, SyntymaAika = new DateTime(1966,9,7), PalkkausPvm = new DateTime(1985,5,1), new Tyontekija EtuNimi = "Eija", SukuNimi = "Laakso-Pekkala", Palkka = 1690, SyntymaAika = new DateTime(1971,3,13), PalkkausPvm = new DateTime(2000,9,1), new Tyontekija EtuNimi = "Mikael", SukuNimi = "Pekkala", Palkka = 1100, SyntymaAika = new DateTime(1993,12,29), PalkkausPvm = new DateTime(2010,1,1) Lisää Form1 ikkunaan kontrollit: LinkLabel kontrolli, johon teksti Kaikki osastot. DataGridView kontrolli, jonka Anchor ominaisuus asetetaan seuraavasti: 18

Lisää sitten LinkLabel kontrollille tapahtuman Click käsittelijä ( toimi samalla idealla kuin Form_Loadkäsittelijän kanssa): aseta DataGridView kontrollin ominaisuuden DataSource arvoksi osastot kentän sisältämä lista Testaa. Linq kyselyt Lisää Form1 ikkunaan Label, johon tekstiksi Osasto TextBox LinkLabel kontrolli, johon teksti Hae osasto (LINQ). LinkLabel kontrolli, johon teksti Hae osasto (laajennusmetodein). Lisää sitten molemmille LinkLabel kontrolleille tapahtuman Click käsittelijä. Hae osasto (LINQ) linkin tapahtumakäsittelijässä: if (textbox1.text.length > 0) var q = (from o in osastot where o.nimi.toupper() == textbox1.text.toupper() 19

select o).tolist(); datagridview1.datasource = q; else MessageBox.Show("Osaston nimi puuttuu."); huomaa implisiittinen tietotyyppi var kyselylauseke from where select tuloksen muuttaminen listaksi ToList() metodilla o IEnumerable rajapinnan metodi voidaan kutsua kaikkien LINQ kyselyjen yhteydessä Hae osasto (laajennusmetodein) linkin tapahtumakäsittelijässä: if (textbox1.text.length > 0) var q = osastot.where(o => o.nimi.toupper() == textbox1.text.toupper()).tolist(); datagridview1.datasource = q; else MessageBox.Show("Osaston nimi puuttuu."); huomaa laajennusmetodin Where() käyttäminen huomaa metodin Where() argumentti: lambda lauseke (parametri on siis delegaattityyppinen: metodi, joka palauttaa totuusarvon) o kääntäjä osaa päätellä parametrin o tyypin o koska lauseita on vain yksi, se tulkitaan automaattisesti return lauseeksi o käy läpi oliokokoelman (tässä tapauksessa Osasto listan osastot) oliot ja suorittaa jokaiselle lambda lausekkeen, jos paluuarvo on tosi, lisää olion uudelle Osasto listalle valitsee siis oliot ehtolausekkeen perusteella. Lisää Form1 ikkunaan LinkLabel kontrolli, johon teksti Osaston työntekijät. LinkLabel kontrolli, johon teksti Kaikki työntekijät. 20

Lisää sitten molemmille LinkLabel kontrolleille tapahtuman Click käsittelijä. Osaston työntekijät linkin tapahtumakäsittelijässä: if (textbox1.text.length > 0) var q = (from o in osastot from t in o.tyontekijat where o.nimi.toupper() == textbox1.text.toupper() select t).tolist(); datagridview1.datasource = q; else MessageBox.Show("Osaston nimi puuttuu."); huomaa kaksi peräkkäistä from osaa ristiliitos Kaikki työntekijät linkin tapahtumakäsittelijässä: var q = (from o in osastot from t in o.tyontekijat orderby t.ika descending select new OsastoNimi = o.nimi, TyöntekijäNimi = t.etunimi + " " + t.sukunimi, Ikä = t.ika ).ToList(); datagridview1.datasource = q; huomaa olioiden järjestäminen eli orderby osa huomaa select osan anonyymin tyypin käyttö 21

Lisää taas Form1 ikkunaan LinkLabel kontrolli, johon teksti Osastokohtainen keski ikä. Tee tälle Click tapahtuman käsittelijä, jossa var q = (from o in osastot from t in o.tyontekijat group t by o.nimi into osastogroup select new Osasto = osastogroup.key, KeskiIka = osastogroup.average(t => t.ika) ).ToList(); datagridview1.datasource = q; huomaa ryhmittelyn käyttäminen eli group osa anonyymissä tyypissä keski iän laskemiseen käytetään laajennusmetodia Average, jossa lambdalauseke Lisää jälleen Form1 ikkunaan LinkLabel kontrolli, johon teksti Yli 30 vuotiaita työntekijöitä. Tee Click tapahtuman käsittelijässä, jossa var q = (from o in osastot select new Osasto = o.nimi, 22

Yli30v = o.tyontekijat.count(t => t.ika > 30) ).ToList(); datagridview1.datasource = q; 23