Programmeren met .NET IB-3020-02 6 Boekhouden Informatica/6 Informaticabeheer Ria Van Eysendeyk Nicole Legroe Werkgroep Handel 2005
Vlaams Verbond van het Katholiek Secundair Onderwijs
Guimardstraat 1, 1040 Brussel
Vlaams Verbond van het Katholiek Secundair Onderwijs Guimardstraat 1, 1040 Brussel
Programmeren met .NET IB-3020-02 6 Boekhouden Informatica/ 6 Informaticabeheer Ria Van Eysendeyk Nicole Legroe Werkgroep Handel -2005
http://handel.vvkso.net
D/2004/7841/047
Alle rechten voorbehouden. Behoudens de uitdrukkelijk bij wet bepaalde uitzonderingen mag niets uit deze uitgave worden verveelvoudigd, opgeslagen in een geautomatiseerd gegevensbestand of openbaar gemaakt, op welke wijze ook, zonder de uitdrukkelijke voorafgaande en schriftelijke toestemming van het VVKSO.
Inhoud 1 Visual Studio .NET................................................................................................................... 7 1.1 Software-ontwikkelomgeving.................................................................................................. 7 1.1.1 De ontwikkelomgeving......................................................................................................... 7 1.1.2 De ontwerpruimte................................................................................................................ 9 1.2 Configuratie............................................................................................................................ 9 1.3 Een toepassing maken......................................................................................................... 10 1.3.1 Besturingselementen......................................................................................................... 10 1.3.2 De toepassing compileren................................................................................................. 11 1.3.3 De toepassing testen......................................................................................................... 13 1.3.4 Bestanden......................................................................................................................... 14 1.3.5 De toepassing uitvoeren.................................................................................................... 14 1.4 Code 14 1.5 Soorten toepassingen........................................................................................................... 17 1.6 Oefeningen........................................................................................................................... 19 1.7 Overzicht.............................................................................................................................. 20 1.7.1 Startpagina (Start Page).................................................................................................... 20 1.7.2 Het ontwerpvenster............................................................................................................ 23 1.7.3 Werkbalken........................................................................................................................ 26 1.7.4 De helpfunctie.................................................................................................................... 26 1.8 Een toepassing testen.......................................................................................................... 28 1.9 Bestanden............................................................................................................................ 29 2 Een objectgeoriënteerde programmeeromgeving.............................................................. 30 2.1 Programmeerstijl.................................................................................................................. 30 2.2 Gegevenstypes..................................................................................................................... 32 2.2.1 Gegevenstypes in .NET..................................................................................................... 32 2.2.2 Sterke typering.................................................................................................................. 32 2.2.3 Voorbeeld 1: Rekenwonder............................................................................................... 32 2.2.4 Voorbeeld 2: Leeftijd.......................................................................................................... 36 2.2.5 Voorbeeld 3: Vermenigvuldiging........................................................................................ 40 2.3 Klasse/module...................................................................................................................... 41 2.3.1 Klasse 42 2.3.2 Modules............................................................................................................................. 42 2.4 Een object creëren en gebruiken.......................................................................................... 46 2.5 Structure............................................................................................................................... 48 2.6 Class Library......................................................................................................................... 50 2.6.1 Namespaces...................................................................................................................... 50 2.6.2 Object Browser.................................................................................................................. 51 2.7 Bereik, beschikbaarheid en levensduur................................................................................ 52 2.7.1 Declaratieruimten............................................................................................................... 52 2.7.2 Bereik 53 2.7.3 Beschikbaarheid................................................................................................................ 53 2.7.4 Variabelen declareren........................................................................................................ 54 2.7.5 Voorbeelden...................................................................................................................... 56 2.7.6 Levensduur........................................................................................................................ 68 2.8 Collecties.............................................................................................................................. 70 2.9 Niet zichtbare besturingselementen..................................................................................... 71 2.10 Tekenen.............................................................................................................................. 76 2.10.1 Het Graphics Object........................................................................................................ 76 2.10.2 Pens en Brushes............................................................................................................. 76 2.10.3 Voorbeeld........................................................................................................................ 77 2.11 Deployment........................................................................................................................ 80 2.11.1 Interpreter en compiler..................................................................................................... 80 2.11.2 Het .NET Framework....................................................................................................... 81 2.11.3 Ondersteuning verschillende programmeertalen............................................................. 82 2.11.4 XCopy Deployment.......................................................................................................... 82
2.12 Bespreking van de Windows Form Designer generated code............................................ 83 2.12.1 Klasse.............................................................................................................................. 83 2.12.2 Constructor...................................................................................................................... 83 2.12.3 Initialisatie........................................................................................................................ 84 2.12.4 Dispose............................................................................................................................ 85 2.13 Oefeningen......................................................................................................................... 85 2.14 Overzicht............................................................................................................................ 86 2.14.1 Namen van variabelen en constanten............................................................................. 86 2.14.2 Gegevenstypes................................................................................................................ 86 2.14.3 Naamgeving.................................................................................................................... 88 2.14.4 Conversiesleutelwoorden................................................................................................ 88 2.14.5 Bereik, beschikbaarheid van een entiteit......................................................................... 88 2.14.6 Levensduur van een variabele......................................................................................... 89 2.14.7 Beschikbaarheid van een variabele................................................................................. 89 2.14.8 De Object Browser........................................................................................................... 90 3 Gebruiksvriendelijkheid........................................................................................................ 93 3.1 De gebruiker staat centraal................................................................................................... 93 3.2 Exceptions............................................................................................................................ 93 3.3 Exception-objecten .............................................................................................................. 95 3.4 Gestructureerde en ongestructureerde foutafhandeling....................................................... 96 3.5 Meervoudige exception handling.......................................................................................... 96 3.6 Validation.............................................................................................................................. 98 3.6.1 Controle op leeg tekstvak.................................................................................................. 98 3.6.2 Controle op patroon......................................................................................................... 100 3.6.3 De visuele foutaanduiding verwijderen............................................................................ 101 3.6.4 Een fraaiere oplossing..................................................................................................... 102 3.7 Hulp voor de gebruiker....................................................................................................... 103 3.7.1 ToolTip............................................................................................................................. 103 3.8 Oefeningen......................................................................................................................... 104 3.9 Overzicht............................................................................................................................ 105 3.9.1 Exception handling.......................................................................................................... 105 3.9.2 Validation......................................................................................................................... 105 4 Object Oriented Programming........................................................................................... 106 4.1 Object Gericht Werken....................................................................................................... 106 4.2 Eenvoudig voorbeeld van OOP.......................................................................................... 108 4.3 Aanpasbaarheid................................................................................................................. 111 4.4 Eigenschappen................................................................................................................... 112 4.5 Verschillende soorten klassen............................................................................................ 113 4.5.1 Standard Class................................................................................................................ 113 4.5.2 Structure.......................................................................................................................... 114 4.5.3 Class Module................................................................................................................... 114 4.5.4 Enumeration.................................................................................................................... 115 4.5.5 Interface........................................................................................................................... 115 4.5.6 Delegate.......................................................................................................................... 115 4.6 OOP toepassen.................................................................................................................. 115 4.7 Array, ArrayList, Collection................................................................................................. 115 4.8 Uitgewerkte voorbeelden.................................................................................................... 119 4.8.1 Puzzel 120 4.8.2 Kasticket.......................................................................................................................... 131 4.9 User Control....................................................................................................................... 142 4.10 DataGrid, DataTable......................................................................................................... 148 4.11 Een Class Library maken.................................................................................................. 153 4.12 Een zelfgemaakte Class Library gebruiken...................................................................... 156 4.13 Oefeningen....................................................................................................................... 156 4.14 Overzicht.......................................................................................................................... 158 4.14.1 Een klasse definiëren.................................................................................................... 158 4.14.2 Eigenschappen.............................................................................................................. 158 4.14.3 Methoden....................................................................................................................... 158 5 Belangrijke kenmerken van OOP ...................................................................................... 159
5.1 Herbruikbaarheid................................................................................................................ 159 5.1.1 Overerving....................................................................................................................... 159 5.1.2 Polymorfisme................................................................................................................... 160 5.2 System.Object.................................................................................................................... 160 5.3 Overerving: uitgewerkt voorbeeld....................................................................................... 163 5.4 Polymorfisme: uitgewerkte voorbeelden............................................................................. 166 5.4.1 Overriding........................................................................................................................ 166 5.4.2 Overloading..................................................................................................................... 170 5.5 Oefeningen......................................................................................................................... 173 5.6 Overzicht............................................................................................................................ 174 5.6.1 Overerving....................................................................................................................... 174 5.6.2 Polymorfisme................................................................................................................... 174 ASP.NET
175
5.7 Een webserver.................................................................................................................... 175 5.8 De samenstelling van een ASP.NET Web project.............................................................. 179 5.9 Server controls................................................................................................................... 181 5.10 Validation controls............................................................................................................ 184 5.11 HttpResponse en HttpRequest......................................................................................... 185 5.12 Variabelen in asp.NET...................................................................................................... 185 5.13 Uitgewerkt voorbeeld........................................................................................................ 186 5.14 Werking van ASP.NET..................................................................................................... 190 5.15 Oefeningen....................................................................................................................... 191 5.16 Overzicht.......................................................................................................................... 192 5.16.1 Server controls.............................................................................................................. 192 5.16.2 Klasse Page.................................................................................................................. 192 5.16.3 Session object............................................................................................................... 192 6 Gegevensbeheer met ADO.NET......................................................................................... 193 6.1 Programmatorisch een databank benaderen...................................................................... 193 6.2 Een verbinding maken met een databank.......................................................................... 194 6.3 Connected/disconnected toegang...................................................................................... 196 6.4 Connected toegang............................................................................................................ 197 6.4.1 Wijzigingen aanbrengen.................................................................................................. 197 6.4.2 Eén gegeven uit de database halen................................................................................ 200 6.4.3 Meerdere gegevens gebruiken........................................................................................ 202 6.4.4 CommandType ............................................................................................................... 207 6.4.5 Exception handling.......................................................................................................... 207 6.4.6 Overzicht connected toegang.......................................................................................... 209 6.5 Disconnected toegang........................................................................................................ 209 6.5.1 DataSet en DataAdapter.................................................................................................. 209 6.5.2 DataSet met gegevens uit één tabel................................................................................ 210 6.5.3 Een DataTable met gegevens uit verschillende tabellen................................................. 217 6.5.4 Een DataSet met verschillende tabellen ......................................................................... 220 6.6 Oefeningen......................................................................................................................... 224 6.7 Overzicht............................................................................................................................ 225 6.7.1 Connected toegang......................................................................................................... 225 6.7.2 Disconnected toegang..................................................................................................... 226 6.7.3 Naamgeving.................................................................................................................... 227 Werken met een database..................................................................................................... 228 6.8 Databinding........................................................................................................................ 228 6.9 Navigeren in een database................................................................................................. 228 6.10 Gegevens selecteren........................................................................................................ 232 6.11 Gegevens aanpassen....................................................................................................... 240 6.11.1 Twee stappen................................................................................................................ 240 6.11.2 Toestanden van een rij.................................................................................................. 241 6.11.3 De methodes AcceptChanges/RejectChanges van een DataSet.................................. 242 6.11.4 De methode GetChanges van een DataSet.................................................................. 242 6.11.5 Toepassing.................................................................................................................... 242 6.11.6 Een bug......................................................................................................................... 246
6.12 De Data Form Wizard....................................................................................................... 246 6.12.1 Een formulier maken met de wizard.............................................................................. 246 6.12.2 Navigeren...................................................................................................................... 250 6.12.3 De tabel onderhouden................................................................................................... 250 6.13 Concurrency problemen................................................................................................... 254 6.14 Inherited forms.................................................................................................................. 256 6.14.1 Visual inheritance ......................................................................................................... 256 6.14.2 Een MDI applicatie......................................................................................................... 259 6.15 Een set-upprogramma maken.......................................................................................... 266 6.15.1 Setup Wizard ................................................................................................................ 267 6.15.2 Het installatiepakket instellen........................................................................................ 268 6.15.3 Build 272 6.15.4 Installeren en verwijderen.............................................................................................. 272 6.16 Oefeningen....................................................................................................................... 272 6.17 Overzicht.......................................................................................................................... 273 6.17.1 Belangrijke eigenschappen van System.Data............................................................... 273 6.17.2 Databinding................................................................................................................... 273 6.17.3 Gegevens selecteren..................................................................................................... 274 6.17.4 Gegevens aanpassen.................................................................................................... 274 7 Relaties en Views................................................................................................................ 276 7.1 XML 276 7.2 XML schema....................................................................................................................... 277 7.3 Relaties in een dataset....................................................................................................... 278 7.3.1 De relatie leggen in XML designer................................................................................... 279 7.3.2 Programmatorisch een relatie toevoegen........................................................................ 281 7.3.3 Voorbeeld ....................................................................................................................... 282 7.3.4 Opmerking....................................................................................................................... 285 7.3.5 Typing gebruiken ......................................................................................................... 286 7.4 DataViews.......................................................................................................................... 287 7.4.1 Een DataView creëren..................................................................................................... 287 7.4.2 Zoeken en sorteren met een DataView........................................................................... 288 7.4.3 Uitgewerkt voorbeeld....................................................................................................... 288 7.4.4 RowStateFilter................................................................................................................. 293 7.5 Berekende kolommen......................................................................................................... 293 7.5.1 Een berekende kolom toevoegen in de XML Designer.................................................... 293 7.5.2 Programmatorisch een berekende kolom toevoegen...................................................... 295 7.5.3 Uitgewerkt voorbeeld....................................................................................................... 295 7.6 Oefeningen......................................................................................................................... 303 7.7 Overzicht............................................................................................................................ 304 7.7.1 Relaties............................................................................................................................ 304 7.7.2 DataRow.......................................................................................................................... 304 7.7.3 DataView......................................................................................................................... 304 7.7.4 Gegevens selecteren in DataSet..................................................................................... 305 8 Rapportering........................................................................................................................ 307 8.1 Een rapport creëren............................................................................................................ 307 8.2 Rapport informatie.............................................................................................................. 310 8.3 Designer............................................................................................................................. 310 8.3.1 Printer Setup.................................................................................................................... 310 8.3.2 Page Setup...................................................................................................................... 311 8.3.3 Default Settings............................................................................................................... 311 8.4 Velden toevoegen............................................................................................................... 312 8.5 Het rapport gebruiken......................................................................................................... 312 8.5.1 Crystal Reports Viewer.................................................................................................... 312 8.5.2 Het startformulier............................................................................................................. 313 8.6 Report expert...................................................................................................................... 313 9 ASP.NET en databases....................................................................................................... 319 9.1 Een gastenboek.................................................................................................................. 319 9.1.1 De toegang verzekeren................................................................................................... 319
9.1.2 StreamWriter/StreamReader........................................................................................... 320 9.1.3 Een DataGrid gebruiken.................................................................................................. 324 9.2 Gebruik van databases in Webtoepassingen..................................................................... 326 9.3 Een gastenboek met een database.................................................................................... 327 9.3.1 Voorbeeld........................................................................................................................ 327 9.3.2 Property Builder............................................................................................................... 330 9.4 Microsoft SQL Server......................................................................................................... 333 9.5 Een kleine website bouwen................................................................................................ 333 9.5.1 Doorverwijzen naar een andere pagina........................................................................... 334 9.5.2 Variabelen in een website................................................................................................ 338 9.5.3 Gegevenstype van een session-variabele....................................................................... 343 9.6 Gebruik van Cascading Style Sheets................................................................................. 349 9.7 Een DataAdapter maken met code..................................................................................... 351 9.8 Beeldbestanden weergeven: Template Column................................................................. 357 9.9 Paginering instellen............................................................................................................ 359 9.10 Een DataGrid opmaken.................................................................................................... 360 9.11 Gegevens in een datagrid aanpassen.............................................................................. 362 9.12 Concurrency..................................................................................................................... 367 9.13 Gegevens toevoegen met een SQLCommand-object ..................................................... 367 9.14 Eén gegeven ophalen met een SqlCommand-object........................................................ 369 9.15 Oefeningen....................................................................................................................... 373 9.16 Overzicht.......................................................................................................................... 374 9.16.1 StreamReader/StreamWriter......................................................................................... 374 9.16.2 DataTable...................................................................................................................... 374 9.16.3 DataGrid Property Builder.............................................................................................. 374 9.16.4 Klasse Page.................................................................................................................. 376 9.16.5 Variabelen..................................................................................................................... 377 Bijlagen
378
1 MSDE
379
1.1 MSDE 2000 versie A installeren......................................................................................... 379 1.2 De geïnstalleerde MSDE op de server............................................................................... 382 2 Naming conventions in .NET.............................................................................................. 384
1
Visual Studio .NET • • • •
1.1
IDE van Visual Studio.NET Een VB.NET project creëren testen en bewaren Windows Application Console Application
Software-ontwikkelomgeving
Een software-ontwikkelomgeving is computersoftware die een software-ontwikkelaar ondersteunt bij het ontwikkelen van computersoftware. De belangrijkste componenten zijn in het algemeen: •
een teksteditor met speciale contextgevoelige hulp;
•
een compiler;
•
een debugger;
•
online documentatie van de programmeertaal.
In een moderne software-ontwikkelomgeving zijn al deze onderdelen geïntegreerd; er is dan sprake van een IDE (Integrated Development Environment). IDE's maken gebruik van een grafische gebruikersinterface (GUI) en ondersteunen de programmeur bij het ontwikkelen van programma's met een grafische gebruikersinterface, bijvoorbeeld in de vorm van een speciaal ontwerpprogramma voor formulieren of webpagina's. Zoals een tekstverwerker het schrijven van documenten ondersteunt, ondersteunt een IDE het ontwikkelen van programma's. De Visual Basic editor waarvan je gebruik maakte om VBA-toepssingen te ontwikkelen is zo'n IDE. In deze cursus zul je kennismaken met de gesofistikeerde IDE voor .NET. Visual Studio .NET 2003 is een ontwikkelomgeving waarmee snel en efficiënt Microsoft .NET toepassingen onder andere voor Microsoft Windows en het web kunnen worden ontwikkeld.
1.1.1
De ontwikkelomgeving Start
Via het tabblad Projects krijg je toegang tot de eigenlijke programmeeromgeving. Een project is een toepassing. Neem het tabblad Projects en klik op de knop New Project.
Voor je kunt beginnen te programmeren kies je eerst het type project dat je wilt maken. De geboden mogelijkheden hangen af van de geïnstalleerde producten.
VVKSO
Werkgroep handel
Programmeren met .NET 7
Kies Visual Basic Projects. Voor dit type zijn verschillende sjablonen (Templates) beschikbaar voor de verschillende typen van projecten die met behulp van de IDE kunnen ontwikkeld worden. Kies Windows Application. Een Windows Application is een toepassing voor het Windows OS. Ze bestaat meestal uit één of meerdere formulieren (forms) waaraan code verbonden is.
Kies een naam voor het project, bijvoorbeeld Welkom en een locatie om de bestanden van het project te bewaren. Klik op OK. De bestanden van het project worden in een map geplaatst die de naam van het project krijgt. Als je op OK klikt wordt deze map gecreëerd op de gespecifieerde locatie. De grafische ontwikkelomgeving wordt opgestart.
VVKSO
Werkgroep Handel
Programmeren met .NET 8
Opmerking
Om een bestaand project te openen, activeer je Start Page. Hier vind je een lijstje met de recentste projecten. Als je er één van wilt openen, dan klik je gewoon op de naam. Bevindt het project zich niet in het lijstje dan klik je op de knop Open Project en je bladert naar de gewenste map. Daar vind je een bestand van het type .vbproj en een bestand van het type .sln (solution). Selecteer één van beide om het project te openen.
1.1.2
De ontwerpruimte
De ontwerpruimte bestaat uit verschillende deelvensters o.a. Toolbox (links), Solution Explorer en Properties (rechts) en een formulier (midden). Elk venster heeft een eigen titelbalk met de naam van het venster. De IDE lijkt op de vertrouwde IDE van VBA, maar heeft meer mogelijkheden. De belangrijkste zul je leren kennen. Raadpleeg het overzicht achteraan dit hoofdstuk voor meer informatie over de verschillende vensters.
1.2
Configuratie
Via de menuoptie Tools, Options… kun je de IDE configuren.
VVKSO
Werkgroep handel
Programmeren met .NET 9
Exploreer de mogelijkheden om de omgeving (Environment) naar je hand te zetten. Wijzig niet te veel in één keer zodat je steeds naar de standaardinstellingen kunt terugkeren.
1.3
Een toepassing maken
Om kennis te maken met de nieuwe ontwikkelomgeving, maak je een zeer eenvoudige toepassing: een formulier met een welkomstboodschap.
1.3.1
Besturingselementen
De Toolbox bevat de besturingselementen die je kunt toevoegen aan een formulier om onder andere de grafische gebruikersinterface te maken van de toepassing. Als je de Toolbox niet op het scherm ziet, kun je hem oproepen via het View-menu of door op de knop
te klikken.
Plaats een label op het formulier. Je kunt een besturingselement snel op een formulier plaatsen door het te selecteren in Toolbox en te dubbelklikken.
VVKSO
Werkgroep Handel
Programmeren met .NET 10
Pas de volgende eigenschappen (venster Properties) aan: Object
Eigenschap
Waarde
frmWelkom
name
frmWelkom
text
Eerste voorbeeld
name
lblWelkom
text
WELKOM
font
naar keuze
forecolor
naar keuze
textalign
middlecenter
lblWelkom
1.3.2
De toepassing compileren
Om een toepassing uit te voeren, moet ze eerst gecompileerd worden (zie 2.11). De gecompileerde code van een toepassing wordt build genoemd. Je kunt een build maken via de optie van menuoptie Build. Bij het maken van een build wordt de broncode gecontroleerd op fouten. Maak een build voor het project Welkom (Build, Build Welkom). De code bevat blijkbaar fouten. Fouten worden gemeld in het venster Task List.
De fout is te wijten aan het hernoemen van het formulier: Form1 heb je gewijzigd in frmWelkom. Visual Studio .NET gaat er van uit dat je de toepassing wilt starten met Form1. Door te dubbelklikken op de foutmelding in Task List wordt ofwel de fout verbeterd, ofwel word je naar de plaats van de fout in de editor gebracht. Dubbelklik op de foutmelding. Het volgende venster verschijnt.
VVKSO
Werkgroep handel
Programmeren met .NET 11
Selecteer Welkom.frmWelkom en klik op OK. Hierdoor wordt het formulier frmWelkom het startobject van de toepassing. Het startobject is een eigenschap van de Solution (oplossing). Je kunt die eigenschap zelf de gepaste waarde geven. Roep in het venster Solution Explorer het snelmenu van Welkom op en kies Properties.
In het eigenschappenvenster kun je Startup object instellen.
VVKSO
Werkgroep Handel
Programmeren met .NET 12
Opmerking
Een Windows Application project start standaard met een formulier Form1. Andere projecten zoals Console projecten (zie 1.5) starten met een functie die Main() genoemd is. Voeg een nieuw formulier frmNieuwFormulier toe aan het project via optie Add … van het snelmenu van het project in Solution Explorer. Maak van dit formulier het Startup object en test het programma opnieuw. Je krijgt nu geen foutmelding.
1.3.3
De toepassing testen
Voor het testen van de toepassing, gebruik je de opties van menuoptie Debug. Selecteer Debug, Start. Er wordt eerst automatisch een build aangemaakt. Daarna wordt de toepassing uitgevoerd.
De IDE bevindt zich nu in run-modus. Je kunt de ontwerpvensters nog bekijken, maar geen wijzigingen aanbrengen. Onderaan worden vensters getoond die nuttig zijn voor de foutopsporing. De werkbalk Debug is ook zichtbaar.
Stop de toepassing door het venster Eerste voorbeeld te sluiten of door op de knop Stop Debugging van de werkbalk Debug te klikken. VVKSO
Werkgroep handel
Programmeren met .NET 13
1.3.4
Bestanden
De gegevens van een project worden opgeslagen in verschillende bestanden. standaardwerkbalk (Standard) bevat twee knoppen om die gegevens op te slaan.
De
Met de eerste knop sla je het actieve bestand op, bijvoorbeeld het formulier. Met de tweede knop (Save all) sla je alle gegevens op. Sla alle gegevens op en bekijk de mappen en bestanden die zijn aangemaakt voor het project (gebruik Verkenner).
In het overzicht op het einde van dit hoofdstuk, vind je meer informatie over deze bestanden. Hoewel je het formulier frmWelkom hebt genoemd (eigenschap Name), worden de gegevens ervan bewaard onder de naam Form1.vb, de naam die gebruikt wordt in het venster Solution Explorer. Solution Explorer bevat bestandsnamen. Je kunt een bestandsnaam wijzigen in het venster Properties van het bestand (selecteer de bestandsnaam in Solution Explorer) of zoals je dat zou doen in Verkenner. Wijzig in Solution Explorer de naam Form1.vb in frmWelkom.vb. Sla de gegevens opnieuw op en bekijk het resultaat. Behoud steeds de extensies (in dit geval vb) van de bestanden! Zelfs het eenmalig bewaren met een foutieve extensie kan tot problemen leiden. Stel de standaardmap voor het bewaren van de projecten in via menuoptie Tools, Options, Environment, Projects en Solutions.
1.3.5
De toepassing uitvoeren
Als je een build maakt, wordt aan de submap bin van het project een .exe bestand toegevoegd. Dit is een uitvoerbaar bestand. Het kan uitgevoerd worden op elke pc die voorzien is van het .NET Framework (zie 2.11.2).
1.4
Code
Zoals VBA is VB.NET een gebeurtenisprocedures schrijven.
VVKSO
Werkgroep Handel
gebeurtenisgestuurde
programmeertaal.
Je
zult
vaak
Programmeren met .NET 14
Als voorbeeld maak je een kleine toepassing die bij een druk op een knop de huidige dag van de week weergeeft.
Start een nieuw project DagVanDeWeek (Windows Application). Een nieuw project start je vanuit de Start page of vanuit een menuoptie van de ontwikkelomgeving. Kies menuoptie File, New, Project.
Als er nog een project actief is waarin niet bewaarde veranderingen staan, dan krijg je eerst nog de mogelijkheid om dit te bewaren. Noem het formulier van het nieuwe project en het bijhorend bestand frmDagVanDeWeek. Pas de eigenschappen van het project aan zodat dit formulier het Startup object is. Plaats een label, lblDag, en een knop, btnOK, op het formulier. Je kunt code beginnen schrijven, zoals je dat deed in de VBA-omgeving. Je dubbelklikt op een besturingselement of je selecteert een besturingselement en je kiest in het snelmenu View, Code. In beide gevallen kom je in de codepagina terecht die de code bevat achter het gebruikte formulier. Dubbelklik op de knop btnOK om het codevenster te openen. Het codevenster bevat reeds automatisch gegenereerde code. Deze wordt later besproken. Begin en einde van de gebeurtenisprocedure staan ook klaar. Private Sub btnOK_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnOK.Click End Sub De gebeurtenisprocedure btnOK_Click heeft automatisch twee argumenten gekregen: sender en e. Sender vertegenwoordigt het object dat de gebeurtenis genereert, in dit geval de knop btnOK, e kan in bepaalde gevallen gebruikt worden voor gebeurtenissen met argumenten (zie 3.6). In de declaratie van de gebeurtenisprocedure wordt expliciet vermeld op welke gebeurtenis gereageerd wordt: Handles btnOK.Click. Eenzelfde procedure kan verschillende gebeurtenissen behandelen. VVKSO
Werkgroep handel
Programmeren met .NET 15
Vermeld elke gebeurtenis met het sleutelwoord Handles.
Voeg onderstaande code toe aan de gebeurtenisprocedure. Private Sub btnOK_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnOK.Click Dim strDay, strDag As String strDay = Today.DayOfWeek.ToString Select Case strDay Case "Sunday" strDag = "Zondag" Case "Monday" strDag = "Maandag" Case "Thuesday" strDag = "Dindag" Case "Wednesday" strDag = "Woensdag" Case "Thursday" strDag = "Donderdag" Case "Friday" strDag = "Vrijdag" Case "Saturday" strDag = "Zaterdag" End Select lblDag.Text = strDag End Sub
Verklaring
Today.DayOfWeek.ToString In VB.NET is de objectoriëntatie verder doorgedreven dan in VBA. Zo zijn alle gegevenstypes klassen met eigen methodes en eigenschappen. Today bevat de huidige datum en is van het type Date. De eigenschap DayOfWeek bevat de huidige dag en is van het type DayOfWeek. Alle types kunnen omgezet worden tot het type string via de eigenschap ToString.
Opmerkingen
•
Je kunt tussen formulier en code schakelen via de tabs bovenaan het ontwerpvenster of de knoppen bovenaan Solution Explorer.
•
In Visual Basic.NET wordt er geen onderscheid gemaakt tussen de eigenschappen: er is geen standaardeigenschap. Dit heeft tot gevolg dat, als je een eigenschap wilt gebruiken, je ze ook expliciet moet vermelden.
•
Syntaxisfouten worden onderlijnd. Als je de muisaanwijzer op het onderlijnde deel plaatst, krijg je uitleg over de fout. Deze uitleg is niet altijd even goed te begrijpen (het zal makkelijker worden naarmate je meer van VB.NET kent), maar het is toch de moeite waard om even te gaan kijken als je zelf de fout niet onmiddellijk herkent.
•
In het Codevenster herken je bovenaan twee keuzelijsten: links de (Class Name) elementen van het formulier en rechts (Method Name) de corresponderende methoden en gebeurtenissen.
VVKSO
Werkgroep Handel
Programmeren met .NET 16
Om de codering van een andere gebeurtenisprocedure te starten, kies je links het betrokken element en rechts de gebeurtenis. Test de werking van het programma.
Dialoogvensters
Je kunt de uitvoer in een apart dialoogvenster plaatsen. Hiervoor gebruik je de methode Show van de klasse MessageBox. Voorbeeld: MessageBox.Show("Resultaat") De ronde haakjes zijn verplicht. Pas het programma aan zodat de uitvoer (dag van de week) in een apart dialoogvenster komt. Volg de aanwijzigingen van Intellisense om in de titelbalk "Dag van de week" te zetten en het dialoogvenster te voorzien van een OK-knop.
Kleuren
Het voorgedefinieerde object Color bezit heel wat eigenschappen waarvan de waarden kleuren vertegenwoordigen. Voorbeelden: color.red, color.green Pas het programma aan zodat de knop OK rood wordt als je er met de muisaanwijzer overgaat (gebeurtenis MouseHover) en groen als je de muisaanwijzer er van wegneemt (MouseLeave).
1.5
Soorten toepassingen
De voorbeelden in vorige paragrafen waren van het type Windows Application. Hierin maak je gebruik van Windows formulieren. In hoofdstuk 6 maak je kennis met ASP.NET Web Applications. Console Applications zijn toepassingen die uitgevoerd kunnen worden aan de Opdrachtprompt. De interactie met de gebruiker is meestal beperkt.
Voorbeeld
Opgave
Maak een programma dat de tafels van vermenigvuldiging (van 1 tot 10) toont aan de opdrachtprompt. Maak een nieuwe Console Application Tafel.
VVKSO
Werkgroep handel
Programmeren met .NET 17
Het ontwerpvenster is een code-editor waarin reeds een module Module1 gedeclareerd is en een subprocedure Main(). Bij de start van het programma zal deze procedure automatisch uitgevoerd worden. Voeg de volgende code toe. Module Module1 Sub Main() Dim intBasisgetal As Integer For intBasisgetal = 0 To 10 Dim i As Integer For i = 1 To 10 Console.Write(intBasisgetal & " X " & i & " = " & _ intBasisgetal * i & vbCrLf) Next Next Console.Read() End Sub End Module De methode Write van Console brengt een tekstboodschap aan de opdrachtprompt. De methode Read van Console leest een tekst ingevoerd aan de opdrachtprompt. Deze instructie werd enkel toegevoegd om het programma te laten pauzeren (wachten op invoer) zodat je tijd hebt om de boodschap (uitvoer) aan de opdrachtprompt te lezen. Test het programma.
VVKSO
Werkgroep Handel
Programmeren met .NET 18
1.6
Oefeningen
Zorg er bij het maken van volgende oefeningen voor dat het venster Dynamic Help geopend is (standaard kun je via tabs schakelen tussen Properties en Dynamic Help). Gebruik indien nodig de hulpinformatie om volgende oefeningen te maken. Je hoeft de namen van de objecten niet aan te passen tenzij expliciet gevraagd. 1
Start een nieuw project Oef1Hoofdstuk1 (Windows Application). Plaats hierop een label en een tekstvak.
De grootte van het label moet zich automatisch aanpassen aan de inhoud. Pas hiervoor de juiste eigenschap aan. Controleer de werking door het opschrift van het label te wijzigen.
Pas deze eigenschap ook aan voor het tekstvak. Is de werking van de eigenschap hetzelfde? Waar is deze eigenschap bruikbaar?
Plaats zes keuzerondjes op het formulier (2 rijen, 3 kolommen). Zorg voor een mooie schikking. Gebruik hiervoor de knoppen van de werkbalk Layout. Pas de naam van het formulier aan: frmOef1Hoofdstuk1 (op twee
plaatsen!).
Test het programma.
Bewaar het programma.
2
Maak een mini-teksteditor Oef2Hoofdstuk1. Noem het formulier frmMiniTekstverwerker. Plaats hiervoor een tekstvak op het formulier en maak het zo groot als het formulier zelf. Geef de eigenschap Multiline de waarde True en de eigenschap ScrollBars de waarde Both. Druk bij het testen op de rechter muisknop. Je ziet dat knippen-en-plakken mogelijk is.
3
Maak een project Oef3Hoofdstuk1. Maak een formulier frmKleuren met een keuzelijst van kleuren en een knop. Als er op de knop geklikt wordt, verandert de achtergrondkleur van het formulier in de in de keuzelijst geselecteerde kleur. Tip: gebruik ActiveForm of Me om naar het formulier te verwijzen in de code.
VVKSO
Werkgroep handel
Programmeren met .NET 19
1.7
Overzicht
1.7.1
Startpagina (Start Page)
My Profile
Voorkeursinstellingen.
Online Resources
•
Via de optie Get Started kun je op zoek gaan naar voorbeelden en tips.
•
De rubriek What’s New bevat verwijzingen naar allerlei nieuwtjes, zoals verwijzingen naar de website van Microsoft om een Service Pack of belangrijke wijzigingen te downloaden, of verwijzingen naar uitleg en tips of nieuwe releases, boeken of geplande vernieuwingen.
•
Op dit tabblad vind je bij de rubrieken Online Community, Headlines, Search Online en Downloads voorbeelden, programmacode, nieuwsgroepen, tips en trucs, best practices … en catalogi van componenten voor Visual Studio. Je kunt ook artikelen doorzoeken over allerlei onderwerpen. Op dit alles kun je ook steeds een filter aanbrengen via het uitschuifvak bovenaan de pagina.
•
Met de XML Web Services kun je Web Services op het Internet zoeken om op te nemen in jouw toepassing, of een eigen webservice registreren zodat anderen er gebruik van kunnen maken.
•
Via Web Hosting kun je een provider zoeken om een website te laten hosten.
VVKSO
Werkgroep Handel
Programmeren met .NET 20
Online Resources
Visual Studio biedt via het tabblad Online Resources een rechtstreeks contact met het internet.
Projects
Toegang tot nieuwe en bestaande projecten. De volgende Visual Basic projecten zijn beschikbaar.
•
Windows Application. Dit project bevat bij de startfase één formulier. Dit is het meest gebruikte project geschikt voor een stand-alone toepassing. Het leidt tot een ‘gewoon’ Windowsprogramma met een gebruikersinterface die wordt getekend met behulp van de mogelijkheden uit de Toolbox. Een dergelijk formulier kan ook als front-end van een Internettoepassing of bijvoorbeeld een databasetoepassing gebruikt worden.
•
Class Library. Alhoewel een formulier ook een klasse is en als zodanig gebruikt wordt, is er een afzonderlijke mogelijkheid om een klasse te definiëren. Dit projecttype moet gebruikt worden om een klasse te maken waarop objecten gebaseerd worden die geen interface hebben. Een klasse die postcodes controleert, begint dus op deze manier.
•
Windows Control Library. Een besturingselement of control is een onderdeel dat bijvoorbeeld op een formulier kan gebruikt worden zoals een knop, een schuifbalk, een lijst, een aanmeldscherm … Met dit type project kun je zelf een nieuw besturingselement maken om dat vervolgens in een ander project te gebruiken. Meerdere besturingselementen kun je ook samen bundelen in een bibliotheek (Library).
•
Smart Device Application. Met dit sjabloon kun je een toepassing ontwikkelen voor een smart device zoals een pocket pc, een pda (personal digital assistant) en een draagbare telefoon. Je ontwikkelt dan een toepassing voor gebruik op een apparaat dat het .NET Compact Framework bevat, wat een deel is van het .NET Framework.
•
ASP.NET Web Application. Dit zijn pagina’s die in een browser bekeken kunnen worden en waarin logica (programmacode) opgenomen is die bepaalde functies op de webserver uitvoeren, bijvoorbeeld het opnemen van op afstand ingevoerde gegevens in een databank.
VVKSO
Werkgroep handel
Programmeren met .NET 21
•
ASP.NET Web Service. Een webservice is een functie die je via Internet kan laten uitvoeren. De gebruiker krijgt een interface te zien, maar alles wordt uitgevoerd op een webserver. Om dit te kunnen maken en gebruiken moet je een webserver IIS 5 of 6 op de computer geïnstalleerd hebben en moet je voldoende rechten en toegang hebben tot de webserver.
•
ASP.NET Mobile Web Application. Dit is een webtoepassing voor het .NET Compact Framework dat bruikbaar is op alle apparaten die dit type framework ondersteunen en gebruik kunnen maken van de protocollen van het Internet.
•
Web Control Library. Te vergelijken met een Windows Control Library, maar dan specifiek toegespitst op het gebruik in een webtoepassing.
•
Console application. Hiermee kun je een programma maken dat achter een MS-DOS-prompt dient uitgevoerd te worden en dus geen grafische interface heeft. Het programma wordt enkel als .exe-bestand gecompileerd.
•
Windows Service. Een service is een Windowsprogramma dat ontworpen is om langere tijd op de achtergrond een bepaalde taak uit te voeren voor een besturingssysteem. Dit is een service zoals je er een aantal terugvindt in Windows 2000/XP.
•
Empty Project. Er wordt wel een mappenstructuur op schijf gemaakt, maar je dient vervolgens zelf alle onderdelen toe te voegen via het menu Project. Dat is precies de bedoeling van de andere klaargezette projecten. Er wordt een mappenstructuur gemaakt en er worden een aantal standaardonderdelen klaar gezet om te gebruiken.
•
Empty Web Project. Dit is een leeg project, maar nu specifiek voor een webtoepassing. De mappenstructuur kan direct op een webserver worden gemaakt, het pad kan opgegeven worden. Ook opslag op je eigen computer of de local host is mogelijk.
•
New Project in Existing Folder. Elk Visual Basic-project wordt automatisch in een eigen map op schijf geplaatst. Door dit type project te kiezen, kun je uit een bestaande map onderdelen gebruiken voor een nieuw project dat aan dezelfde map wordt toegevoegd.
•
Set-up and deployment Projects. Hiermee kun je een installatieprogramma samenstellen waar later allerlei bestanden aan kunnen worden toegevoegd. - Set-up
Project maakt een toepassing waarmee Windows Installer dan de gemaakte toepassing op een willekeurige andere computer kan installeren. De gebruiker krijgt er nog een uninstall-optie bij om het programma later te kunnen verwijderen.
- Set-up
Wizard. Het gebruik van deze wizard maakt het samenstellen van een installatieprogramma eenvoudiger, maar leidt uiteindelijk tot hetzelfde resultaat.
- Web
Set-up Project. Dit levert een installatieprogramma om een webapplicatie te laten installeren.
- Merge
Module Project. Dit is een project waarin een component kan gebruikt worden die ontwikkeld werd in Visual Basic 6.0 en/of voor de vorige versie van het .NET Framework. Met dit type project kun je ook een Visual Basic 6.0 toepassing maken die gebruik maakt van .NET componenten of bij een bestaande toepassing een nieuwe versie van een component gebruiken.
- CAB
Project. Dit soort project wordt gebruikt om cabinetbestanden (extensie .cab) te maken om componenten te laten downloaden met een browser. Deze optie dient gebruikt te worden als je code wenst uit te voeren om een clientcomputer en niet op een server.
VVKSO
Werkgroep Handel
Programmeren met .NET 22
•
•
Other Projects. -
Database Project. Hiermee zet je een databasegeoriënteerd project klaar, waarbij je direct al van bij het begin moet opgeven welke database zal gebruikt worden. Je kunt koppelingen maken naar meerdere databankformaten zoals MS Access, Oracle en SQL-server.
-
Extensibility Projects. Hiermee kun je een add-in maken waarmee Visual Studio of Microsoft Office kan uitgebreid worden.
Visual Studio Solutions, Blank Solution. Hiermee kun je een ingewikkeld geheel, bestaande uit meerdere projecten opzetten.
1.7.2
Het ontwerpvenster
De meeste vensters die links of rechts in het venster van Visual Studio voorkomen zijn aangemeerd (docked), maar je kunt deze ook vrij laten ‘zweven’. Wissel tussen aangemeerd en zwevend door te dubbelklikken op de titelbalk van het venster. Veel vensters hebben een Auto hide functie
.
Het venster blijft steeds geopend, wat er ook in de andere vensters gebeurt. Het venster klapt dicht van zodra in een ander venster geklikt wordt. Als je met de muisaanwijzer over het dichtgeklapte venster gaat, klapt het automatisch terug open.
Toolbox
De Toolbox bevat meerdere categorieën besturingselementen: Data, Components, Windows Forms, Clipboard Ring en General. In Windows Forms herken je de besturingselementen die ook beschikbaar zijn in de Toolbox van de VBA-IDE. Gebruik het pijltje onderaan om de overige besturingselementen te bekijken. Selecteer naar de muisaanwijzer.
VVKSO
Werkgroep handel
als je geen besturingselement wilt selecteren. Pointer verwijst
Programmeren met .NET 23
Designer
Het eigenlijke ontwerpvenster bevat meestal meerdere tabbladen. •
Designer (bijvoorbeeld Form1.vb[Design]) In Visual Studio is een formulier een venster dat gebruikt wordt binnen de toepassing. Voor elk formulier binnen de toepassing voorziet Visual Studio een Form Designer in Design Time die het formulier bevat en alle besturingselementen die je op het formulier plaatst.
•
Code (bijvoorbeeld Form1.vb) is een afzonderlijk venster met daarin alle code behorend bij elk formulier of module opgenomen in het project. Je kunt dit venster openen door o.a. te dubbelklikken op het formulier. Het Code venster bevat twee keuzelijsten bovenaan het venster: -
Objectlijst (links)
-
Memberslijst (rechts)
VVKSO
Werkgroep Handel
Programmeren met .NET 24
De objectlijst bevat een lijst van alle besturingselementen die voorkomen op het formulier. De memberslijst bevat alle members (eigenschappen, methoden en gebeurtenissen) behorend bij het besturingselement geselecteerd in de objectlijst. Aan een member die vetjes weergegeven wordt, is code verbonden. Door deze twee keuzelijsten samen te gebruiken kun je vlug de gewenste code lokaliseren en bewerken.
Solution Explorer
Het Solution Explorer venster toont de lijst van alle delen die de volledige toepassing (=solution) uitmaken. De knoppen die bovenaan links staan, dienen om te wisselen tussen het Designer en het Code venster.
Soms zijn er meerdere vensters op dezelfde plaats beschikbaar. Deze zijn dan beschikbaar via tabbladen die automatisch aangemaakt worden als twee vensters op dezelfde plaats terecht komen.
Properties
Een eigenschap van een object beschrijft een karakteristiek hiervan zoals grootte, tekst, kleur. Het Properties venster geeft een lijst van alle eigenschappen van het gekozen object die in Design Time (ontwerpfase) kunnen gewijzigd worden. Je kunt de categorieën alfabetisch of volgens categorie geordend bekijken. Je kunt wisselen tussen beide weergaven door op de voorziene tabbladen te klikken. Als je op de categorie of eigenschap klikt, krijg je eronder een korte beschrijving van wat deze betekent.
VVKSO
Werkgroep handel
Programmeren met .NET 25
De eigenschappen van een object die voorkomen in een eigenschappenvenster zijn meestal niet de enige eigenschappen die dat object heeft. In de meeste gevallen zijn er ook eigenschappen die enkel in run time (als het programma uitgevoerd wordt) kunnen aangepast worden.
1.7.3
Werkbalken
In Visual Studio .NET zijn heel wat werkbalken beschikbaar. De voornaamste is de Standard Toolbar. Deze contextgevoelige werkbalk bevat knoppen voor de meest voorkomende bewerkingen.
1.7.4
De helpfunctie
Microsoft Visual Studio is enkel beschikbaar in het Engels. Dit betekent dat de hulpinformatie ook Engelstalig is. De helpfunctie is zeer uitgebreid. Lees de informatie die je bekomt via menuoptie Help, Help on Help om uit te vinden hoe je ze het best gebruikt. Je kunt de Helpfunctie bijvoorbeeld aanspreken via menuoptie Help, Contents…
VVKSO
Werkgroep Handel
Programmeren met .NET 26
Je kunt ook laten zoeken op bepaalde trefwoorden, de bekomen resultaten sorteren en/of filteren, een lijst van favorieten opstellen of de hulpfunctie via de index raadplegen.
In sommige gevallen wordt er contact gemaakt via het Internet met de locatie waar bepaalde hulp ter beschikking is. Dit is onder andere het geval voor sommige onderdelen van de MSDN-Library. In heel wat Help-vensters vind je het See also-symbool een lijst aanverwante onderwerpen.
terug. Als je op dit symbool klikt, vind je
Je kunt ook contextgevoelige hulp vragen over een besturingselement, een functie of een eigenschap door de Dynamic Help te gebruiken.
VVKSO
Werkgroep handel
Programmeren met .NET 27
Dit venster komt standaard onderaan rechts, als tabblad achter het eigenschappenvenster. Staat dit er niet, dan kun je het steeds oproepen door de menuoptie Help, Dynamic Help. De inhoud van dit Help-venster is contextgevoelig. In het begin kan de hoeveelheid informatie die je krijgt verwarrend zijn. Als je verder gevorderd bent in VB.NET zal het gemakkelijker worden om de juiste technische informatie te bekomen.
1.8
Een toepassing testen
Je kunt de toepassing uitvoeren door op de F5-toets te drukken of op de onderstaande toets uit de werkbalk. Je kunt ook in het Debug-menu de optie Start kiezen.
Stoppen van de toepassing gebeurt door op de onderstaande toets in de werkbalk te klikken of de optie Stop Debugging te kiezen in het Debug-menu. Door het bekijken van de opties uit het Debugmenu, wordt het ineens duidelijk wat de andere knoppen betekenen.
Op het moment dat je de optie Start kiest, wordt het programma gecompileerd. Er wordt een build gemaakt. •
Als er een fout gemaakt werd, dan verschijnt een venster met daarin een verwijzing en een vraag om al dan niet verder te gaan met de toepassing.
Het is aan te raden om bij bovenstaande foutmelding op Nee te klikken en te zoeken naar de fout.
Kies je om niet verder te gaan, dan komt in het Taskvenster een lijst met de fout(en) gecombineerd met een todo-lijst om deze op te lossen.
In sommige gevallen, kun je bij het dubbelklikken op de fout deze reeds herstellen. De geboden oplossing wordt bepaald door de aard van de fout en het feit of Visual Studio deze kan oplossen of niet. •
Als er geen fouten zijn, dan wordt dit onderaan in beeld in het venster Output getoond en zal het formulier verschijnen. In de titelbalk van Visual Basic verschijnt het woord run om aan te tonen dat de toepassing zich in uitvoeringsfase bevindt.
VVKSO
Werkgroep Handel
Programmeren met .NET 28
Je stopt de uitvoering bijvoorbeeld met het aanklikken van de juiste knop. Normaal verschijnt nu onderaan het venster Output.
Dit geeft informatie hoe de compilatie van het project verlopen is, of er fouten waren of niet, en hoe het programma beëindigd is.
1.9
Bestanden
Een Windows Application project bevat onder meer volgende bestanden. Elk van deze bestanden heeft een eigen pictogram. •
een projectbestand (*.vbproj)
Dit tekstbestand in XML-formaat (leesbaar met Kladblok) bevat de lijst van alle bestanden en componenten die verbonden zijn aan het project. •
een Form Module (frm*.vb)
Deze bevat informatie over het formulier en zijn besturingselementen en de waarden van de eigenschappen. Bovendien kunnen hierin ook declaraties vervat zitten die op het niveau van het formulier gemaakt werden. Dit kunnen declaraties zijn van constanten, variabelen, externe procedures, eigenschappenprocedures en general procedures. Hierin vind je ook steeds de zelfgemaakte code terug. •
een XML bronbestand per formulier (frm*.resx)
Visual Studio .NET maakt per formulier één bestand (in XML) dat alle referenties bevat die met dit formulier te maken hebben. Voor een volledige lijst en meer informatie kun je terecht bij de Help van Visual Basic onder de rubriek: Project File Formats.
VVKSO
Werkgroep handel
Programmeren met .NET 29
2
Een objectgeoriënteerde programmeeromgeving • • • • • •
2.1
Programmeerstijl Gegevenstypes in .NET Conversie van gegevenstypes De Class Library Variabelen: declaratie, bereik, beschikbaarheid Het uitvoerbaar bestand
Programmeerstijl
Om de leesbaarheid en dus onderhoudbaarheid van je toepassingen te verhogen moet je een zekere programmeerstijl in acht nemen, onafhankelijk van de programmeertaal die je gebuikt. Een programmeerstijl of “huisstijl” binnen een bepaalde groep of instelling, is een verzameling van regels, strikter dan de syntaxis van de programmeertaal zelf, die bepalen hoe een programma moet worden geschreven. Een programmeertaal als VB.NET laat immers nog veel vrijheid toe, die bij het werken in teamverband of tijdens het onderhoud van de software voor verwarring kan zorgen. Natuurlijk zijn niet alle regels even strikt. Het is wel belangrijk dat alle regels consistent gebruikt worden, enerzijds in de hele applicatie, en anderzijds door de verschillende programmeurs van het ontwikkelingsteam. Dat leidt tot kwaliteit en betrouwbaarheid van het ontwikkelde product en verhoogt de snelheid tijdens het ontwikkelingsproces en onderhoud. Volgende regels zijn een must.
Documenteer je code, d.w.z. voorzie voldoende commentaar
De commentaar in de source code moet het programma blijvend verstaanbaar maken, zowel voor diegene die het codeerde als voor anderen. Voldoende commentaar is onmisbaar. Een “tricky” of niet voor de hand liggend programmaonderdeel wordt zeker van commentaar voorzien. Er komt commentaar (beginnen met ' ) bij de belangrijkste deelalgoritmen in een functie. vb. ' testen op geldige invoer. Overdrijf ook niet met commentaar. Het is beter om zinvolle namen te gebruiken dan het schrijven van overbodige commentaar. Het volgende is zeker overbodig: i = i + 1
'i wordt met 1 verhoogd
Commentaar schrijven, gebeurt dadelijk bij het intikken van het programma. Je kunt het te gebruiken algoritme ook vooraf vastleggen in commentaarregels. Vergeet niet het commentaar aan te passen bij programmawijzigingen. Commentaar staat steeds boven of achter de code waar hij op slaat, nooit eronder.
Gebruik steeds een duidelijke, betekenisvolle naamgeving
Het ligt voor de hand dat er betekenisvolle namen gegeven worden aan alle gegevens in het programma: in een project steeds dezelfde benaming gebruiken voor eenzelfde begrip; ieder nieuw woord in de naam moet met een hoofdletter beginnen;
VVKSO
Werkgroep Handel
Programmeren met .NET 30
onderlijningstekens worden niet in de naamgeving gebruikt; in deze cursus wordt de Hongaarse naamgeving gebruikt. Sommige tags zijn anders dan diegene die je gebruikte in VBA. Je vindt een overzicht in de bijlagen.
Declareer alle variabelen en gebruik steeds geschikte gegevenstypes
Net zoals in de VBA-omgeving, kun je het declareren van variabelen verplichten via Option Explicit. Maar er is meer. Selecteer Tools, Options. Bij Projects, VB Defaults vind je belangrijke instellingen:
•
Option Explicit On bepaalt dat alle variabelen die gebruikt worden expliciet moeten gedeclareerd worden. Indien er in de declaratie geen gegevenstype wordt toegekend, krijgt de gedeclareerde variabele het algemene type Object.
•
Option Strict On dwingt vroeg-binden af en voorkomt impliciete conversie op die plaatsen waar gegevens verloren zouden kunnen gaan. Vroeg-binden (early binding) betekent dat in de declaratie een AS statement moet gebruikt worden, m.a.w. dat je expliciet een gegevenstype toekent. Dit heeft tot gevolg dat je er altijd zelf voor moet zorgen dat de variabele die je in een instructie gebruikt, van het juiste type is en dat je eventueel een gegevenstypeconversie moet doen om het juiste type te bekomen. Impliciete conversie tussen strings en numerieke types is nooit toegelaten met Option Strict on. Wat wel kan is bijvoorbeeld een 'integer' toekennen aan een 'long', maar niet omgekeerd. In het omgekeerde geval zouden er immers gegevens kunnen verloren gaan.
•
Option Compare bepaalt de manier waarop twee 'strings' vergeleken worden met elkaar. Deze optie heeft twee mogelijkheden: binary (hoofdlettergevoelig) en text (niet hoofdlettergevoelig). Kies zowel voor Option Explicit als voor Option Strict: on. Deze opties zijn actief bij elk volgend nieuw project.
VVKSO
Werkgroep handel
Programmeren met .NET 31
Een variabele moet natuurlijk gedeclareerd worden vóór hij gebruikt wordt. Declareer de belangrijkste variabelen steeds bovenaan de procedure. Hulpvariabelen zoals een teller voor een For Next loop mag je net boven de loop declareren.
2.2
Gegevenstypes
2.2.1
Gegevenstypes in .NET
In .NET worden gegevenstypes ingedeeld in: - value types - reference types. Beide types worden door .NET anders behandeld o.a. wat geheugentoekenning en initialisatie betreffen. Alle numerieke en binaire types zoals Integer, Char en Boolean zijn value types. Strings, arrays en alle klassen zijn reference types. Het gebruik van variabelen en constanten in VBA en in VB.NET is ongeveer hetzelfde. Je vindt een overzicht van de mogelijke gegevenstypes in 2.14.2.
Opmerkingen De types Long en Integer bestrijken in VB.NET een groter interval en nemen meer geheugenruimte in beslag. Er is een nieuw type bijgekomen namelijk Short. Dit type vervangt het type Integer uit VBA.
2.2.2
Sterke typering
Sterke typering (strong typing) betekent dat je aan iedere variabele die je gebruikt een gegevenstype toekent. Werken met sterke typering biedt heel wat voordelen •
Sterk getypeerde variabelen laten IntelliSense toe om eigenschappen en methodes te tonen terwijl je in de editor werkt.
•
De compiler kan de gegevenstypes controleren en zo potentiële runtime fouten voorkomen.
•
De code wordt sneller uitgevoerd omdat de CPU niet moet proberen uit te vissen over welk gegevenstype het gaat en dan eventueel nog in de achtergrond bijkomende code moet uitvoeren voor gegevenstypeconversie.
2.2.3
Voorbeeld 1: Rekenwonder
Project
Rekenwonder
Type
Windows Application
Doel
- Conversie van gegevenstypes
Extra
- Groepsvak (GroupBox) met keuzerondjes (radiobuttons) - Select Case True structuur
Moeilijkheid
*
Vorm
Volledig uitgewerkt
VVKSO
Werkgroep Handel
Programmeren met .NET 32
Probleemstelling Ontwikkel een mini rekenmachine: in een formulier kunnen twee willekeurige getallen ingevoerd worden en kan een bewerking gekozen worden ( optelling, verschil, vermenigvuldiging, deling). Het resultaat van de bewerking op de ingevoerde getallen wordt getoond. Probleemanalyse en implementatie Klasse: frmRekenwonder Invoer, uitvoer en bewerkingen via een instantie van klasse frmRekenwonder.
frmRekenwonder: eigenschappen Eigenschap
waarde
Text
Rekenwonder
frmRekenwonder: besturingselementen
Voorzie twee tekstvakken voor de invoer van willekeurige getallen, optierondjes in een groepsvak voor de bewerking, een knop voor de resultaatberekening en een label voor het resultaat.
VVKSO
Werkgroep handel
Programmeren met .NET 33
Gebruik de opties van menuoptie Format van de menubalk om een mooie schikking van de besturingselementen te bekomen. Gebruik de knoppen van de werkbalk Layout voor de opmaak van het formulier.
Er is een verschil tussen het gebruik van RadioButtons en CheckBoxes in een GroupBox. Met RadioButtons kun je slechts één keuze maken, bij CheckBoxes heb je de mogelijkheid om meerdere keuzes te maken. Besturingselement
Eigenschap
Waarde
lblGetal1
Text
Getal 1
txtGetal1
Text
leeg
lblGetal2
Text
Getal 2
txtGetal2
Text
leeg
grpBewerking
Text
Bewerking
rdbQuotient
Text
Quotiënt
rdbVerschil
Text
Verschil
rdbProduct
Text
Product
rdbSom
Text
Som
Checked
True
btnBereken
Text
Bereken
lblResultaat
Text
leeg
Autosize
True
Wat is de betekenis van deze eigenschap Autosize? Pas in Solution Explorer de naam van het formulier aan. frmRekenwonder: procedures btnBereken_Click (Handles btnBereken.Click) Besturingselement
Gebeurtenis
Doel
btnBereken
Click
- Resultaat berekenen - Resultaat tonen
VVKSO
Werkgroep Handel
Programmeren met .NET 34
Algoritme btnBereken_Click Lees getal1, getal2 en bewerking Bewerking rdbSom
rdbVerschil
rdbProduct
rdbQuotiënt
resultaat=getal1+getal2 resultaat=getal1-getal2 resultaat=getal1*getal2 resultaat=getal1/getal2 Toon resultaat Implementatie De foutafhandeling voeg je later toe. Private Sub btnBereken_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBereken.Click Dim dblGetal1, dblGetal2, dblResultaat As Double Dim strBewerking As String dblGetal1 = Double.Parse(txtGetal1.Text) dblGetal2 = Double.Parse(txtGetal2.Text) Select Case True Case rdbSom.Checked dblResultaat = dblGetal1 + dblGetal2 strBewerking = "Som: " Case rdbVerschil.Checked dblResultaat = dblGetal1 - dblGetal2 strBewerking = "Verschil: " Case rdbProduct.Checked dblResultaat = dblGetal1 * dblGetal2 strBewerking = "Product: " Case rdbQuotient.Checked dblResultaat = dblGetal1 / dblGetal2 strBewerking = "Quotiënt: " End Select lblResultaat.Text = strBewerking & dblResultaat.ToString("#,##0.####") End Sub
Verklaring
Vermits Option Explicit op On staat is declaratie van de variabelen verplicht. Je mag meerdere variabelen van hetzelfde type declareren in dezelfde statement. •
dblGetal1 = Double.Parse(txtGetal1.Text)
Expliciete conversie is verplicht omdat Option Strict op On staat. Met de methode Parse van het gegevenstype Double wordt een String omgezet in een Double. Je mag de statement vervangen door: dblGetal1 = CDbl(txtGetal1.Text)
VVKSO
Werkgroep handel
Programmeren met .NET 35
Het resultaat is hetzelfde. Double.Parse is beschikbare in alle .NET programmeertalen terwijl CDbl een sleutelwoord van Visual basic is. •
dblResultaat.ToString("#,##0.####")
Met de methode ToString wordt het getal van type Double omgezet naar type String. Als argument van de eigenschap mag je een formaat opgeven. (Voor meer uitleg: zie de volgende paragraaf.) Je mag de expressie vervangen door: FormatNumber(dblResultaat, 4) Het resultaat is hetzelfde. Test de werking van je programma. Testen Wat gebeurt er als je deelt door 0? Wat gebeurt er als je 0 deelt door 0? Uitbreiding VB.NET kent nog drie andere rekenkundige operatoren dan deze gebruikt in het project Rekenwonder: •
^ : machtsverheffing,
•
MOD: rest bij deling,
•
\: gehele deel van quotiënt. Breid het project uit zodat ook deze bewerkingen mogelijk worden. Tip: de bewerking \ (geheel deel van quotiënt) is enkel bruikbaar voor gehele getallen. Maak de nodige conversies.
2.2.4
Voorbeeld 2: Leeftijd
Elk gegevenstype is een klasse. Een variabele van een bepaald gegevenstype is een instantie van de bijbehorende klasse en kan dus gebruik maken van de methodes en eigenschappen van die klasse. Voorbeeld dteVandaag = DateTime.Today intJaar = dteVandaag.Year De eigenschap Today van de klasse DateTime bevat de huidige datum. De eigenschap Year bevat het jaartal (type Integer) van het DateTime-object. Als Option Strict op On staat, sta je zelf in voor de conversies naar het gepaste gegevenstype. In Windows Applications moet je vaak omzettingen doen van numerieke gegevens naar strings en omgekeerd.
VVKSO
Werkgroep Handel
Programmeren met .NET 36
Alle numerieke gegevenstypes (Single, Double, Integer, …) hebben een methode ToString voor de conversie naar het gegevenstype String. Als argument kun je eventueel een formaat meegeven. Voorbeeld strResultaat= dblResultaat.ToString("#,##0.#####") Omgekeerd: om een string naar het gewenste numerieke gegevenstype om te zetten, gebruik je de methode Parse van dat gegevenstype. Voorbeeld dblGetal1 = Double.Parse(txtGetal1.Text) Om een gegeven van een willekeurig type om te zetten naar een bepaald type, kun je ook de conversiesleutelwoorden gebruiken. Voor meer informatie hierover zie overzicht 2.14.4.
Voorbeeld Project
Leeftijd
Type
Windows Application
Doel
Gebruik en conversie van gegevenstypes
Extra
Werken met datums
Moeilijkheid
*
Vorm
Volledig uitgewerkt
Probleemstelling Bereken de leeftijd aan de hand van een ingevoerde geboortedatum. Probleemanalyse Project: Leeftijd Type: Windows Application Klasse(n): frmVerjaardag Het probleem kan opgelost worden door gebruik te maken van een eenvoudig formulier.
VVKSO
Werkgroep handel
Programmeren met .NET 37
frmVerjaardag frmVerjaardag: eigenschappen Eigenschap
Waarde
Text
Verjaardag
frmVerjaardag: besturingselementen
Besturingselement
Eigenschap
Waarde
txtGeboortedatum
Text
leeg
btnLeeftijd
Text
Leeftijd?
lblLeeftijd
Text
Vul je geboortedatum in en druk op een knop.
frmVerjaardag: procedures Object
Gebeurtenis
Doel
btnLeeftijd
Click
- leeftijd bereken - leeftijd tonen
Het berekenen van de leeftijd zal in een aparte functie (Leeftijd) verwerkt worden. Algoritmen btnLeeftijd_Click (Handles btnLeeftijd.Click) btnLeeftijd_Click Bereken leeftijd
(Leeftijd)
Toon leeftijd op scherm
VVKSO
Werkgroep Handel
Programmeren met .NET 38
Leeftijd(Geboortedatum) Leeftijd(Geboortedatum) Leeftijd Jaar(Huidige datum) – Jaar(Geboortedatum) Maand(Huidige datum) < Maand(Geboortedatum) of (Maand(Huidige datum) = Maand (Geboortedatum) en Dag(Huidige datum) < Dag(Geboortedatum)) Ja
Nee
Leeftijd Leeftijd -1 Implementatie Private Sub btnLeeftijd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLeeftijd.Click Dim intLeeftijd As Integer Dim dteGeboortedatum As DateTime dteGeboortedatum = DateTime.Parse(txtGeboortedatum.Text) intLeeftijd = Leeftijd(dteGeboortedatum) lblLeeftijd.Text = "Je bent " & intLeeftijd.ToString & " jaar!" End Sub Private Function leeftijd(ByVal pdteGeboorteDatum As DateTime) As Integer Dim intGeboortejaar, intGeboortemaand, intGeboortedag As Integer Dim intJaar, intMaand, intDag As Integer Dim intAantaljaar As Integer intGeboortejaar = pdteGeboorteDatum.Year intGeboortemaand = pdteGeboorteDatum.Month intGeboortedag = pdteGeboorteDatum.Day intJaar = Today.Year intMaand = Today.Month intDag = Today.Day intAantaljaar = intJaar - intGeboortejaar If intMaand < intGeboortemaand Or _ (intMaand = intGeboortemaand And intDag < intGeboortedag) Then intAantaljaar -= 1 End If Return intAantaljaar End Function Verklaring In de code wordt gebruik gemaakt van een functie om de leeftijd te berekenen. Wat is het verschil tussen een functie en een procedure? In VB.NET wordt de waarde in een functie doorgegeven via het sleutelwoord Return. VVKSO
Werkgroep handel
Programmeren met .NET 39
Uitbreiding Pas het project aan zodat ook het aantal dagen tot de volgende verjaardag weergegeven wordt en de dag waarop deze valt (maandag, dinsdag, …)
2.2.5
Voorbeeld 3: Vermenigvuldiging
Project
Vermenigvuldiging
Type
Windows Application
Doel
Conversie van gegevenstypes
Extra
Vernestelde if-statement
Moeilijkheid
**
Vorm
Oplossing
Probleemstelling Het project Vermenigvuldig genereert de uitkomsten van de tafels van vermenigvuldiging tot en met 10 op een formulier, zoals hieronder.
Probleemanalyse en implementatie Er wordt een formulier aangemaakt met een groot label (lblTonen). Het lettertype voor het label is een niet propertioneel type, bvb. Courrier New, zodat de gegevens mooi onder elkaar komen. Implementatie Private Sub frmVermenigvuldig_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim intLijn As Integer Dim intKolom As Integer Dim strProduct As String Dim strUitkomst As String For intLijn = 1 To 10 'per lijn For intKolom = 1 To 10 'per kolom strProduct = (intLijn * intKolom).ToString("000") strUitkomst &= " " & strProduct Next intKolom strUitkomst &= vbCrLf Next intLijn VVKSO
Werkgroep Handel
Programmeren met .NET 40
lblTonen.Text = strUitkomst End Sub Verklaring •
De operatoren &=, += en -= zijn verkorte schrijfwijzen:
strWoord &= “nogeenwoord” → strWoord = strWoord & “nogeenwoord” intAantal += 1 → intAantal = intAantal +1 (de inhoud van de variabele wordt met 1 verhoogd) intAantal -= 2 → intAantal = intAantal – 2 (de inhoud van de variabele wordt met 2 verlaagd) •
strProduct = (intLijn * intKolom).ToString("000")
Om de getallen mooi uit te lijnen worden voorloopnullen getoond. De klasse Strings van de namespace Visual Basic bevat een reeks nuttige methodes die kunnen toegepast worden op gegevens van het type string. Als je de vetjes gedrukte regels in de code vervangt door: strProduct = Strings.Right(Space(3) & (intLijn * intKolom).ToString, 3) strUitkomst &= Strings.Space(2) & strProduct dan krijg je het volgende resultaat.
Wat is de betekenis van de methodes Space en Right? Bekijk met Object browser de methodes van de klasse Strings. Welke methode kun je gebruiken om na te gaan of bepaalde karakters in een string voorkomen? Uitbreiding Pas het programma aan zodat de volledige vermenigvuldiging getoond wordt. (Tip: let op het lettertype)
2.3
Klasse/module
In Visual Basic moeten alle functies en procedures ingekapseld zitten in een klasse of module. Een klasse kan vele eigenschappen, methodes en events hebben. Een klasse kan verschillende instanties hebben in een toepassing. Een module bevat enkel functies en procedures (methodes) en kan niet geïnstantieerd worden. VVKSO
Werkgroep handel
Programmeren met .NET 41
2.3.1
Klasse Bekijk de code van het project Rekenwonder.
In het codevenster kun je code dichtklappen of openklappen door op de Dit is erg handig om een overzicht te krijgen van de gegenereerde code.
of
knopjes te klikken.
Visual Basic.NET volgt de principes van objectgeörienteerd programmeren. Net als in VBA is het nieuwe formulier een klasse. Dit wordt hier duidelijk aangegeven door: Public Class frmRekenwonder … End Class In VBA heeft een nieuw formulier alle members (eigenschappen, methoden en gebeurtenissen) van de voorgedefinieerde klasse Form plus de methoden (procedures en functies) die je zelf bijmaakt. In .NET is dit ook zo. Het erven van de members van de klasse Form, de parent-klasse, wordt zelfs expliciet aangeduid door: Inherits System.Windows.Forms.Form De klasse frmRekenwonder heeft dezelfde eigenschappen en methoden en herkent dezelfde gebeurtenissen als de voorgedefinieerde klasse Form. Ze bezit bovendien één extra methode namelijk btnBereken_Click. In een project kunnen uiteraard meerdere klassen gedefinieerd worden. Dit kunnen andere formulieren zijn of klassen van een andere soort.
2.3.2
Modules
Modules zijn verzamelingen van methodes en constanten. Ze kunnen geen instanties (objecten) genereren zoals klassen. Ze worden gebruikt om bij elkaar horende methodes te groeperen, die bijvoorbeeld in diverse andere modules of klassen gebruikt worden. Voorbeeld Project
Module
Type
Windows Application
Doel
Illustratie van het gebruik van een module
Extra
- oproepen van een formulier vanuit een ander formulier - eigenschappen van klasse String: ToUpper, ToLower, SubString - eigenschap van klasse Strings: Split - gebruik van een array
Moeilijkheid
*
Vorm
Oplossing
VVKSO
Werkgroep Handel
Programmeren met .NET 42
Probleemstelling Een woord of een tekst moet omgezet worden in kleine letters, hoofdletters of beginhoofdletter. Er moet een formulier zijn voor de woordomzettingen en een ander formulier voor de tekstomzettingen. De formulieren worden opgeroepen met een startformulier. Probleemanalyse en implementatie
Klassen: frmStart, frmOmzettingWoord, frmOmzettingTekst, mdlOmzettingen frmStart Implementatie Public Class frmStart Inherits System.Windows.Forms.Form Windows Form Designer generated code Private Sub btnWoord_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWoord.Click Dim frmWoord As New frmOmzettingWoord frmWoord.Show() End Sub Private Sub btnTekst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTekst.Click Dim frmTekst As New frmOmzettingTekst frmTekst.Show() End Sub End Class Verklaring Als je een formulier aanmaakt, creëer je een klasse. Als je het wilt gebruiken in een procedure, dan moet je een instantie van die klasse instantiëren. Dus, om vanuit frmStart een ander formulier te openen, moet hiervan een instantie gecreëerd worden, net zoals bij om het even welke ander klasse. Deze instantie wordt gecreëerd met het sleutelwoord New. Via de methode Show wordt het formulier getoond op het scherm (zie volgende paragraaf).
VVKSO
Werkgroep handel
Programmeren met .NET 43
Als de toepassing slechts uit één formulier bestaat, maakt de compiler zelf een instantie van die klasse in een procedure Main (de startprocedure) die ook aangemaakt wordt door de compiler. mdlOmzettingen Implementatie Module Omzettingen Public Function Hoofdletters(ByVal pstrTekst As String) As String Return pstrTekst.ToUpper.Trim End Function Public Function Kleineletters(ByVal pstrTekst As String) As String Return pstrTekst.ToLower.Trim End Function Public Function BeginHoofdletter(ByVal strTekst As String) As String Return pstrTekst.Trim.Substring(0, 1).ToUpper & _ pstrTekst.Trim.Substring(1).ToLower End Function End Module Verklaring •
In alle functies wordt de methode Trim gebruikt om voorlopende en achterlopende spaties te verwijderen. Is er een verschil tussen pstrTekst.ToUpper.Trim en pstrTekst.Trim.ToUpper? Is er een verschil tussen pstrTekst.Trim.Substring(0, 1).ToUpper pstrTekst.Substring(0, 1).ToUpper.Trim? Verklaar je antwoord.
•
en
Voor alle functies is de 'modifier' Public gebruikt . De modifier bepaalt het bereik van de functie. Zie paragraaf Error: Reference source not found.
frmOmzettingWoord Implementatie Public Class frmOmzettingWoord Inherits System.Windows.Forms.Form Windows Form Designer generated code Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click Select Case True Case rdb.Checked lblResultaat.Text = Kleineletters(txtInvoer.Text) Case rdbHoofd.Checked lblResultaat.Text = Hoofdletters(txtInvoer.Text) Case rdbBeginHoofd.Checked lblResultaat.Text = BeginHoofdletter(txtInvoer.Text) End Select End Sub End Class
VVKSO
Werkgroep Handel
Programmeren met .NET 44
frmOmzettingTekst Implementatie Public Class frmOmzettingTekst Inherits System.Windows.Forms.Form Windows Form Designer generated code Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click Dim strWoorden() As String Dim intTeller As Integer lblResultaat.Text = String.Empty strWoorden = Strings.Split(txtInvoer.Text, Space(1)) Select Case True Case rdbKlein.Checked For intTeller = 0 To strWoorden.Length - 1 lblResultaat.Text &= Kleineletters(strWoorden(intTeller)) & Space(1) Next Case rdbHoofd.Checked For intTeller = 0 To strWoorden.Length - 1 lblResultaat.Text &= Hoofdletters(strWoorden(intTeller)) & Space(1) Next Case rdbBeginHoofd.Checked For intTeller = 0 To strWoorden.Length - 1 lblResultaat.Text&=BeginHoofdletter(strWoorden(intTeller)) & Space(1) Next End Select End Sub End Class Verklaring •
Dim strWoorden() As String
strWoorden wordt gedeclareerd als een (onbegrensde) array waarvan ieder element van het type String is. •
String.Empty
De eigenschap Empty van String stelt een lege string voor. Gebruik hiervan is duidelijker dan “” gebruiken. •
strWoorden = Strings.Split(txtInvoer.Text, Space(1))
Met de eigenschap Split wordt de opgegeven String opgesplitst, ieder deeltje komt in een element van de array strWoorden. De splitsing gebeurt op basis van 1 spatie. Test deze procedure met een tekst van een aantal woorden waartussen verschillende spaties staan. De spaties blijven behouden omdat de functie Split splits op elke spatie, er wordt m.a.w. als er twee spaties naast elkaar staan een leeg woord in de array strWoorden ingevoegd. Pas de code als volgt aan en test opnieuw. Select Case True Case rdbKlein.Checked For intTeller = 0 To strWoorden.Length - 1 If strWoorden(intTeller) <> String.Empty Then VVKSO
Werkgroep handel
Programmeren met .NET 45
lblResultaat.Text &= Kleineletters(strWoorden(intTeller)) & Space(1) End If Next Case rdbHoofd.Checked For intTeller = 0 To strWoorden.Length - 1 If strWoorden(intTeller) <> String.Empty Then lblResultaat.Text &= Hoofdletters(strWoorden(intTeller)) & Space(1) End If Next Case rdbBeginHoofd.Checked For intTeller = 0 To strWoorden.Length - 1 If strWoorden(intTeller) <> String.Empty Then lblResultaat.Text&=BeginHoofdletter(strWoorden(intTeller))& Space(1) End If Next End Select
2.4
Een object creëren en gebruiken
Een procedure werkt met instanties van een klasse, objecten genoemd. Je creëert een object meestal via de constructor New. In sommige gevallen wordt het object gecreëerd door een eigenschap of methode van een ander object. Om de geheugenruimte die het object inneemt terug vrij te geven gebruik je de destructor Dispose. .NET maakt gebruik van garbage collection voor het opruimen van geheugen. Dat is software die speurt naar objecten die niet meer gebruikt worden en ze vernietigt (ingenomen geheugenruimte weer vrij geeft). In principe hoef je je daar zelf niets van aan te trekken als programmeur. Toch is het goed programmeergebruik om objecten die je niet meer nodig hebt zo snel mogelijk op te ruimen (‘dispose’), zeker als je werkt met resources waar je zuinig mee om moet gaan zoals een databaseconnectie of GDI-objecten. Door het gebruik van de destructor weet de garbage collector dat het object ook echt verwijderd mag worden. Voorbeeld Project
GetalRaden
Type
Windows Application
Doel
Gebruik van de constructor New
Extra
Willekeurige getallen genereren (klasse Random)
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling Telkens er geklikt wordt op de knop Spelen worden drie vakjes ingevuld met willekeurige getallen tussen 0 en 9. Als het getal 7 één of meerdere keren voorkomt, wordt de figuur met het geld getoond, in het andere geval niet. Je kunt telkens opnieuw op de knop drukken, tot je besluit om te stoppen.
VVKSO
Werkgroep Handel
Programmeren met .NET 46
Probleemanalyse en implementatie Klasse: frmGetalKiezen frmGetalKiezen: procedures Implementatie Private Sub btnSpelen_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSpelen.Click Dim objCijfer As New Random picGeld.Visible = False lblEen.Text = objCijfer.Next(0, 10).ToString lblTwee.Text = objCijfer.Next(0, 10).ToString lblDrie.Text = objCijfer.Next(0, 10).ToString
End Sub
'Als een van de getallen 7 is, toon de geldstukken en maak geluid If (lblEen.Text = "7") Or (lblTwee.Text = "7") _ Or (lblDrie.Text = "7") Then picGeld.Visible = True End If
Private Sub btnStoppen_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnStoppen.Click Me.Close() End Sub Van welk type is het besturingselement waarop de afbeelding verschijnt? Verklaring •
Dim objCijfer As New Random
De klasse Random wordt gebruikt om willekeurige getallen te genereren. Door in de declaratie van de objectvariabele de constructor New op te nemen, wordt meteen een object van het type Random gecreëerd en de variabele wordt hiermee geïnitialiseerd. Dit statement is gelijkwaardig met: Dim objCijfer As Random objCijfer = New Random De methode Next geeft een getal (Integer) dat tussen het opgegeven minimum (inbegrepen) en maximum (niet inbegrepen) ligt.
VVKSO
Werkgroep handel
Programmeren met .NET 47
Uitbreiding Pas het project aan zodat ook het gewonnen bedrag getoond wordt: 5 EURO voor één 7, 50 EURO voor twee 7’s en 500 EURO voor drie 7’s. Pas het project aan zodat je een bedrag kunt inzetten om te spelen. Per beurt betaal je 1 EURO. Het resterende bedrag wordt getoond. Eventuele winsten worden bij de inzet gevoegd.
2.5
Structure
Een structure is een samengesteld gegevenstype dat bestaat uit een aantal elementen (zie Error: Reference source not found). .NET beschikt over heel wat voorgedefinieerde structures. Hun gebruik wordt geïllustreerd in het onderstaande voorbeeld.
Voorbeeld
Project
Programmeren
Type
Windows Application
Doel
Gebruik van een Structure
Extra
Gebeurtenis MouseEnter
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling Een gebruiker kan ogenschijnlijk stemmen of programmeren plezant of saai is. Door het verplaatsen van de knop om 'saai' te stemmen, wordt deze optie verhinderd. Probleemanalyse Klasse: frmStemmen Het probleem wordt opgelost via een eenvoudig formulier.
VVKSO
Werkgroep Handel
Programmeren met .NET 48
frmStemmen frmStemmen: eigenschappen Eigenschap
waarde
Text
Stemmen
MaximizeBox
False
MinimizeBox
False
WindowState
Maximized
frmStemmen: besturingselementen
Besturingselement
Eigenschap
Waarde
btnPlezant
Text
Plezant
btnSaai
Text
Saai
frmStemmen: procedures VVKSO
Werkgroep handel
Programmeren met .NET 49
Object
Gebeurtenis
Doel
btnPlezant
Click
Boodschap op scherm brengen
btnSaai
MouseEnter
Knop verplaatsen
Implementatie Private Sub btnPlezant_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnPlezant.Click MessageBox.Show("Dat vindt iedereen!") End Sub Private Sub btnSaai_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaai.MouseEnter Dim intPositie As New Random Dim pntLocatie As Point pntLocatie.X = intPositie.Next(0, Me.Width - btnSaai.Width) 'Knop mag niet verdwijnen onder Taakbalk, vandaar -100 pntLocatie.Y = intPositie.Next(0, Me.Height - btnSaai.Height - 100) btnSaai.Location = pntLocatie End Sub Verklaring •
Dim pntLocatie As Point
De structure Point bestaat uit twee Integers, X en Y, die samen een coördinaat vormen. •
btnSaai.Location = pntLocatie
De eigenschap Location van een control bevat de coördinaat van de linker bovenhoek van de control. Uitbreiding Pas de code aan zo dat de knop btnSaai naar haar oorspronkelijke positie terugkeert als de gebruiker op de knop btnPlezant klikt.
2.6
Class Library
2.6.1
Namespaces
Het .NET Framework bevat een massa voorgedefinieerde klassen. Hiervan heb je er al verschillende gebruikt in de voorbeelden. Klassen die bij elkaar horen, worden gegroepeerd in zogenaamde namespaces. Door een referentie naar een namespace op te nemen in je toepassing, kun je gebruik maken van die klassen. Open een willekeurig project. Open in het venster Solution Explorer de map References.
VVKSO
Werkgroep Handel
Programmeren met .NET 50
Als je bij het aanmaken van een project kiest voor Windows Application, dan neemt VB.NET automatisch een reeks referenties op naar namespaces waarin klassen gegroepeerd zijn die vaak in Windows toepassingen gebruikt worden. In de map References wordt in feite niet rechtstreeks verwezen naar een namespace, maar naar de assembly, gewoonlijk een .dll bestand, waarin de namespace zich bevindt. Een assembly is een eenheid van data, of simpelweg: een assembly is een .NET dll of exe file. De data in de assembly kan bestaan uit verschillende klassen (ook figuren, geluiden ...) die gebruikt worden in een programma. Elk programma gecompileerd in .NET bestaat dan ook uit minimaal 1 assembly (1 exe of dll file) Een assembly beschrijft zichzelf d.m.v. metadata die in het programmabestand zitten. Deze metadata bevatten: •
de naam en versie van de assembly;
•
de lijst van bestanden die de assembly bevat;
•
de types die geïmplementeerd zijn in de assembly.
Namespaces kunnen naast klassen ook (sub)namespaces bevatten. Zo wordt een hiërarchische structuur gevormd. Je vindt de structuur terug in de naamgeving.
Voorbeeld: System.Data
Data is een (sub)namespace die in de namespace System zit. Selecteer de assembly System.Data in Solution Explorer. Bekijk de eigenschappen van de assembly in het properties venster. Met welk bestand komt deze assembly overeen? Waar bevindt zich dit bestand op jouw computer?
2.6.2
Object Browser
Open Object Browser via het menu View, Object Browser op de Standard werkbalk of door te dubbelklikken op de naam van een namespace in de References lijst.
VVKSO
Werkgroep handel
Programmeren met .NET 51
Namespaces herken je aan de symbolen { en }. In de namespace System.Drawing, herken je de klasse Color die je reeds gebruikt hebt. Je kunt naar de klassen van System.Drawing verwijzen door enkel de klassenaam op te geven, d.w.z. Color i.p.v. System.Drawing.Color. In welke namespace zit de klasse Form?
2.7
Bereik, beschikbaarheid en levensduur
2.7.1
Declaratieruimten
Een .NET programma bestaat uit een hiërarchische reeks benoemde entiteiten. Bovenaan staat de namespace. Een namespace bevat andere namespaces en/of klassen. Klassen bevatten o. a. methodes, eigenschappen en events. Deze kunnen op hun beurt constanten en variabelen bevatten. Al deze benoemde entiteiten moeten gedeclareerd worden. Een entiteit die andere entiteiten bevat, definieert een declaratieruimte (declaration space). De declaratieruimte van een entiteit eindigt steeds met een End statement. Bijvoorbeeld: Namespace School End Namespace Duid in onderstaand voorbeeld de vernestelde declaratieruimten (4 in het totaal) aan. Namespace School Class Leerling Familienaam VVKSO
Werkgroep Handel
Programmeren met .NET 52
Punten End Class Class Leraar Familienaam Sub GeeftPunten End Sub End Class End Namespace In eenzelfde declaratieruimte context mogen geen entiteiten met dezelfde naam voorkomen. In bovenstaand voorbeeld komt de entiteit Familienaam tweemaal voor: eenmaal in de declaratieruimte van Leerling en eenmaal in de declaratieruimte van Leraar. Vermits dat verschillende declaratieruimten zijn, mag dat. Je zou in de declaratieruimte van GeeftPunten ook nog een variabele Familienaam mogen declareren, omdat je dan weer in een andere declaratieruimte context zit.
2.7.2
Bereik
Het bereik (scope) van een entiteit is de verzameling van alle declaratieruimten waarin je haar kunt gebruiken met de simpele naam (zonder uitbreiding met bijvoorbeeld de klassenaam). Gewoonlijk is dit de context waarin zij gedeclareerd is. Alleen als er in vernestelde declaratieruimten entiteiten met dezelfde naam zijn, dan is de buitenste entiteit enkel bruikbaar door de volledige naam te gebruiken. Het bereik van een entiteit wordt bepaald door de plaats waar ze gedeclareerd is: in een blok, procedure, module/klasse of namespace. (Een blok is een set instructies die beëindigd worden door een instructie zoals End, Else, Loop, of Next, bijvoorbeeld een For...Next of If...Then...Else...End If constructie.) Voorbeeld Class Leraar Familienaam ‘Bereik: klasse Leraar uitgezonderd procedure GeeftPunten Sub GeeftPunten Familienaam
‘Bereik: procedure GeeftPunten
… End Sub End Class Als je in de procedure GeeftPunten Familienaam gebruikt, dan gaat het over de variabele die gedeclareerd is in de procedure. Wil je de variabele die op klasseniveau gedeclareerd is, gebruiken dan moet je als naam Leraar.Familienaam gebruiken.
2.7.3
Beschikbaarheid
De beschikbaarheid van een entiteit, d.w.z. de plaats waar je ze kunt gebruiken met welke naamgeving dan ook, wordt bij de declaratie bepaald door een access modifier. De belangrijkste access modifiers zijn Public, Private, Protected en Friend. Wat dit praktisch betekent, hangt er vanaf of je met een module of een klasse werkt (voor het verschil tussen beide, zie paragraaf Error: Reference source not found).
VVKSO
Werkgroep handel
Programmeren met .NET 53
Modifier
Gedeclareerd in
Beschikbaarheid
Public
Module
Een Public entiteit (procedure, variabele…) kan overal in het project opgeroepen worden.
Klasse
De entiteit is beschikbaar voor elk object van die klasse, het is m.a.w. de declaratie van een methode of eigenschap.
Private
Module/Klasse
Een Private entiteit kan alleen opgeroepen worden in de module of klasse waarin ze gedeclareerd is.
Protected
Klasse
Een Protected entiteit is beschikbaar in de klasse waarin ze gedeclareerd is en in de klassen die hiervan erven (zie later). Protected kan niet gebruikt worden in een module)
Friend
Module/Klasse
Een Friend entiteit is overal in het project beschikbaar.
2.7.4
Variabelen declareren
Afhankelijk van waar je een variabele nodig hebt, ga je hem op een andere manier declareren.
Blok
De variabele is gekend in het blok waarin hij gedeclareerd is. Modifier: Dim Plaats: in blok Voorbeeld Private Sub BlokTest() Dim blnPerform As Boolean blnPerform = True If blnPerform Then Dim intValue As Integer = 10 MessagBox.Show ("intValue = " & intValue.ToString) End If ' Het volgende zal niet werken omdat intValue hier niet gekend is. MessagBox.Show ("intValue = " & intValue.ToString) End Sub Variable: intValue Bereik: blok Beschikbaarheid: blok
Procedure niveau
De variabele is gekend in de procedure waarin hij gedeclareerd is en in geen enkele andere procedure. Modifier: Dim Plaats: declaratiegedeelte van procedure Voorbeeld VVKSO
Werkgroep Handel
Programmeren met .NET 54
Private Sub ScopeTest() Dim intValue As Integer intValue = 10 MessagBox.Show ("intValue = " & intValue.ToString) ' Na de End Sub, wordt intValue vrijgeven (niet meer beschikbaar) End Sub Variable: intValue Bereik: procedure Beschikbaarheid: procedure
Module/klasse niveau
De variabele is gekend door alle procedures in de module. Modifier: Private, Dim (gebruik bij voorkeur Private) Plaats: declaratiegedeelte van module/klasse Voorbeeld Module modVar1 Private intLoop As Integer Public Sub LoopIncrement() intLoop += 1 End Sub Public Sub LoopDisplay() MessagBox.Show ("intLoop = " & intLoop.ToString) End Sub End Module Variable: intLoop Bereik: module/klasse, hier modVar1 Beschikbaarheid: module/klasse, hier modVar1
Project niveau
De variabele is gekend in gans het project. Een dergelijke variabele wordt ook wel globale variabele genoemd. Globale variabelen kunnen enkel in een module gedeclareerd worden, niet in een klasse. Modifier: Public Plaats: declaratiegedeelte van module Voorbeeld Module modVar2 Public gintValue As Integer Public Sub GlobalModuleValue() MessagBox.Show ("intLoop = " & intLoop.ToString) End Sub End Module Variable: gintValue VVKSO
Werkgroep handel
Programmeren met .NET 55
Bereik: project Beschikbaarheid: huidig project en projecten die dit project gebruiken. Om aan te duiden dat het om een globale variabele gaat, wordt de gebruikelijke tag voorafgegaan door een g: gint. Opmerking Als je in een klasse een variabele in het declaratiegedeelte van de klasse declareert als Public, dan maak je hiervan een eigenschap van de klasse. Public Class Wagen Public Kleur As String End Class Kleur is een eigenschap van de klasse Wagen. Als Wagen1 hiervan een object is, kun je dus gebruik maken van Wagen1.Kleur. Variable: Kleur Bereik: klasse Wagen Beschikbaarheid: klasse Wagen en alle declaratieruimten die gebruik maken van objecten van deze klasse.
2.7.5
Voorbeelden
Voorbeeld 1 Project
Aanwezigen
Type
Windows Application
Doel
Bereik van variabelen
Extra Moeilijkheid
*
Vorm
Volledig uitgewerkt
Probleemstelling In een dancing mag maar een bepaald aantal mensen tegelijkertijd binnen zijn. De portier heeft een programma nodig waarmee hij het aantal aanwezigen kan bijhouden en dat aanduidt wanneer de limiet overschreden wordt. Probleemanalyse Klasse: frmAanwezigen Het probleem kan opgelost worden door gebruik te maken van een eenvoudig formulier.
VVKSO
Werkgroep Handel
Programmeren met .NET 56
Telkens iemand binnengaat, klikt hij op de In-knop, gaat er iemand naar buiten dan klikt hij op de Uit-knop. Zolang het aantal aanwezigen onder het maximaal aantal toegelaten personen blijft is het formulier groen gekleurd, bij het overschrijden van de limiet wordt het rood. frmAanwezigen frmAanwezigen:eigenschappen Eigenschap
waarde
Text
Aantal aanwezigen
frmAanwezigen: besturingselementen
(Enkel besturingselementen die in de code zullen gebruikt worden, worden in de tabel vermeld.) Besturingselement
Belangrijkste Eigenschappen
Waarde
btnIn
Text
In
btnUit
Text
Uit
lblAantal
Text
leeg
frmAanwezigen:procedures Object
Gebeurtenis
Doel
btnIn
Click
- aantal aanwezigen met 1 verhogen - Controle op aantal aanwezigen/ gepaste kleur weergeven
btnUit
Click
- aantal aanwezigen met 1 verlagen - Controle op aantal aanwezigen/ gepaste kleur weergeven
In beide procedures moet het aantal aanwezigen gebruikt worden. Hiervoor wordt een variabele (intAantal) van klasse-niveau gebruikt. Zo'n variabele wordt boven de procedures gedeclareerd en zal in alle procedures van de klasse bereikbaar zijn.
VVKSO
Werkgroep handel
Programmeren met .NET 57
In beide gebeurtenisprocedures komt 'Controle op aantal aanwezigen/ gepaste kleur weergeven' voor. Dit zal daarom in een aparte procedure (VerwerkingAantal) verwerkt worden die aanroepen wordt door beide gebeurtenisprocedures. Algoritmen BtnIn_Click (Handles BtnIn.Click) BtnIn_Click intAantal +1 VerwerkingAantal BtnUit_Click (Handles BtnUit.Click) BtnUit_Click intAantal -1 VerwerkingAantal VerwerkingAantal VerwerkingAantal intAantal < 0 Ja
Nee
intAantal 0 intAantal > maximum aantal Ja achtergrond formulier: rood
Nee achtergrond formulier: groen
Implementatie Private intAantal As Integer = 0 Private Sub btnIn_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnIn.Click intAantal += 1 VerwerkingAantal() End Sub Private Sub btnUit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnUit.Click intAantal -= 1 VerwerkingAantal() End Sub
VVKSO
Werkgroep Handel
Programmeren met .NET 58
Private Sub VerwerkingAantal() Const cintMax As Integer = 500 'maximum toegelaten aanwezigen If intAantal < 0 Then intAantal = 0 End If lblAantal.Text = intAantal.ToString If intAantal > cintMax Then Me.BackColor = Color.Red Else Me.BackColor = Color.LightGreen End If End Sub End Class Verklaring •
Private intAantal As Integer = 0
De variabele intAantal is buiten alle procedures gedeclareerd (in de zone Declarations). Dit betekent dat hij gebruikt kan worden door alle procedures van de klasse frmAanwezigen. Een variabele die binnen een procedure gedeclareerd wordt, kan enkel binnen die procedure gebruikt worden. In welke procedures wordt deze variabele gebruikt? Zou je in elk van deze procedures een variabele intAantal kunnen declareren? Verklaar je antwoord. Als je in plaats van het sleutelwoord Private, het sleutelwoord Public zou gebruiken, dan kan de variabele ook buiten de klasse frmAanwezigen gebruikt worden. In VB.NET kun je in de declaratie de variabele meteen initialiseren. •
Const cintMax As Integer = 500
De constante cintMax is gedeclareerd in de procedure VerwerkingAantal en is dus enkel binnen deze procedure beschikbaar. Wijzig de waarde van de constante in 5 en test de werking van het programma. •
Private Sub VerwerkingAantal()
Je voegt een procedure toe door in het code venster Sub de naam van de procedure te typen. Door het gebruik van het sleutelwoord Private, is de procedure VerwerkingAantal enkel bruikbaar binnen de klasse frmAanwezigen. In de procedure wordt het resultaat weergegeven op een label. Je kunt zowel een tekstvak als een label gebruiken voor uitvoer. Een label heeft o.a. het voordeel dat het alleen-lezen is en dat de achtergrondkleur standaard dezelfde is als deze van het formulier. Uitbreiding Pas bovenstaand project aan zodat: - bij het maximum aantal toegestane aanwezigen de knop btnIn uitgeschakeld wordt; - wanneer er geen aanwezigen meer zijn, de knop btnUit uitgeschakeld wordt.
VVKSO
Werkgroep handel
Programmeren met .NET 59
Voorbeeld 2 De grootte van een formulier wordt bepaald door de waarde van de eigenschap Size. De positie op het scherm bij het starten van de toepassing, wordt bepaald door StartPosition of Location. Hoogte en breedte worden uitgedrukt in pixels. frmHoeken heeft : • •
breedte: 197 hoogte: 152
Bij de start van het programma (StartPosition) wordt het formulier op de standaardpositie getoond. Kies je voor CenterScreen, dan wordt het fomulier bij de start in het midden van het scherm geplaatst.
Als je voor StartPosition de waarde Manual kiest, dan kun je via de eigenschap Location zelf de startpositie van het formulier bepalen. De X-component (horizontaal) en de Ycomponent (vertikaal) bevatten het aantal pixels t.o.v. de linkerbovenhoek van het scherm. Het gegevenstype van Location is Point.
Project
Hoeken
Type
Windows Application
Doel
Bereik van variabelen
Extra
- Een afbeelding op een knop plaatsen - Positie van een formulier op het scherm - Klasse Screen
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling In de hoeken van een formulier worden knoppen geplaatst. Bij het klikken op een knop wordt het formulier in de corresponderende hoek van het schem geplaatst. Bij het openen van het formulier worden hoogte en breedte van het scherm en hoogte en breedte van het formulier getoond in een dialoogvenster (eenheid: pixel).
VVKSO
Werkgroep Handel
Programmeren met .NET 60
Probleemanalyse en implementatie Klasse: frmHoeken frmHoeken: procedures Implementatie Private pntLocatie As Point Private intSchermBreedte, intSchermHoogte As Integer Private Sub frmHoeken_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load intSchermHoogte = Screen.PrimaryScreen.Bounds.Height intSchermBreedte = Screen.PrimaryScreen.Bounds.Width MessageBox.Show("Shermhoogte: " & intSchermHoogte.ToString & vbCrLf _ & "Schermbreedte: " & intSchermBreedte.ToString & vbCrLf _ & "Formulierhoogte: " & Me.Height & vbCrLf _ & "Formulierbreedte: " & Me.Width & vbCrLf) End Sub Private Sub btnLinksboven_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLinksboven.Click pntLocatie.X = 0 pntLocatie.Y = 0 txtRichting.Text = "linksboven" Verplaats() End Sub Private Sub btnRechtsboven_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnRechtsboven.Click pntLocatie.X = intSchermBreedte - Me.Width pntLocatie.Y = 0 txtRichting.Text = "rechtsboven" Verplaats() End Sub Private Sub btnLinksonder_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLinksonder.Click pntLocatie.X = 0 pntLocatie.Y = intSchermHoogte - Me.Height txtRichting.Text = "linksonder" Verplaats() VVKSO
Werkgroep handel
Programmeren met .NET 61
End Sub Private Sub btnRechtsonder_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnRechtsonder.Click pntLocatie.X = intSchermBreedte - Me.Width pntLocatie.Y = intSchermHoogte - Me.Height txtRichting.Text = "rechtsonder" Verplaats() End Sub Private Sub Verplaats() Me.Location = pntLocatie End Sub pntLocatie, intSchermHoogte en intSchermBreedte gedeclareerd. Waarom? Wat is hun bereik?
zijn
boven
de
procedures
Wat is de betekenis van het sleutelwoord Me? Via welke eigenschap is er een afbeelding op de knoppen geplaatst? Bij een standaard installatie van Visual Studio.NET, bevat de map \Program Files\Microsoft Visual Studio .NET 2003\Common7\ Graphics verschillende nuttige afbeeldingen.
Screen.PrimaryScreen.Bounds. Height en Screen.PrimaryScreen.Bounds.Width bevatten respectievelijk de volledige schermhoogte en de schermbreedte. Wil je niet dat het formulier onderaan het scherm gedeelte achter de Taakbalk verdwijnt, dan vervang je Bounds door WorkingArea. Doe dit en test het programma. Uitbreiding Voeg een knop toe die het formulier naar het midden van het scherm brengt. Verwijder het tekstvak txtRichting.
Voorbeeld 3 Project
VerschilData
Type
Windows Application
Doel
Bereik van variabelen
Extra
- Gebruik van MonthCalendar - Werken met datums
Moeilijkheid
*
Vorm
Oplossing
VVKSO
Werkgroep Handel
Programmeren met .NET 62
Probleemstelling In het project VerschilData wordt het aantal dagen tussen twee opgegeven datums berekend en weergegeven. Probleemanalyse en implementatie Het probleem wordt op twee manieren opgelost: frmSimpel: beide datums worden ingevoerd in een tekstvak frmElegant: beide datums worden ingevoerd via een besturingselement MonthCalender. frmSimpel
Implementatie Private Sub btnAantalDagen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAantalDagen.Click Dim intAantalDagen As Integer Dim dteBegindatum, dteEinddatum As DateTime dteBegindatum = CType(txtBegindatum.Text, DateTime) dteEinddatum = CType(txtEinddatum.Text, DateTime) intAantalDagen = dteEinddatum.Subtract(dteBegindatum).Days lblAantalDagen.Text = "Aantal dagen tussen begin- en einddatum: " _ & intAantalDagen.ToString End Sub Verklaring •
dteBegindatum = CType(txtBegindatum.Text, DateTime)
Het sleutelwoord CType zet het opgegeven object opgegeven type DateTime.
txtBegindatum.Text
om naar het
Je mag ook gebruik maken van DateTime.Parse. •
intAantalDagen = dteEinddatum.Subtract(dteBegindatum).Days
Met de methode Substract van een datum wordt de opgegeven datum hiervan afgetrokken. Het resultaat is van het type Timespan. Via de eigenschap Days wordt deze Timespan omgezet in een aantal dagen. Opmerking: trek de begindatum van de einddatum af om een positief aantal dagen te bekomen. frmElegant
VVKSO
Werkgroep handel
Programmeren met .NET 63
frmElegant: besturingselementen Besturingselement
Eigenschap
Waarde
txtBegindatum
ReadOnly
True
txtEinddatum
ReadOnly
True
lblAantalDagen
AutoSize
True
mclrKalender
Visible
False
Implementatie Private blnBegindatum As Boolean Private dteBegindatum, dteEinddatum As DateTime Private Sub txtBegindatum_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles txtBegindatum.Click blnBegindatum = True mclrKalender.Visible = True mclrKalender.Focus() End Sub Private Sub txtEinddatum_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles txtEinddatum.Click blnBegindatum = False mclrKalender.Visible = True mclrKalender.Focus() End Sub Private Sub btnAantalDagen_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAantalDagen.Click Dim intAantalDagen As Integer intAantalDagen = dteEinddatum.Subtract(dteBegindatum).Days lblAantalDagen.Text = "Aantal dagen tussen begin- en einddatum: " _ & lngAantalDagen.ToString End Sub Private Sub mclrKalender_DateSelected(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DateRangeEventArgs) _ Handles mclrKalender.DateSelected
VVKSO
Werkgroep Handel
Programmeren met .NET 64
If blnBegindatum Then dteBegindatum = mclrKalender.SelectionStart txtBegindatum.Text = dteBegindatum.ToShortDateString txtBegindatum.Focus() Else dteEinddatum = mclrKalender.SelectionStart txtEinddatum.Text() = dteEinddatum.ToShortDateString txtEinddatum.Focus() End If mclrKalender.Visible = False End Sub Bestudeer de mogelijkheden van een besturingselement van het type MonthCalendar. Welke members van dit besturingselement worden in de code gebruikt? Wat is hun betekenis? Welke variabelen zijn lokaal (procedure niveau) en welke van klasse niveau? Waarom? De eigenschap ReadOnly van de tekstvakken is op True gezet. Waarom? In welk formaat verschijnen de datums in de tekstvakken? Waar wordt dit bepaald?
Voorbeeld 4 Project
Gemiddelde
Type
Windows Application
Doel
Bereik van variabelen
Extra
Een tweede formulier openen Methode Dispose
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling Het gemiddelde van een aantal getallen moet berekend worden. Eerst wordt het aantal gevraagd en dan worden de getallen één voor één ingelezen.
VVKSO
Werkgroep handel
Programmeren met .NET 65
Probleemanalyse en implementatie Klassen: frmInvoer, frmGemiddelde Er worden twee formulieren gemaakt. Een voor het weergeven van het resultaat en een dialoogvenster voor het invoeren van aantal en getallen. Bij het laden van het eerste formulier wordt het dialoogvenster opgeroepen. frmInvoer Implementatie Public Getal As Single = 0 Public Prompt As String = String.Empty Private Sub btnOK_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnOK.Click If txtInvoer.Text <> String.Empty Then Getal = Single.Parse(txtInvoer.Text) End If Me.Close() End Sub Private Sub frmInvoer_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load lblPrompt.Text = Prompt End Sub Verklaring Getal en Prompt zijn op klasse niveau gedeclareerd met de modifier Public. Dit betekent dat ze eigenschappen zijn van de klasse. Later zul je zien dat er nog een andere (betere) manier bestaat om eigenschappen te declareren. Merk op dat voor deze variabelen de Hongaarse notatie niet gebruikt wordt. Implementatie Private Sub frmGemiddelde_Load(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles MyBase.Load Dim intAantal, intTeller As Integer VVKSO
Werkgroep Handel
Programmeren met .NET 66
Dim sngGetal, sngTotaal, sngGemiddelde As Single Dim strGetallenReeks As String Dim frmInv As frmInvoer 'Aantal getallen inlezen frmInv = New frmInvoer frmInv.Prompt = "Aantal in te voeren getallen:" frmInv.ShowDialog() intAantal = frmInv.Getal frmInv.Dispose() 'Getallen inlezen strGetallenReeks = String.Empty sngTotaal = 0 For intTeller = 1 To intAantal 'Een getal inlezen frmInv = New frmInvoer frmInv.Prompt = "Voer een getal in" frmInv.ShowDialog() sngGetal = frmInv.Getal frmInv.Dispose() 'Het getal verwerken sngTotaal = sngTotaal + sngGetal strGetallenReeks &= sngGetal.ToString & " Next intTeller
"
'Het gemiddelde bereken sngGemiddelde = sngTotaal / intAantal 'De resultaten in het formulier zetten lblAantal.Text = intAantal.ToString lblGetallenReeks.Text = strGetallenReeks lblGemiddelde.Text = sngGemiddelde.ToString End Sub
Verklaring
•
frmInv = New frmInvoer
Er wordt een object van de klasse frmInvoer gecreëerd. •
frmInv.Prompt = "Aantal in te voeren getallen:"
De eigenschap Prompt van het object wordt ingesteld. Bij het laden van het object wordt deze eigenschap gebruikt. •
frmInv.ShowDialog()
Het dialoogvenster wordt getoond als modaal venster, d.w.z. dit venster behoudt de focus zolang het geopend is. •
intAantal = frmInv.Getal
Het ingevoerde getal wordt toegekend aan intAantal. Merk op dat dit geen problemen geeft ook al is Getal van het type Single. •
frmInv.Dispose()
VVKSO
Werkgroep handel
Programmeren met .NET 67
Het object wordt vernietigd zodat het geen plaats meer inneemt in het geheugen. Uitbreiding Wat gebeurt er als je als aantal 0 invoert? Pas het programma aan zodat een gepaste boodschap verschijnt als voor het aantal 0 ingevoerd wordt.
2.7.6
Levensduur
Bij het declareren van een variabele wordt een geheugenplaats voor die variabele voorzien. Als de procedure, klasse of module waarin die variabele gedeclareerd is, afgesloten wordt, dan verdwijnt automatisch ook die geheugenplaats: de variabele bestaat niet meer. In sommige gevallen is het nodig dat de inhoud van de variabele behouden blijft na het afsluiten van de procedure waarin hij gedeclareerd is. Dit krijg je voor elkaar met het sleutelwoord Static.
Voorbeeld Project
Declaraties
Type
Windows Application
Doel
Levensduur van variabelen
Extra
Operator Mod
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling 1 Het project Declaraties maakt de som van twee getallen. Daarna kan via een klik op de knop Even/Oneven nagegaan worden of de som een even of een oneven getal is.
VVKSO
Werkgroep Handel
Programmeren met .NET 68
Probleemanalyse en implementatie Klasse: frmDeclaraties Eenvoudig formulier. De knop Even/Oneven wordt na de controle uitgeschakeld. Implementatie Public Class frmDeclaraties Inherits System.Windows.Forms.Form Windows Form Designer generated code Private intResultaat As Integer Private Sub btnSom_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSom.Click Dim intGetal1, intGetal2 As Integer intGetal1 = Integer.Parse(txtGetal1.Text) intGetal2 = Integer.Parse(txtGetal2.Text) intResultaat = intGetal1 + intGetal2 lblResultaat.Text = "Som: " & intResultaat.ToString btnControle.Enabled = True End Sub Private Sub btnControle_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnControle.Click If intResultaat Mod 2 lblResultaat.Text Else lblResultaat.Text End If btnSom.Focus() btnControle.Enabled =
= 0 Then &= ", een even getal" &= ", een oneven getal" False
End Sub Verklaring •
Private intResultaat As Integer
De variabele intResultaat is op het niveau van de klasse gedefinieerd. Daarom is deze variabele beschikbaar in alle procedures van de klasse, zowel in btnSom_Click als in btnControle_Click. In de declaratie is het sleutelwoord Private gebruikt, dit betekent dat de variabele wel overal in de klasse bruikbaar is, maar niet in andere klassen of modules. •
Dim intGetal1, intGetal2 As Integer
De variabelen intGetal1 en intGetal2 zijn op het niveau van de procedure btnSom_Click gedefinieerd en zijn daarom ook alleen in deze procedure beschikbaar. Dergelijke variabelen worden lokale variabelen genoemd.
VVKSO
Werkgroep handel
Programmeren met .NET 69
Probleemstelling 2 Stel dat je in het vorige voorbeeld Declaraties wilt bijhouden hoe vaak je een som hebt laten berekenen. Probleemanalyse en implementatie In de procedure btnSom_Click moet je een statische variabele opnemen, bijvoorbeeld intAantal. Telkens de procedure doorlopen wordt moet de inhoud van intAantal met 1 verhoogd worden. Om er voor te zorgen dat de inhoud van intAantal bewaard blijft na het beëindigen van de procedure, gebruik je de declaratie: Static intAantal as Integer Pas de code van btnSom_Click aan op de volgende manier en test het programma. Private Sub btnSom_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSom.Click Static intAantal As Integer = 0 Dim intGetal1, intGetal2 As Integer intAantal += 1 intGetal1 = Integer.Parse(txtGetal1.Text) intGetal2 = Integer.Parse(txtGetal2.Text) intResultaat = intGetal1 + intGetal2 lblResultaat.Text = "Aantal: " & intAantal.ToString _ & vbCrLf & "Som: " & intResultaat.ToString btnControle.Enabled = True End Sub Klik meerdere keren op de knop Som. Wat zie je? Uitbreiding Voeg een knop Wissen toe, die de ingevoerde getallen en het resultaat verwijdert.
2.8
Collecties
Een collectie is een verzameling van objecten van dezelfde klasse. Zo vormen alle besturingselementen op een formulier een collectie van Controls. Als je op verschillende elementen van een collectie dezelfde code wilt toepassen, kun je een For Each … Next blok gebruiken.
Voorbeeld Project
For Each
Type
Windows Application
Doel
For Each … Next blok
Extra
Groepsvak
Moeilijkheid
*
VVKSO
Werkgroep Handel
Programmeren met .NET 70
Vorm
Oplossing
Probleemanalyse Uit een lijst van gerechten kunnen en willekeurig aantal gerechten geselecteerd worden. De geselecteerde gerechten worden getoond.
Probleemanalyse en implementatie Klasse: frmMenu Implementatie Private Sub btnTonen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTonen.Click Dim strKeuze As String Dim chkWat As CheckBox strKeuze = String.Empty For Each chkWat In grpKeuzelijst.Controls If chkWat.Checked Then strKeuze &= vbCrLf & chkWat.Text End If Next lblGekozen.Text = "U heeft gekozen: " & vbCrLf & strKeuze End Sub De waarde van de eigenschap Controls van het object grpKeuzelijst (type: groepsvak) is de collectie (verzameling) van de besturingselementen van het groepsvak, m.a.w. alle aankruisvakjes. Door het For Each … Next blok, wordt dezelfde code één na één uitgevoerd op elk aankruisvakje. Hoe zou de code er uitzien als je geen For Each blok gebruikt?
2.9
Niet zichtbare besturingselementen
Het Timer-besturingselement kan gebruikt worden om code uit te voeren met vaste tijdsintervallen. De timer genereert, met een vast tijdsinterval bepaald door de eigenschap Interval, een timergebeurtenis. VVKSO
Werkgroep handel
Programmeren met .NET 71
De onderstaande tabel bevat de belangrijkste eigenschappen van het besturingselement. Eigenschap
Beschrijving
Interval
bevat een waarde tussen 1 en 65 535. De waarde komt overeen met een tijdsinterval uitgedrukt in milliseconden
Enabled
Als deze eigenschap de waarde True bevat betekent dit dat het timerbesturingselement de timer-gebeurtenis zal oproepen telkens het tijdsinterval voorbij is.
.NET beschikt over twee types besturingselementen om te werken met menu's: MainMenu en ContextMenu. Ze zijn zeer gemakkelijk te gebruiken.
Voorbeeld 1 Project
DigitaalUurwerk
Type
Windows Application
Doel
Gebruik van een Timer en een ContextMenu
Extra
Gebruik van het argument e van een gebeurtenisprocedure
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling Maak een digitaal uurwerk dat op het scherm kan geplaatst worden. Via een contextmenu kan het uurwerkje gesloten worden.
Probleemanalyse en implementatie frmKlok: eigenschappen Eigenschap
waarde
FormBorderStyle
None
Opacity
50 %
StartPosition
Manual (Location: 0;0)
Text
Klok
Geef aan het formulier de gewenste grootte. Plaats op het formulier een label lblKlok dat even groot is als het formulier.
VVKSO
Werkgroep Handel
Programmeren met .NET 72
Sleep een Timer-besturingselement naar het formulier. Omdat een Timer-besturingselement niet zichtbaar is, wordt het niet op het formulier geplaatst, maar in het zogenaamde componentenvak. Alle niet zichtbare besturingselementen die je naar het formulier sleept komen automatisch in dit vak.
Eigenschappen van het Timer-besturingselement Eigenschap
waarde
Name
tmrKlok
Enabled
True
Interval
1000
Om de hoeveel tijd wordt er een timergebeurtenis gegenereerd? Als een timergebeurtenis gegenereerd wordt (een Tick), wordt de volgende code uitgevoerd. Private Sub tmrKlok_Tick(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles tmrKlok.Tick lblKlok.Text = Date.Now.TimeOfDay.ToString End Sub Test het programma. Nu ga je nog een contextmenu toevoegen om het klokje te sluiten. Sleep een ContextMenu-besturingselement naar het formulier. Noem het cmnuKlok. Ook dit verschijnt in het componentenvak. Waar Type here staat typ je Sluiten. Noem dit MenuItem mnuSluiten. Bij het klikken op dit menuitem moet het klokje verdwijnen, d.w.z. frmklok moet gesloten worden. Implementatie Private Sub mnuSluiten_Click(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles mnuSluiten.Click Me.Close() End Sub
VVKSO
Werkgroep handel
Programmeren met .NET 73
Het contextmenu moet verschijnen als de gebruiker met de rechtermuisknop op het label klikt. Private Sub lblKlok_MouseUp(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) Handles lblKlok.MouseUp If e.Button = MouseButtons.Right Then cmnuKlok.Show(Me, New Point(20, 20)) End If End Sub Verklaring Bij een gebeurtenisprocedure die een 'muisgebeurtenis' behandelt, kun je via het argument e van de gebeurtenis achterhalen op welke muisknop geklikt is. Om het contectmenu te tonen gebruik je de methode Show. Deze heeft twee argumenten - de control waarbij het contextmenu hoort, hier het formulier - de positie t.o.v. van deze control. De positie moet van het type (System.Drawing.)Point zijn. In de code wordt hiervoor een instantie van de structure gecreëerd. Uitbreiding Breid het contextmenu uit zodat de gebruiker kan kiezen voor een kleur voor de cijfers van het klokje.
Voorbeeld 2 Project
Timer
Type
Windows Application
Doel
Gebruik van een Timer en een ImageList
Extra
Levensduur van een variabele (Static)
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling Het programma toont om de vier seconden een andere figuur. In het totaal zijn er 4 verschillende figuren. Probleemanalyse en implementatie Klasse: frmTimer In het voorbeeld Timer wordt nog een 'onzichtbaar' besturingselement gebruikt: een ImageList. Een ImageList bevat een collectie (verzameling) afbeeldingen.
VVKSO
Werkgroep Handel
Programmeren met .NET 74
Het eigenschappenvenster van de ImageList bevat niet veel items. Je kunt de collectie afbeeldingen aanmaken door te klikken op … naast de eigenschap Images. In het nieuwe dialoogvenster kun je de verschillende figuren ingeven.
Elke afbeelding is een object van een klasse. Van welke klasse? De figuren zijn bereikbaar via een index, bijvoorbeeld imlLijst.Images(0) bevat de eerste afbeelding. Welk type besturingselement wordt gebruikt om de afbeeldingen in te tonen?
VVKSO
Werkgroep handel
Programmeren met .NET 75
Implementatie Private Sub tmrWissel_Tick(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles tmrWissel.Tick Static intTeller As Integer picPrent.Image = ilsLijst.Images(intTeller) intTeller += 1 If intTeller = 4 Then intTeller = 0 End If End Sub Waarom wordt in de code gebruik gemaakt van een statische variabele? Uitbreiding Pas het programma aan zodat de gebruiker bij het openen van de toepassing het tijdsinterval van wisseling kan opgeven.
2.10
Tekenen
In de System.Drawing namespace vind je klassen die je kunt gebruiken om tekeningen naar een willekeurig besturingselement in een Windows Forms applicatie te schrijven.
2.10.1
Het Graphics Object
Om ook maar iets te kunnen tekenen, moet je een Graphics object creëren. In de Graphics class zitten alle tekenfuncties waarmee je lijnen, elipsen, bogen, vierkanten en dergelijke kunt tekenen. Er zijn twee soorten tekenfuncties (methoden): - Draw… , bijvoorbeeld DrawEllipse - Fill… bijvoorbeeld FillRectangle. De Draw-methoden tekenen de omtrek van een figuur en de Fill-methoden tekenen een gevulde figuur. Voor de positionering van de tekening wordt een coördinatensysteem gebruikt. Het startpunt (0,0) is in de linkerbovenhoek van het graphics object. Graphics objecten worden niet gecreëerd met New, maar met de methode CreateGraphics van het besturingselement waarop je wilt tekenen.
2.10.2
Pens en Brushes
Om op het Graphics object te tekenen, moet je beschikken over een pen of een brush. Pens worden gebruikt om de omtrek van een vorm te tekenen, brushes zijn voor het vullen van een vorm. Zowel pens als brushes creëren een GDI object in Windows, dus moet je ervoor zorgen dat ze na gebruik weggegooid worden via Dispose(). Pens worden gemaakt door het opgeven van een kleur en de dikte van de lijn die met de pen wordt getekend.
VVKSO
Werkgroep Handel
Programmeren met .NET 76
Er zijn 5 soorten brushes. • • • • •
HatchBrush: zorgt voor vulling via een patroon dat je via HatchStyle kunt bepalen. LinearGradientBrush: geeft een kleurovergang van de ene kleur naar de andere kleur. PathGradientBrush: geeft een kleurovergang vanuit het centrum van de vorm naar de rand. SolidBrush: een vaste kleur voor de gehele vorm. TextureBrush: vult de vorm met een plaatje.
2.10.3
Voorbeeld
Project
Tekenen
Type
Windows Application
Doel
Objecten instantiëren, gebruiken en verwijderen
Extra
Gebruik van grafische objecten (Graphics, SolidBrush, Pen …)
Moeilijkheid
**
Vorm
Oplossing Open het project Tekenen.
Het project bevat een formulier met twee besturingselementen een picturebox en een knop. Als je op de knop klikt wordt er in de picturebox een smiley getekend.
Een picturebox is een besturingselement dat gebruikt wordt om grafische elementen op een formulier te brengen. Je kunt hiervoor een bestaande tekening of afbeelding gebruiken door de eigenschap Image de naam van een grafisch bestand als waarde te geven. Je kunt er ook zelf in tekenen via de objecten van de namespace System.Drawing. De smiley wordt getekend met volgende code. Private Sub btnTeken_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTeken.Click Dim Dim Dim Dim
graTekenoppervlak As Graphics objYellowBrush As SolidBrush objBlackBrush As SolidBrush objBlackPen As Pen
graTekenoppervlak = picTekening.CreateGraphics objYellowBrush = New SolidBrush(Color.Yellow) VVKSO
Werkgroep handel
Programmeren met .NET 77
objBlackBrush = New SolidBrush(Color.Black) objBlackPen = New Pen(Color.Black, 10) graTekenoppervlak.FillEllipse(objYellowBrush, 25, 25, 187, 187) graTekenoppervlak.FillEllipse(objBlackBrush, 70, 75, 22, 17) graTekenoppervlak.FillEllipse(objBlackBrush, 140, 75, 22, 17) graTekenoppervlak.DrawArc(blackPen, 65, 95, 102, 75, 0, 180) objYellowBrush.Dispose() objBlackBrush.Dispose() objBlackPen.Dispose() End Sub •
Verklaring Dim Dim Dim Dim
graTekenoppervlak As Graphics objYellowBrush As Brush objBlackBrush As Brush objBlackPen As Pen
Declaratie van 4 objectvariabelen. Voor de eerste variabele is een specifieke tag gebruikt, nl. gra. Voor de andere is de algemenere tag obj gebruikt. Het is ondoenbaar om voor alle objecten een specifieke tag te gebruiken. Kies een specifieke tag voor objecten die je vaak gebruikt en obj voor de andere. Zorg er in dit geval voor dat uit de naam blijkt van welk type het object is. •
graTekenoppervlak = picTekening.CreateGraphics
Het object van het type Graphics wordt geïnstantieerd via de methode CreateGraphics van de picturebox. Merk op dat er bij het toekennen van een objectvariabele in VB.NET geen gebruik gemaakt wordt van het sleutelwoord Set zoals in VBA. •
objYellowBrush = New SolidBrush(Color.Yellow) objBlackBrush = New SolidBrush(Color.Black) objBlackPen = New Pen(Color.Black, 10)
Voor het creëren van de andere objecten wordt de constructor New gebruikt. Selecteer in Object Browser de klasse SolidBrush van de namespace System.Drawing. Deze klasse wordt gebruikt voor het inkleuren van vormen. Je ziet dat de constructor New een argument van het type Color nodig heeft. Selecteer in Object Browser de klasse Pen van de namespace System.Drawing. De klasse Pen bevat 4 verschillende constructors New. Dit is een voorbeeld van Polymorfisme (veelvormigheid, wordt verder in de cursus besproken). De constructor heeft vier verschillende vormen. Merk op dat de argumenten van de vier vormen verschillend zijn. Er bestaat ook een mogelijkheid om tegelijkertijd een variabele te declareren en te instantiëren. De code ziet er dan als volgt uit: Dim Dim Dim Dim
VVKSO
graTekenoppervlak As Graphics = picTekening.CreateGraphics objYellowBrush As New SolidBrush(Color.Yellow) objBlackBrush As New SolidBrush(Color.Black) objBlackPen As New Pen(Color.Black, 10)
Werkgroep Handel
Programmeren met .NET 78
Welke vorm is hier gebruikt? •
graTekenoppervlak.FillEllipse(objYellowBrush, 25, 25, 187, 187) graTekenoppervlak.FillEllipse(objBlackBrush, 70, 75, 22, 17) graTekenoppervlak.FillEllipse(objBlackBrush, 140, 75, 22, 17)
De FillEllipse methode van het Graphics object heeft volgende argumenten: FillEllipse(brush, x-coördinaat, y-coördinaat, breedte, hoogte) x-coördinaat, y-coördinaat, breedte, hoogte zijn van het type Integer. De methode vult een ellips die begrensd wordt door een rechthoek waarvan de linkerbovenhoek de coördinaten (x,y) heeft en met de opgegeven breedte en hoogte. Alle waarden worden uitgedrukt in pixels en de coördinaten worden gemeten t.o.v. de linkerbovenhoek van de picturebox. •
graTekenoppervlak.DrawArc(objBlackPen, 65, 95, 102, 75, 0, 180)
De DrawArc methode van het Graphics object heeft volgende argumenten: DrawArc(brush, x-coördinaat, y-coördinaat, breedte, hoogte, beginhoek, draaihoek) x-coördinaat, y-coördinaat, breedte, hoogte, beginhoek en draaihoek zijn van het type Integer. De methode tekent een boog beginnend bij een punt met de coördinaten (x,y) en met de opgegeven breedte en hoogte. De hoeken bepalen de vorm van de boog. •
objYellowBrush.Dispose() objBlackBrush.Dispose() objBlackPen.Dispose()
Als een object niet meer gebruikt wordt, geef je de geheugenruimte die het inneemt weer vrij met de methode Dispose. Alle klassen bezitten een dergelijke methode. In feite is het niet noodzakelijk om de opdracht hiervoor te geven. Na het uitvoeren van de procedure worden de daarin aangemaakte objecten vanzelf vrijgegeven. De Garbage Collection zorgt voor het vrijmaken van het geheugen. Door de methode Dispose expliciet te gebruiken, zorg je er voor dat dit onmiddellijk gebeurt.
Tekenen op een formulier
Je kunt ook rechtstreeks tekenen op een formulier door de nodige code toe te voegen aan de procedure die de gebeurtenis Paint van het formulier afhandelt. Deze gebeurtenis treedt op bij het op het scherm zetten van het formulier. Voorbeeld Private Sub frmTekening_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint Dim Dim Dim Dim
graOpp As Graphics objGeel As Brush objZwart As SolidBrush objZwartePen As Pen
graOpp = Me.CreateGraphics objGeel = New SolidBrush(Color.Yellow) objZwart = New SolidBrush(Color.Black) objZwartePen = New Pen(Color.Black, 10) graOpp.FillEllipse(objGeel, 25, 25, 187, 187) graOpp.FillEllipse(objZwart, 70, 75, 22, 17) graOpp.FillEllipse(objZwart, 140, 75, 22, 17)
VVKSO
Werkgroep handel
Programmeren met .NET 79
graOpp.DrawArc(objZwartePen, 65, 95, 102, 75, 0, 180) End Sub Uitbreiding Maak een formulier met verschillende knoppen en een picturebox. Met elke knop wordt een andere smiley in de picturebox getekend (lachende, trieste, strenge…)
2.11
Deployment
Eens je programma (project) volledig klaar is wil je het waarschijnlijk verspreiden, d.w.z. ook op andere computers beschikbaar maken. Dit wordt deployment genoemd. .NET projecten kunnen op verschillende manieren gedeployed worden: XCopy deployment en via een setup programma. Beide komen aan bod in deze cursus, maar vooraf een beetje achtergrondinformatie.
2.11.1
Interpreter en compiler
Programmacode kan op verschillende manieren uitgevoerd worden, met behulp van: •
een interpreter worden de instructies direct uitgevoerd. De omzetting naar machinetaal gebeurt praktisch instructie per instructie. Na de omzetting wordt de instructie onmiddellijk uitgevoerd;
•
een compiler worden alle instructies vooraf omgezet naar een uitvoerbaar bestand in machinetaal. Dit bestand kan door de processor direct worden begrepen en uitgevoerd;
•
een compiler voor de programmeertaal worden de instructies omgezet in een tussencode, een speciale interpreter voor die tussencode voert dan deze instructies uit.
Een programma dat met een compiler wordt vertaald kan over het algemeen sneller worden uitgevoerd dan wanneer gebruik gemaakt wordt van een interpreter. Het voordeel van een taal die geïnterpreteerd kan worden, is dat het testen veel sneller gaat, omdat compileren niet nodig is. Compileren gebeurt in verschillende fases: •
analysefase om te zien of er geen syntaxis-fouten zijn gemaakt;
•
één of meerdere omzettingsfases;
•
schrijven van het zogenaamde objectbestand.
De resulterende objectbestanden moeten vaak nog gelinkt worden, d.w.z. samengevoegd met andere code, bijvoorbeeld opstartcode, waarna het uitvoerbaar bestand (meestal met extensie .exe) klaar is. In het geval van de variant die nog een interpreter vereist, wordt de linkfase gewoonlijk overgeslagen. Het compilatieproces is hierdoor meestal wat sneller, maar de uitvoering trager. Een voordeel van interpreter gebaseerde compilatie kan wel zijn dat de gegenereerde objectcode portable is naar andere systemen. De interpreter zelf is dan niet portable en handelt de platform specifieke zaken af. Visual Basic code wordt gecompileerd en gelinkt, maar is niet zelfstandige uitvoerbaar: een VBprogramma zal steeds de Visual Basic Runtime Libraries nodig hebben om uitgevoerd te worden. Deze libraries zijn gratis te downloaden vanaf de Microsoft-site en mogen vrij gekopieerd worden. VBA-programma's worden in zekere mate gecompileerd, ze kunnen echter enkel uitgevoerd worden binnen hun host (MS Excel, MS Access …).
VVKSO
Werkgroep Handel
Programmeren met .NET 80
Bij het maken van een build, wordt Visual Basic.NET-code gecompileerd naar MSIL, Microsoft Intermediate Language. Dit is géén machinecode en kan dus niet rechtstreeks worden uitgevoerd. De MSIL-code wordt doorgegeven aan het platform waarop ze gebruikt zal worden. Daar zal de Common Language Runtime (CLR), een onderdeel van het .NET framework (zie 2.11.2), de code just-in-time (JIT) compileren naar machinecode en dan pas uitvoeren. Dit betekent dat een VB.NET project enkel kan uitgevoerd worden op computers waarop het .NET framework geïnstalleerd is.
2.11.2
Het .NET Framework
Het .NET Framework is standaard voorzien in Windows Server 2003. Het wordt meegeleverd met Visual Studio .NET en is vrij downloadbaar van de website van Microsoft. .NET Framework bevat geen IDE, daarvoor heb je Visual Studio .NET nodig! Op computers die niet gebruikt worden voor ontwikkeling volstaat het .NET Framework om .NET toepassingen uit te voeren. In Configuratiescherm, Software kun je zien of .NET Framework geïnstalleerd is op de computer.
Windows .NET Framework bestaat uit de gestandaardiseerde set klassenbibliotheken.
Common
Language
Runtime
en
een
Common Language Runtime
De CLR (Common Language Runtime) is verantwoordelijk voor runtime-services, o.a. voor de vertaling van MSIL-code naar machinetaal, het beheren van beveiliging, geheugen, processen en threads. •
Garbage Collection is een technologie waarmee het geheugen beheerd wordt dat door een toepassing gebruikt wordt in runtime. Zaken zoals lege referenties worden door de Garbage Collector opgeruimd zonder dat de programmeur zich daarmee moet bezighouden in de code.
VVKSO
Werkgroep handel
Programmeren met .NET 81
Hierdoor wordt de kans op geheugenlekken sterk gereduceerd en is het programmeren van toepassingen in .NET eenvoudiger. •
Code verificatie is een speciaal proces dat controleert of code veilig is om uitgevoerd te worden en geen problemen kan veroorzaken. Het gaat o.a. over de controle van gegevenstypes, het vermijden van illegale uitvoeringen op ongeldige geheugengebieden enz. Als de code iets verkeerds doet, dan zal de CLR ervoor zorgen dat er een exception (opmerking, verwittiging) wordt teruggegeven voordat de code schade berokkent. Deze uitzondering kan opgevangen worden door een toepassing (zie volgend hoofdstuk).
•
Code access security controleert of bepaalde stukken code uitgevoerd mogen worden of juist niet, afhankelijk van de instellingen van de machine waarop de code uitgevoerd wordt. De uitvoerrechten worden bepaald op basis van de configuratie, de metadata en de oorsprong van de code. Het hoofddoel van deze functionaliteit is het vermijden dat schadelijke code uitgevoerd kan worden en dat deze eventueel (code van) andere toepassingen kan schaden bij uitvoering.
Code die gegenereerd wordt door de CLR, noemt men managed code of beheerde code. Code afkomstig uit niet .NET -omgevingen, zoals VBA, wordt dan unmanaged code genoemd.
Klassenbibliotheken
In het .NET Framework zijn een massa voorgedefineerde klassen voorzien. Deze spreek je aan bij het ontwikkelen, je creëert objecten en gebruikt de members hiervan. Bij het uitvoeren van een programma wordt de corresponderende code in de klasse uitgevoerd.
2.11.3
Ondersteuning verschillende programmeertalen
http://www.microsoft.com/netherlands/vstudio/ Visual Studio .NET ondersteunt verschillende programmeertalen, o.a. de talen die Microsoft bij .NET levert: Visual Basic.NET, Visual C#.NET, Visual J#.NET (aangepaste Java) en Visual C++.NET. Een van de doelstellingen van .NET is de stimulering van “cross language development”. Dit betekent dat verschillende talen “door elkaar” gebruikt mogen en kunnen worden om één applicatie te ontwikkelen. Deze talen moeten aan de Common Language Specification van .NET voldoen. Elk van deze talen heeft zijn eigen compiler binnen de .NET omgeving. Deze vertaalt de broncode naar MSIL, Microsoft Intermediate Language. Deze taal is voor alle .NET programmeertalen dezelfde. De MSIL-code wordt bij uitvoering door de Common Language Runtime omgezet naar machinetaal.
2.11.4
XCopy Deployment
http://www.developer.com/net/net/print.php/3352511 http://msdn.microsoft.com/netframework/technologyinfo/infrastructure/deployment/default.aspx Als je een succesvolle build maakt van een project, verschijnt in de submap bin van het project een .exe bestand met dezelfde naam als het project. Dit is een uitvoerbaar bestand, d.w.z. je kunt het uitvoeren los van Visual Studio.NET. Het .pdb bestand bevat debugging gegevens. Voer het .exe bestand uit vanuit Verkenner. Bij het ontwikkelen van het programma worden deze bestanden telkens aangepast. Op dat moment is het niet zo belangrijk dat de gecompileerde code zo efficiënt mogelijk is, het moet snel gaan. Eens je een definitieve versie van het programma hebt, wordt efficiëntie van de code wel belangrijk. Daarom zijn er verschillende opties mogelijk voor het maken van een build: Debug en Release. VVKSO
Werkgroep Handel
Programmeren met .NET 82
•
Debug: het uitvoerbaar bestand bevat debugging informatie en is niet geoptimaliseerd.
•
Release: het uitvoerbaar bestand is geoptimaliseerd.
Je kiest de geschikte optie via Build, Configuration Manager.
Kies Debug zolang je in de ontwikkelingsfase zit. Voor de definitieve versie kies je Release. Een applicatie overbrengen naar de computer(s) die er gebruik van zullen maken, noemt men Deployment. Voor een eenvoudige .NET Windows Application heb je twee mogelijkheden hiervoor: - XCopy: je kopieert het uitvoerbare bestand naar een willekeurige map van de doelcomputer. Hierop moet wel het .NET Framework geïnstalleerd zijn. - een setupbestand: je maakt een msi-bestand voor Windows Installer. Het maken van een setupbestand wordt later besproken.
E X T R A
2.12
Bespreking van de Windows Form Designer generated code
Hieronder wordt een korte verklaring gegeven van de code die gegenereerd werd door de Windows Form Designer voor het project Rekenwonder. Het is zeker niet de bedoeling dat je alles reeds tot in de puntjes begrijpt. Naarmate je verder vordert in het object georiënteerd programmeren, zul je deze code beter begrijpen.
2.12.1
Klasse
Bij het ontwerpen van het formulier wordt er automatisch code gegeneerd. Je kunt die code zien door op het +-teken voor Windows Form Designer generated code te klikken. Doe dit.
2.12.2
Constructor
De eerste procedure in de gegenereerde code: Public Sub New() MyBase.New() 'This Me.is required by the Windows Form Designer. InitializeComponent()
VVKSO
Werkgroep handel
Programmeren met .NET 83
'Add any initialization after the InitializeComponent() call End Sub Iedere klasse heeft een procedure New. Deze wordt constructor genoemd. Ze wordt uitgevoerd bij het creëren van een object van de klasse. De procedure bevat in dit geval twee instructies die beide een andere procedure oproepen. Mybase.New(): de procedure New() van de parent-klasse wordt uitgevoerd. Het sleutelwoord Mybase verwijst naar die parent-klasse. Wat is de parent-klasse? InitializeComponent(): een procedure die verder in de gegenereerde code staat.
2.12.3
Initialisatie
Bekijk de subprocedure InitializeComponent(): Private Sub InitializeComponent() Me.txtGetal1 = New System.Windows.Forms.TextBox Me.lblGetal1 = New System.Windows.Forms.Label Me.lblGetal2 = New System.Windows.Forms.Label … End Sub Het sleutelwoord Private wijst er op dat deze procedure enkel binnen de klasse frmRekenwonder kan uitgevoerd worden. Wanneer wordt deze procedure uitgevoerd? Met de eerste instructies zoals Me.txtgetal1 = New System.Windows.Forms.TextBox worden de objecten gecreëerd die als besturingselementen op het formulier geplaatst worden. Het sleutelwoord New verwijst naar een nieuwe instantie van de klasse. In VB.NET wordt het sleutelwoord Set dat in VBA nodig is bij de toekenning van een objectvariabele, niet gebruikt. De variabelen zijn buiten de functie gedeclareerd: Friend WithEvents txtgetal1 As System.Windows.Forms.TextBox Friend WithEvents txtGetal2 As System.Windows.Forms.TextBox Friend WithEvents grpBewerking As System.Windows.Forms.GroupBox … Wat is de betekenis van de sleutelwoorden Friend en WithEvents? Tot welke klasse behoort het object dat geïnstantieerd wordt met de volgende instructie? Me.optQuotient = New System.Windows.Forms.RadioButton
VVKSO
Werkgroep Handel
Programmeren met .NET 84
In welke statements worden de waarden die je zelf aan eigenschappen van besturingselementen gegeven hebt, ingesteld?
2.12.4
Dispose
De methode Dispose wordt opgeroepen als een component niet langer nodig is. Windows Forms roept de methode op voor een formulier en alle besturingselementen die er op staan als het formulier gesloten wordt. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub
2.13
Oefeningen
1
Maak een eenvoudig formulier dat aan de hand van een ingegeven datum, bij benadering het aantal resterende lesuren geeft van een bepaald vak. Je geeft de naam van het vak op, het aantal lesuren in de week en het aantal weken (vanaf de ingegeven datum) dat er geen les gegeven wordt vanwege vakantie, examenperiode, stage … Als toemaatje wordt ook het aantal minuten gegeven waarmee dit overeenkomt.
2
Een groep die naar de bioscoop gaat, krijgt korting. Een toegangskaartje kost normaal 5,00 EUR. Vanaf 10 personen geeft de filmuitbater reductie. Zijn er minder dan 20 bezoekers dan bedraagt de korting 15 %, in het andere geval 30 %. Maak een programma Bioscoop om te bepalen hoeveel een groep juist moet betalen.
3
Maak een rekentest voor de kleintjes (project Rekentest). Op het scherm komen 5 willekeurige sommen. De getallen die opgeteld moeten worden zijn allemaal kleiner dan 10. Op het formulier met de sommen komen twee knoppen: één knop om een nieuwe reeks sommen te genereren en één knop om de resultaten te controleren. Bij controle van de resultaten krijgen de foute antwoorden een rode achtergrond, de juiste een groene.
4
Maak een programma (project Cirkel) dat een cirkel tekent in een picturebox. De kleur wordt gekozen in een keuzelijst, de coördinaten van de linkerbovenhoek van het vierkant waarin de cirkel wordt getekend en de straal worden ingevoerd.
5
Maak een casinospelletje (project Casino). Bij een druk op een knop worden 3 positieve gehele getallen kleiner dan 10 gegeneerd en getoond op het scherm. Als twee getallen hetzelfde zijn verdient de speler 10 punten, als de drie getallen hetzelfde zijn verdient hij 100 punten. Toon op het formulier het aantal gespeelde beurten en het totaal aantal verdiende punten. Gebruik je fantasie om het spelletje zo aangenaam mogelijk te maken.
6
Pas het project Casino aan zodat er figuren getoond worden i.p.v. getallen.
VVKSO
Werkgroep handel
Programmeren met .NET 85
2.14
Overzicht
2.14.1
Namen van variabelen en constanten
Bij het benoemen van de variabele moet je onderstaande regels naleven: •
de naam moet met een letter beginnen, niet met een cijfer of een ander teken. De rest van de naam mag uit letters, cijfers en onderstrepingtekens bestaan;
•
de naam mag niet langer dan 255 tekens zijn.;
•
binnen het bereik van de variabele moet de naam uniek zijn. (Het bereik is de actieradius waarbinnen de variabele kan werken, zie verder);
•
de naam mag niet één van de gereserveerde woorden van Visual Basic.NET zijn;
•
spaties, punten en andere interpunctietekens mogen niet.
2.14.2
Gegevenstypes
Type
Inhoud
Byte
Kleine getallen, opsomming
1B
geheel getal tussen 0 en 255
Short
Gehele getallen
2B
-32 768 tot 32 767
Integer
Gehele getallen
4B
ongeveer +/- 2 miljard 147 miljoen
Long
Gehele getallen
8B
-9223372036854775808 t.e.m. 9223372036854775807
Single
Decimale getallen
4B
(+/-)1.401298E- 45 tot 3.402823E38
Double
Decimale getallen
8B
(+/-)1.79769313486231E+308 tot 4.940656458424E-324
Decimal
Decimale getallen
16B
0 tot +/-79228162514264337593543950335 zonder decimaal punt; 0 tot +/-7.9228162514264337593543950335 met 28 cijfers rechts van het decimaal punt;
Geheugenruimte
Waardenbereik
Het kleinste getal dat niet gelijk is aan nul: +/-0.0000000000000000000000000001 (+/-1E-28). Char
Eén tekstkarakter
String
Tekstinformatie
Boolean
Logische waarde
VVKSO
Werkgroep Handel
2B
Eén tekstkarakter in 16 bits Unicode, dus eigenlijk een getal tussen 0 en 65 536 (zonder teken).
1B per teken
Tot 65 400 tekens voor reeksen met een vaste lengte en tot 2 miljard tekens voor dynamische tekenreeksen.
2B
True of False
Programmeren met .NET 86
Date
Datumtijdinformatie
Object
Instanties van klassen
en
8B 4B extra
100-1-1 tot en met 9999-12-31 ---
Je mag in VB.NET ook de datatypes gebruiken van de Common Language Runtime (Common Type System).
De gegevenstypes van VB.NET (en van de andere .NET talen) moeten door de compiler vertaald worden naar gegevenstypes van MSIL. Voor elk gegevenstype van VB.NET bestaat een corresponderend gegevenstype in MSIL. De benamingen die MSIL gebruikt zijn lichtjes anders dan deze van VB.NET.
Volgende tabel geeft de corresponderende gegevenstypes weer. VB.NET
CLR
VB.NET
CLR
Boolean
System.Boolean
Integer
System.Int32
Byte
System.Byte
Long
System.Int64
Char
System.Char
Object
System.Object
Date
System.DateTime
Short
System.Int16
Decimal
System.Decimal
Single
System.Single
Double
System.Double
String
System.String
Je kunt in een declaratie de verschillende datatypes door elkaar gebruiken.
VVKSO
Werkgroep handel
Programmeren met .NET 87
2.14.3
Naamgeving
Binnen Microsoft .NET ontwikkelteams worden over het algemeen bepaalde Naming Conventions gehanteerd. Je vindt hierover meer op http://www.tenback.com/ . In deze cursus wordt de Hongaarse notatie gebruikt voor de besturingselementen op formulieren (zie bijlage 2). Om didactische redenen wordt deze methode hier ook gebruikt voor de (private) variabelenamen. Elke woordsamenstelling in de Hongaarse notatie begint met een prefix van meestal drie of vier niet hoofdletters. De prefix geeft in het kort weer, van welk type variabele of object het tweede gedeelte van de woordsamenstelling is, bijvoorbeeld btnOK is een OK button.
2.14.4
Conversiesleutelwoorden
Volgende tabel bevat een overzicht van een aantal conversiesleutelwoorden van Visual Basic. Alle conversiefuncties beginnen met de letter C.
Functie Return type
Bereik voor het expressie argument
CBool
Boolean
String of numerische expression.
CByte
Byte
0 through 255; fracties worden afgerond.
CChar Char
String; waarde tussen 0 en 65 535.
CDate
Date
Datum en tijd.
CDbl
Double
-1.79769313486231E+308 tot -4.94065645841247E-324 voor negatieve waarden; 4.94065645841247E-324 tot 1.79769313486231E+308 voor positieve waarden.
CDec
Decimal
+/-79 228 162 514 264 337 593,543 950 335 voor getallen zonder decimalen. Voor getallen met 28 decimalen: +/-7,9228162514264337593543950335.
CInt
Integer
-2 147 483 648 tot 2,147,483,647; fracties worden afgerond
CLng
Long
-9 223 372 036 854 775 808 tot 9 223 372 036 854 775 807; fracties worden afgerond
CObj
Object
Om het even welke expressie.
CShort Short
-32 768 through 32 767; fracties worden afgerond.
CSng
Single
-3,402823E+38 tot -1.401298E-45 voor negatieve waarden; 1,401298E-45 tot 3,402823E+38 for positieve waarden.
CStr
String
Een getal, boolean of datum.
CType Aangeduide Ctype(obj, gegevenstype) gegevenstype
2.14.5
Bereik, beschikbaarheid van een entiteit
Het bereik van een entiteit is de verzameling van declaratieruimten waarin de entiteit kan gebruikt worden onder zijn eenvoudige naam.
VVKSO
Werkgroep Handel
Programmeren met .NET 88
De beschikbaarheid van een variabele is de verzameling van declaratieruimten waarin de entiteit kan gebruikt worden, onder welke naam dan ook. Modifier
Gedeclareerd in
Beschikbaarheid
Public
Module
Een Public entiteit (procedure, variabele…) kan overal in het project opgeroepen worden.
Klasse
De entiteit is beschikbaar voor elk object van die klasse, het is m.a.w. de declaratie van een methode of eigenschap.
Private
Module/Klasse
Een Private entiteit kan alleen opgeroepen worden in de module of klasse waarin ze gedeclareerd is.
Protected
Klasse
Een Protected entiteit is beschikbaar in de klasse waarin ze gedeclareerd is en in de klassen die hiervan erven (zie later). Protected kan niet gebruikt worden in een module)
Friend
Module/Klasse
Een Friend entiteit is overal in het project beschikbaar.
Wees voorzichtig bij het gebruik van dezelfde namen voor elementen met een verschillend bereik. Dit kan tot onverwachte resultaten leiden.
2.14.6
Levensduur van een variabele
De levensduur van een variabele is de periode gedurende dewelke ze kan gebruikt worden. •
Variabelen die gedeclareerd worden op niveau van een module of een toepassing (klasse) bestaan en behouden een waarde zolang de toepassing actief is.
•
Een lokale variabele bestaat enkel zolang de procedure uitgevoerd wordt. Wanneer de procedure stopt, bestaat de lokale variabele niet meer, en gaat de waarde normaal gezien verloren. Indien de procedure de volgende keer uitgevoerd wordt, worden de lokale variabelen opnieuw gedeclareerd en de geheugenruimte wordt opnieuw toegekend.
•
De modifier STATIC zorgt ervoor dat de variabele enkel lokaal bruikbaar blijft, maar dat de waarde tussen twee oproepen van de procedure wel behouden blijft. Dit heeft een voordeel ten opzichte van de declaratie van een variabele met een grotere scope, want de waarde kan niet binnen een andere procedure, module of klasse aangepast worden. Deze soort declaratie wordt vooral gebruikt voor tellers die binnen een procedure verhoogd dienen te worden.
2.14.7
Beschikbaarheid van een variabele
De beschikbaarheid (accessibility) van een gedeclareerd element is de mogelijkheid om het te gebruiken. Dit wordt niet enkel bepaald door de declaratie van het element zelf, maar ook door de beschikbaarheid van het grotere geheel (klasse, module) waarvan het element deel uitmaakt. Als dit niet beschikbaar is voor bepaalde code, dan zal het element zelf nooit beschikbaar zijn (ook niet als het Public gedeclareerd wordt).
VVKSO
Werkgroep handel
Programmeren met .NET 89
De beschikbaarheid wordt bepaald door: •
de plaats van declaratie;
•
de manier van declareren aan de hand van de sleutelwoorden Dim, Public, Protected, Friend, Protected Friend of Private.
De vermelde sleutelwoorden hebben de volgende betekenis: •
Public. Hierdoor zijn de variabelen bruikbaar van op elke locatie binnen hetzelfde project, vanuit andere projecten die naar dit project refereren en vanuit een assembly die gebouwd wordt vanuit dit project. De declaratie met Public kan enkel gebruikt worden op niveau van een module, een namespace of een klasse, niet op niveau van een procedure.
•
Protected. Dit betekent dat deze variabele enkel bruikbaar is binnen dezelfde klasse of binnen een klasse die afgeleid werd van deze klasse. Het sleutelwoord Protected kan enkel op niveau van de klasse gebruikt worden.
•
Friend. Dit betekent dat deze variabele enkel bruikbaar is binnen hetzelfde project en niet buiten het gedefinieerde project. Het sleutelwoord Friend kan enkel op niveau van een module, klasse of structuur gebruikt worden en niet binnen een procedure!
•
Protected Friend. Dit betekent dat deze variabele enkel bruikbaar is binnen een afgeleide klasse of hetzelfde project. Deze sleutelwoorden kunnen enkel op niveau van de klasse gebruikt worden.
•
Private. Dit betekent dat deze variabele enkel bruikbaar is binnen dezelfde module, klasse of structuur. Het sleutelwoord Private kan enkel op niveau van een module, klasse of structuur gebruikt worden en niet binnen een procedure! Als je op niveau van een module het sleutelwoord DIM gebruikt, dan wordt hiermee eigenlijk Private bedoeld.
•
Shared. Dit betekent dat de variabele gedeeld kan gebruikt worden door alle instanties van een klasse, ook buiten de klasse of de structuur waarin ze gedefinieerd werd. Je spreekt ze dan aan door ook de naam van de klasse of de structuur te vermelden, zoals bijvoorbeeld: frmEersteVoorbeeld.strNaam Het sleutelwoord Shared kan enkel op niveau van een module, klasse of namespace gebruikt worden en niet binnen een procedure! Het gebruik van de sleutelwoorden Static en Shared samen in dezelfde variabelendeclaratie wordt niet ondersteund. Er bestaan ook nog sleutelwoorden zoals Shadows, ReadOnly en WithEvents. De betekenis hiervan kun je terugvinden in de Visual Studio.NET helpfunctie.
2.14.8
De Object Browser
Om te weten welke eigenschappen, gebeurtenissen en methodes een bepaald object heeft, kun je de Object Browser gebruiken. Open de Object Browser via het menu View, Object Browser vanaf de werkbalk.
VVKSO
Werkgroep Handel
Programmeren met .NET 90
Als je bijvoorbeeld de attributen van een tekstvak wenst te weten, kun je via de ingebouwde zoekfunctie een overzicht krijgen.
In het venster Find Symbol geef je in wat je wenst te zoeken en waarin moet gezocht worden.
Je krijgt dan een venster met de zoekresultaten.
Dubbelklik op een zoekresultaat om de Object Browser te openen op het gewenste object of attribuut.
VVKSO
Werkgroep handel
Programmeren met .NET 91
Je krijgt een overzicht en een heel beperkte uitleg over het gevraagde. Je krijgt hier wel een duidelijk inzicht van de plaats van het gevraagde in het objectenmodel. Je kunt echter gewoon de Object Browser openen en zelf scrollen doorheen de gebruikte referenties tot je het object of de klasse waarover je informatie wenst, hebt gevonden.
VVKSO
Werkgroep Handel
Programmeren met .NET 92
3
Gebruiksvriendelijkheid • • •
3.1
Foutafhandeling in VB.NET: exceptions Validatie van invoer HelpProvider, ToolTip
De gebruiker staat centraal
Een programma moet niet alleen correct werken, het moet ook gebruiksvriendelijk zijn. Een programma is gebruiksvriendelijk of gebruikersvriendelijk wanneer een gemiddelde gebruiker het eenvoudig en zonder grote problemen kan gebruiken. Noodzakelijke voorwaarden hiervoor zijn: de bediening moet logisch zijn (termen, menu's, pictogrammen en knoppen moeten overeenkomen met de functie die een gebruiker er van verwacht); •
de bediening moet consequent zijn (eenzelfde term, menu, knop of pictogram heeft in alle gevallen een gelijke betekenis); •
de bediening en indeling van standaardelementen (menu's, functietoetsen etc.) moet overeenkomen met standaarden die in andere programma’s gebruikt worden; •
overbodige/onnodige gebruikershandelingen moeten zoveel mogelijk door het programma voorkomen worden; •
het programma moet zo lang mogelijk blijven draaien, ook als de gebruiker foute handelingen verricht; • •
de gebruiker krijgt contextgevoelige informatie (hulp).
3.2
Exceptions
Om het programma draaiende te houden, moet je anticiperen op dingen die kunnen mislopen tijdens de uitvoering van het programma: een bestand dat geopend moet worden is verdwenen, de gebruiker voert iets onverwachts in, bijvoorbeeld tekst waar een getal verwacht wordt, enzovoort. In .NET spreekt men van Exceptions, uitzonderingen. Deze uitzonderingen moeten opgevangen worden door het programma. Voorbeeld Maak een nieuw project Uitzonderingen van het type Console Application. Je komt meteen in de code editor.
Een Console Application is een toepassing die uitgevoerd wordt aan de Opdrachtprompt. Als het programma wordt uitgevoerd, wordt standaard de subprocedure met de naam Main() uitgevoerd.
VVKSO
Werkgroep handel
Programmeren met .NET 93
Voeg de volgende code toe aan de procedure Main(): Sub Main() Dim intDeeltal, intDeler, intResultaat As Integer intDeeltal = 10 intDeler = 0 intResultaat = intDeeltal \ intDeler End Sub Wat is de betekenis van de operator \? Test het programma. Je had waarschijnlijk problemen verwacht en je krijgt die ook!
In het dialoogvenster is er sprake van een exception (uitzondering), niet van een fout. De exception is unhandled (niet behandeld) en van het type System.DivideByZeroException. De knop Break brengt het programma in onderbrekingsmode. Met de knop Continue kun je proberen verder gaan. In dit voorbeeld stopt het programma gewoon. Een exception is, letterlijk vertaald, een uitzondering, een uitzondering op de normaal te volgen instructieweg. Een exception is zeker niet te zien als een fatale fout, maar als een afwijkende situatie waarop gereageerd moet worden. Elek methode van het .NET Framework is zo ontworpen dat ze een exception werpt (throws) zodra zich een fout of een anomalie voordoet. Die exception moet dan door specifieke code behandeld worden in een try-catch blok of een try-catch-finally blok. Een catch blok wordt exception handler genoemd omdat daarin code staat die moet uitgevoerd worden als de exception optreedt. Pas de code als volgt aan: Sub Main() Dim intDeeltal, intDeler, intResultaat As Integer intDeeltal = 10 intDeler = 0 Try intResultaat = intDeeltal \ intDeler Catch Console.Write("Deling door 0") End Try Console.Read() End Sub
VVKSO
Werkgroep Handel
Programmeren met .NET 94
Verklaring
•
Console.Write("Deling door 0")
De methode Write van Console brengt een tekstboodschap aan de opdrachtprompt. Try
•
intResultaat = intDeeltal \ intDeler Catch Console.Write("Deling door 0") End Try Uitzonderingen die optreden binnen het Try – Catch blok (hier slechts één instructie) worden opgevangen door de code in het Catch – End Try blok. •
Console.Read()
De methode Read van Console leest een tekst, ingevoerd aan de opdrachtprompt. Deze instructie werd enkel toegevoegd om het programma te laten pauzeren (wachten op invoer) zodat je tijd hebt om de boodschap aan de opdrachtprompt te lezen. Test het programma. Als er bij het optreden van een exception een exception handler gevonden wordt, dan wordt de code daarvan uitgevoerd. Nadien gaat het programma verder met de code achter de exception handler. Als er geen exception handler gevonden wordt, dan stopt de .NET Common Language Runtime het proces waarin de exception werd opgeworpen en toont de naam en boodschap van de exception. Het is de zorg van elke .NET programmeur om alle exceptions op te vangen zodat zijn of haar programma niet plotseling onderuit gaat. Een exception kan expliciet door het programma veroorzaakt worden door middel van een throw-statement.
3.3
Exception-objecten
Wens je meer informatie te kennen over een exception, dan kun je in het catch-statement een exception-object als argument definiëren. Dit exception-object moet van het type System.Exception (zoals in volgend voorbeeld) of van een afgeleide klasse zijn: Try intResultaat = intDeeltal \ intDeler Catch excUitzondering As Exception Console.Write(excUitzondering.Message) End Try De Message-eigenschap van de Exception-klasse bevat de reden van de exception. In bovenstaand voorbeeld: Attempted to divide by zero Voor Engelstalige programma’s is dit best bruikbaar. Voor Nederlandstalige programma's zul je zelf een boodschap moeten geven. Pas de code aan en test het programma. Je kunt voor het Exception-object ook gebruik maken van een afgeleide van de Exception-klasse, bijvoorbeeld de System.DivideByZeroException: VVKSO
Werkgroep handel
Programmeren met .NET 95
Try intResultaat = intDeeltal \ intDeler Catch excUitzondering As DivideByZeroException Console.Write(excUitzondering.Message) End Try Pas de code aan en test het programma. Bij de uitvoering van de code is in dit geval geen verschil merkbaar, maar de programmacode is beter begrijpbaar. Er wordt duidelijk gemaakt welke exception verwacht en behandeld wordt. Enkel het exceptions van het opgegeven type worden behandeld! De verschillende afgeleide exceptionklassen worden weergegeven door Intellisense.
3.4
Gestructureerde en ongestructureerde foutafhandeling
In VBA zorgen statements als: On Error GoTo Foutafhandeling … Foutafhandeling: … voor de foutafhandeling in een procedure. Men spreekt van ongestructureerde foutafhandeling. Deze vorm blijft mogelijk in VB.NET. De boven besproken exception handling wordt gestructureerde foutafhandeling genoemd. Gestructureerde exception handling is robuuster en flexibeler dan de ongestructureerde. Toch zijn er omstandigheden denkbaar waarbij je voor de ongestructureerde variant zou kunnen kiezen, bijvoorbeeld als je gebruik wil maken van Resume Next wat bij exception handling niet mogelijk is.
3.5
Meervoudige exception handling Open het project Rekenwonder en voer het uit. Wat gebeurt er bij deling door 0? En als zowel deler als deeltal 0 zijn?
Vb.NET vangt deze speciale gevallen op via de eigenschappen Infinity en NaN (Not a Number) van de klasse Double. Voer als getal 1 een aantal letters in, kies een bewerking en klik op de knop Bereken. Volgend dialoogvenster verschijnt.
VVKSO
Werkgroep Handel
Programmeren met .NET 96
Het type exception is System.InvalidCastException. Dit is een voor de hand liggende exception bij invoer in een formulier. Je zorgt zeker voor specifieke afhandeling van deze fout. Mogelijk kunnen er nog andere exceptions optreden. Ook die moeten behandeld worden. Pas de code van het btnBereken_Click aan als volgt. Private Sub btnBereken_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles btnBereken.Click Dim dblGetal1, dblGetal2, dblResultaat As Double Dim strBewerking, strResultaat As String Try
dblGetal1 = Double.ParsetxtGetal1.Text) dblGetal2 = Double.ParsetxtGetal2.Text) Select Case True Case optSom.Checked dblResultaat = dblGetal1 + dblGetal2 strBewerking = "Som: " Case optVerschil.Checked dblResultaat = dblGetal1 - dblGetal2 strBewerking = "Verschil: " Case optProduct.Checked dblResultaat = dblGetal1 * dblGetal2 strBewerking = "Product: " Case optQuotient.Checked dblResultaat = dblGetal1 / dblGetal2 strBewerking = "Quotiënt: " End Select lblResultaat.Text = strBewerking dblResultaat.ToString("#,##0.#####")
&
Catch excUitzondering As InvalidCastException MessageBox.Show(excUitzondering.Message) Catch MessageBox.Show("Fout") End Try End Sub Catch clausules worden uitgevoerd in de volgorde waarin ze in het Catch blok zijn geplaatst.
Voeg exception handling toe aan het project DagVandeWeek. In principe moet elke procedure van elk programma voorzien zijn van Exception handling.
VVKSO
Werkgroep handel
Programmeren met .NET 97
3.6
Validation
Voor de invoer van gegevens in een Windows toepassing worden meestal formulieren gebruikt. De besturingselementen op een dergelijk formulier hebben allemaal de eigenschap CausesValidation en herkennen de gebeurtenis Validating. Dit kun je gebruiken om de invoer te controleren. Als de waarde van de eigenschap CausesValidation False is, dan worden de gebeurtenissen Validating en Validated onderdrukt. De gebeurtenis Validating treedt op bij het verlaten van het besturingselement, de gebeurtenis Validated treedt op na de gebeurtenis Validating. Maak een nieuw Windows Application project Validatie. Voeg 3 labels, 3 tekstvakken en 2 knoppen toe. Geef alle besturingselementen en het formulier gepaste namen (txtStraat, txtGemeente …).
Controleer of voor elk tekstvak de eigenschap CausesValidation de waarde True heeft. Voeg aan het formulier een besturingselement ErrorProvider toe. Een ErrorProvider is een onzichtbaar besturingselement. Daarom wordt het niet op het formulier zelf weergegeven maar onder het formulier. Noem het besturingselement erprvAdres. Met een ErrorProvider kun je visueel tonen welk besturingselement foutieve invoergegevens bevat. Een voorbeeld zal dit duidelijk maken.
3.6.1
Controle op leeg tekstvak Voeg volgende code toe in het codevenster:
VVKSO
Werkgroep Handel
Programmeren met .NET 98
Private Sub ControleOpLeeg(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles txtStraat.Validating, _ txtGemeente.Validating, _ txtPostnummer.Validating Dim ctlSender As Control ctlSender = CType(sender, Control) If ctlSender.Text.Trim = String.Empty Then e.Cancel = True erprvAdres.SetError(ctlSender, "Vul dit veld in!") End If End Sub
Verklaring
•
Private Sub ControleOpLeeg(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles txtStraat.Validating, _ txtGemeente.Validating, _ txtPostnummer.Validating Wat is de betekenis van het sleutelwoord Private. Waaraan herken je dat dit een gebeurtenisprocedure is?
Deze procedure handelt meerdere gebeurtenissen af. Welke? •
Dim ctlSender As Control
De variabele ctlSender wordt gedeclareerd als besturingselement. •
ctlSender = CType(sender, Control)
Het argument sender van de gebeurtenisprocedure verwijst naar het besturingelement (tekstvak, keuzelijst …) dat de gebeurtenis heeft veroorzaakt. Met de conversiefunctie CType wordt het gegevenstype omgezet naar het type Control. •
If ctlSender.Text.Trim = String.Empty Then e.Cancel = True erprvAdres.SetError(ctlSender, "Vul dit veld in!") End If
In de voorwaarde ctlSender.Text.Trim = String.Empty wordt de methode Trim gebruikt van het string-object ctlSender.Text. Wat is de betekenis van deze methode? Wat wordt er in de voorwaarde gecontroleerd? •
e.Cancel = True
VVKSO
Werkgroep handel
Programmeren met .NET 99
De gebeurtenis Validating treedt op bij het verlaten van het besturingselement. Met de methode Cancel van het argument e, wordt het verlaten van het besturingselement geannuleerd. De focus blijft op het besturingselement. •
erprvAdres.SetError(ctlSender, "Vul dit veld in!")
De methode SetError van de ErrorProvider plaatst een pictogram naast het besturingselement waarin de fout optreedt. Als je met de muisaanwijzer over het pictogram schuift, verschijnt de opgegeven boodschap: Vul dit veld in. Test het programma. Merk op dat je het tekstvak niet kunt verlaten zolang je er niets hebt in getypt. Je kunt zelfs het formulier niet sluiten!
3.6.2
Controle op patroon
Het postnummer moet precies 4 cijfers bevatten. Ook dit kun je controleren. Voeg volgende code toe aan het project: Private Sub txtPostnummer_Validating(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles txtPostnummer.Validating Dim ctlSender As Control Dim RegEx As System.Text.RegularExpressions.Regex ctlSender = CType(sender, Control) If Not RegEx.IsMatch(ctlSender.Text.Trim, "\d\d\d\d") Then e.Cancel = True erprvAdres.SetError(ctlSender, "Vier cijfers invullen!") End If End Sub
Verklaring
•
Private Sub txtPostnummer_Validating(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles txtPostnummer.Validating Welke gebeurtenis wordt afgehandeld?
•
Dim RegEx As System.Text.RegularExpressions.Regex
De class library van .NET bevat een klasse voor de gewone uitdrukkingen (regular expressions). Regex. In welke namespace zit deze klasse? Voor klassen van System.Text.RegularExpressions, moet de volledige naam gebruikt worden, anders worden ze niet herkend. •
RegEx.IsMatch(ctlSender.Text.Trim, "\d\d\d\d")
De klasse Regex heeft een methode IsMatch die een tekst vergelijkt met een bepaald patroon, in dit geval "\d\d\d\d". Elke \d stelt een cijfer (digit) voor. Als de tekst voldoet aan het patroon geeft IsMatch de waarde True terug, anders de waarde False.
VVKSO
Werkgroep Handel
Programmeren met .NET 100
Test het programma.
Opmerking
Om te vermijden dat je de volledige naam System.Text.RegularExpressions.Regex moet gebruiken, 'importeer' je de naam van de namespace. Plaats helemaal bovenaan in de code: Imports System.Text.RegularExpressions Je mag nu Dim RegEx As System.Text.RegularExpressions.Regex vervangen door Dim RegEx As Regex Doe dit en test het programma. Meer informatie http://www.codeproject.com/dotnet/RegexTutorial.asp http://www.regular-expressions.info/
3.6.3
De visuele foutaanduiding verwijderen
Als de foutieve invoer gecorrigeerd is, moet de visuele foutaanduiding verdwijnen. Hiervoor gebruik je de gebeurtenis Validated die optreedt na Validating. Vermits de procedure dezelfde is voor alle besturingselementen, schrijf je maar één procedure die de gebeurtenis voor elk besturingselement afhandelt. Voeg de volgende code toe. Private Sub Besturingselement_Validated(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles txtStraat.Validated, _ txtGemeente.Validated, _ txtPostnummer.Validated Dim ctlSender As Control ctlSender = CType(sender, Control) erprvAdres.SetError(ctlSender, String.Empty) End Sub Verklaar de code. Test het programma.
VVKSO
Werkgroep handel
Programmeren met .NET 101
3.6.4
Een fraaiere oplossing
Hoewel de besproken controles op de invoer goed werken, kunnen ze heel wat irritatie opwekken. Je kunt niets doen voor je een correcte invoer hebt ingegeven, zelfs niet op de knop Annuleren klikken of het formulier sluiten. Het is gebruiksvriendelijker om alle invoer te controleren als er op de knop OK geklikt wordt. Open het project Validatie2 en test het programma. Het programma bevat volgende code: Imports System.Text.RegularExpressions Public Class frmAdres Inherits System.Windows.Forms.Form Windows Form Designer generated code Private Sub besturingselement_Validated(ByVal sender As Object,_ ByVal e As System.EventArgs) _ Handles txtStraat.Validated, _ txtGemeente.Validated, _ txtPostnummer.Validated Dim ctlSender As Control
End Sub
ctlSender = CType(sender, Control) erprvAdres.SetError(ctlSender, String.Empty)
Private Sub btnAnnuleren_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAnnuleren.Click txtStraat.Clear txtGemeente.Clear txtPostnummer.Clear erprvAdres.SetError(txtStraat, String.Empty) erprvAdres.SetError(txtGemeente, String.Empty) erprvAdres.SetError(txtPostnummer, String.Empty) End Sub Private Sub btnOk_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnOk.Click Dim RegEx As Regex
End Sub
If txtStraat.Text.Trim = String.Empty Then erprvAdres.SetError(txtStraat, "Vul een waarde in") End If If txtGemeente.Text.Trim = String.Empty Then erprvAdres.SetError(txtGemeente, "Vul een waarde in") End If If Not RegEx.IsMatch(txtPostnummer.Text.Trim, "\d\d\d\d") Then erprvAdres.SetError(txtPostnummer, "Vier cijfers invullen") End If
End Class Verklaar de code.
VVKSO
Werkgroep Handel
Programmeren met .NET 102
3.7
Hulp voor de gebruiker
3.7.1
ToolTip
De gebruiker gepaste hulp geven, bijvoorbeeld bij het invullen van tekstvakken, verhoogt de gebruiksvriendelijkheid van een programma vaak aanzienlijk. Met het besturingselement ToolTip kun je een infobox tonen als de gebruiker met de muisaanwijzer over een besturingselement schuift. Voorbeeld Maak een Windows Application project Hulp met een formulier frmHulp dat er als volgt uitziet.
tltInformatie is een ToolTip (Toolbox). Wat is de betekenis van de eigenschappen waarin “Delay” voorkomt? Met de methode SetToolTip ken je een tekst toe per besturingselement. Voeg de volgende code toe. Private Sub frmHulp_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load tltInformatie.SetToolTip(txtLeeftijd, "Exacte leeftijd (geheel getal)") tltInformatie.SetToolTip(txtNaam, "Familienaam gevolgd door voornaam") tltInformatie.SetToolTip(txtDatum, "jjjj-mm-dd") End Sub Test de werking. In plaats van een ToolTip, of naast een ToolTip, kun je ook gebruik maken van een HelpProvider. Terwijl een ToolTip de informatie toont als de muisaanwijzer over het besturingselement glijdt, moet je, om de informatie van de HelpProvider zichtbaar te maken, het besturingselement in runtime selecteren en op F1 drukken. Een HelpProvider wordt meestal gebruikt om iets uitgebreidere hulpinformatie te geven.
VVKSO
Werkgroep handel
Programmeren met .NET 103
Voeg een HelpProvider hpvInformatie toe. Voeg de volgende code toe aan de voorgaande procedure. hpvInformatie.SetHelpString(txtLeeftijd, "Vul je exacte leeftijd in (geheel getal)") hpvInformatie.SetHelpString(txtNaam, "Vul je familienaam in, gevolgd door je voornaam") hpvInformatie.SetHelpString(txtDatum, "Formaat: jjjj-mm-dd") Test de werking.
3.8
Oefeningen
1
Maak een formulier om een naam, een bedrag (geheel getal) en een rekeningnummer in te vullen. Controleer de invoer. (patroon voor een rekeningnummer: \d\d\d-\d\d\d\d\d\d\d-\d\d; de twee laatste cijfers moeten gelijk zijn aan de rest bij deling door 97 van het getal gevormd door de 10 andere cijfers, als die rest 0 is, moeten de twee laatste cijfers 97 zijn).
2
Voorzie de al gemaakte oefeningen van validatie, exception handling en hulp.
VVKSO
Werkgroep Handel
Programmeren met .NET 104
3.9
Overzicht
3.9.1
Exception handling
Elke methode van het .NET Framework is zo ontworpen dat ze een exception werpt (throws) zodra zich een fout of een anomalie voordoet. Een exception wordt opgevangen in een Try…Catch… End Try blok. Try … Catch Code om de exception op te vangen End Try Wens je meer informatie te kennen over een exception, dan kun je in het catch-statement een exception-object als argument definiëren. Dit exception-object moet van type System.Exception of van een afgeleide klasse zijn. Try … Catch excUitzondering as Exception Code om de exception op te vangen End Try Als je met meerdere type exceptions rekening wilt houden, dan maak je best gebruik van een meervoudig exception-handlersblok, dit wil zeggen één blok met meerdere onmiddellijk opeenvolgende catch-statements horend bij één enkel Try-statement. De volgorde is belangrijk.
3.9.2
Validation
Voor de invoer van gegevens in een Windows toepassing worden meestal formulieren g ebruikt. De besturingselementen op zo'n formulier hebben allemaal de eigenschap CausesValidation en herkennen de gebeurtenis Validating. Dit kun je gebruiken om de invoer te controleren. Als de waarde van de eigenschap CausesValidation False is, dan worden de gebeurtenissen Validating en Validated onderdrukt. De gebeurtenis Validating treedt op bij het verlaten van het besturingselement, de gebeurtenis Validated treedt op na de gebeurtenis Validating.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 105
4
Object Oriented Programming
4.1
Object Gericht Werken
Er zijn veel verschillende programmeertalen. Ze hebben een hele evolutie ondergaan (zie bvb. http://nl.wikipedia.org/wiki/Programmeertaal). De manier van programmeren of programmeerstijl is ook geëvolueerd. VB.NET is een object georiënteerde programmeertaal. Als je in je eigen programma’s dezelfde principes toepast, dan ben je bezig met OOP (Object Oriented Programming). In OOP staan objecten centraal. Je moet goed het verschil begrijpen tussen de begrippen object en klasse. Een klasse bevat de instructies om een object te creëren in het geheugen van de computer. Je kunt een klasse vergelijken met het plan van een huis en objecten met de huizen die volgens dat plan gebouwd worden. Eens een object gecreëerd is, staat het volkomen los van alle andere objecten. Het leidt een eigen leven. Belangrijk aan een object is dat data (gegevens - eigenschappen) en de operaties op die data (gedrag - methodes) in één geheel verwerkt zijn en dus ook als geheel behandeld worden. Objecten zijn de bouwstenen van een object georiënteerd programma. In een Windows applicatie is een formulier een dergelijke bouwsteen. Een formulier heeft een achtergrondkleur, een bepaalde grootte, … Deze karakteristieken worden eigenschappen (property) genoemd. Ze bepalen de status (state) van het object. Een formulier weet hoe het moet minimaliseren en maximaliseren en hoe het zijn grootte moet aanpassen als je de randen verschuift. Dit ingebouwde gedrag is geïmplementeerd als methodes. Je ‘praat’ met een object door een waarde aan een eigenschap te geven of op te vragen of door een methode op te roepen. Voorbeeld Project
Formulieren
Type
Windows Application
Doel
Objecten zijn onafhankelijk Modifier Shared
Extra
Application.Run
Moeilijkheid
**
Vorm
Oplossing
Probleemstelling Via een knop op een formulier wordt een nieuwe instantie van het formulier gecreëerd. Op de titelbalk van het formulier wordt weergegeven om het hoeveelste bijgemaakte object het gaat.
VVKSO
pagina 106 - Programmeren met .NET
Werkgroep Handel
Implementatie Public Class Formulier Inherits System.Windows.Forms.Form Windows Form Designer generated code Private Shared Aantal As Integer = 0 Private Sub btnNieuwFormulier_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNieuwFormulier.Click Dim frm As New Formulier Aantal += 1 frm.Text = "Formulier " & Aantal.ToString frm.Show() End Sub End Class
Modifier Shared
Een variabele die gedeclareerd wordt als Shared is beschikbaar voor alle objecten van een klasse. Hij behoort dus eerder tot de klasse zelf dan tot een object hiervan. Test het programma. Elk zo geopend formulier kan onafhankelijk verplaatst, vergroot, verkleind … worden. Sluit een willekeurig bijgemaakt formulier. Sluit het oorspronkelijke formulier. Alle nog openstaande formulieren worden automatisch gesloten.
Application object
In een Windows toepassing is er steeds 1 en slechts 1 (verborgen) methode Main() die gebruikt wordt om de toepassing te starten. (In Webtoepassingen vind je dit niet terug.) Als je zelf geen procedure Main schrijft, maakt de compiler er één. Shared Sub Main() Application.Run(New Form1) End Sub
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 107
Via de methode Main() wordt een instantie Dit gebeurt door de instructie New Form1().
aangemaakt
van
de
klasse
Form1.
Normaal verdwijnen alle variabelen en objecten wanneer aan het einde van hun bereik. De instructie Application.Run () zorgt er voor dat het formulier zichtbaar blijft (m.a.w. dat de instantie Form1 niet verdwijnt) en kijkt uit naar ‘messages’ van Windows zoals muisklikken en gegevensinvoer die bedoeld zijn voor het programma. Dit blijft duren tot het formulier gesloten wordt. Voeg een module toe aan het project en plaats hierin volgende procedure. Sub Main() Dim frm As New Formulier frm.BackColor = Color.Yellow Application.Run(frm) End Sub Als je zelf een procedure Main schrijft, wordt deze ook gebruikt, de compiler maakt er zelf geen. Pas het Startup object van het project aan: Sub Main. Test het programma.
4.2
Eenvoudig voorbeeld van OOP
In hoofdstuk 2 heb je een mini rekenmachine geprogrammeerd. Nu wordt hetzelfde probleem opgelost, maar nu met OO. Project
RekenwonderOO
Type
Windows Application
Doel
Object gericht werken
Extra Moeilijkheid
*
Vorm
Volledig uitgewerkt
Probleemstelling Ontwikkel een mini rekenmachine: in een formulier kunnen twee willekeurige getallen ingevoerd worden en kan een bewerking gekozen worden ( optelling, verschil, vermenigvuldiging, deling). Het resultaat van de bewerking op de ingevoerde getallen wordt getoond. Probleemanalyse en implementatie Klassen: Bewerking, frmRekenwonder Een klasse wordt vaak voorgesteld in een klassendiagram.
VVKSO
pagina 108 - Programmeren met .NET
Werkgroep Handel
Bewerking Bewerking +Getal1: Double +Getal2: Double
→
Naam van de klasse
→
Eigenschappen
→
Methodes
+Som: Double +Verschil: Double +Product: Double +Quotiënt: Double
Implementatie Public Class Bewerking Public Getal1, getal2 As Double Public Function Som() As Double Return Getal1 + getal2 End Function Public Function Verschil() As Double Return Getal1 - Getal2 End Function Public Function Product() As Double Return Getal1 * Getal2 End Function Public Function Quotiënt() As Double Return Getal1 / Getal2 End Function End Class Variabelen die in de declaratiesectie van een klasse als Public gedeclareerd worden, zijn eigenschappen van die klasse. Functies en procedures die Public gedeclareerd worden zijn methodes van de klasse. frmRekenwonder: eigenschappen Eigenschap
Waarde
Text
Rekenwonder
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 109
frmRekenwonder: besturingselementen
Besturingselement
Eigenschap
Waarde
lblGetal1
Text
Getal 1
txtGetal1
Text
leeg
lblGetal2
Text
Getal 2
txtGetal2
Text
leeg
grpBewerking
Text
Bewerking
rdbQuotient
Text
Quotient
rdbVerschil
Text
Verschil
rdbProduct
Text
Product
rdbSom
Text
Som
Checked
True
btnBereken
Text
Bereken
lblResultaat
Text
leeg
Autosize
True
frmRekenwonder: procedures btnBereken_Click (Handles btnBereken.Click) Object
Gebeurtenis
Doel
btnBereken
Click
- Resultaat berekenen - Resultaat tonen
VVKSO
pagina 110 - Programmeren met .NET
Werkgroep Handel
Inplementatie Private Sub btnBereken_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBereken.Click Dim objBewerking As New Bewerkin Dim strBewerking As String Try objbewerking.Getal1 = CDbl(txtGetal1.Text) objBewerking.Getal2 = CDbl(txtGetal2.Text) Select Case True Case rdbSom.Checked strBewerking = "Som: " & objBewerking.Som.ToString Case rdbVerschil.Checked strBewerking = "Verschil: " & objBewerking.Verschil.ToString Case rdbProduct.Checked strBewerking = "Product: " & objBewerking.Product.ToString Case rdbQuotient.Checked strBewerking = "Quotiënt: " & objBewerking.Quotiënt.ToString End Select lblResultaat.Text = strBewerking Catch excUitzondering As InvalidCastException MessageBox.Show(excUitzondering.Message) Catch MessageBox.Show("Fout") End Try End Sub
4.3
Aanpasbaarheid
Projecten die volgens de principes van OO geprogrammeerd zijn, zijn makkelijker aanpasbaar. Stel dat het vorige voorbeeld moet aangepast worden en dat het resultaat van de bewerking moet afgerond worden op 2 cijfers na de komma. Dit vereist enkel een aanpassing van de klasse Bewerking. De klasse frmRekenwonder blijft ongewijzigd. Project: RekenwonderOO2 Public Class Bewerking Public Getal1, getal2 As Double Public Function Som() As Double Return Math.Round((Getal1 + getal2), 2) End Function Public Function Verschil() As Double Return Math.Round(Getal1 - getal2, 2) End Function Public Function Product() As Double Return Math.Round(Getal1 * getal2, 2) End Function Public Function Quotiënt() As Double Return Math.Round(Getal1 / getal2, 2) End Function End Class VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 111
Stel dat er nu een aanpassing aan de interface (het formulier) gevraagd wordt (zie onderstaand schermvoorbeeld). Nu moet enkel frmRekenwonder aangepast worden.
Project: RekenwonderOO3 In deze oplossing is gekozen om te werken met één gebeurtenisprocedure die reageert op de gebeurtenis Click van elk van de vier knoppen. Private Sub btnBereken_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSom.Click, btnVerschil.Click, btnProduct.Click, btnQuotient.Click Dim objBewerking As New Bewerking Dim strBewerking As String Try objBewerking.Getal1 = CDbl(txtGetal1.Text) objBewerking.getal2 = CDbl(txtGetal2.Text) Select Case CType(sender, Button).Text Case "Som" strBewerking = "Som: " & objBewerking.Som.ToString Case "Verschil" strBewerking = "Verschil: " & objBewerking.Verschil.ToString Case "Product" strBewerking = "Product: " & objBewerking.Product.ToString Case "Quotiënt" strBewerking = "Quotiënt: " & objBewerking.Quotiënt.ToString End Select lblResultaat.Text = strBewerking Catch excUitzondering As InvalidCastException MessageBox.Show(excUitzondering.Message) Catch MessageBox.Show("Fout") End Try End Sub
4.4
Eigenschappen
In voorgaande voorbeelden zijn de eigenschappen van de klassen gedefinieerd als variabelen op klasse-niveau. Het is beter om hiervoor de speciale ‘functie’ Property te gebruiken. Bij het lezen van de eigenschap wordt het Get-blok uitgevoerd, bij het schrijven het Set-blok. Project: RekenwonderOO4 Public Class Bewerking VVKSO
pagina 112 - Programmeren met .NET
Werkgroep Handel
Private dblGetal1, dblGetal2 As Double Public Property Getal1() As Double Get Return dblGetal1 End Get Set(ByVal Value As Double) dblGetal1 = Value End Set End Property Public Property Getal2() As Double Get Return dblGetal2 End Get Set(ByVal Value As Double) dblGetal2 = Value End Set End Property Public Function Som() As Double Return Math.Round((dblGetal1 + dblGetal2), 2) End Function Public Function Verschil() As Double Return Math.Round(dblGetal1 - dblGetal2, 2) End Function Public Function Product() As Double Return Math.Round(dblGetal1 * dblGetal2, 2) End Function Public Function Quotiënt() As Double Return Math.Round(dblGetal1 / dblGetal2, 2) End Function End Class
4.5
Verschillende soorten klassen
.NET kent 6 verschillende soorten van klassen: •
Standard Class
•
Structure
•
Module Class
•
Enumeration
•
Interface
•
Delegate
4.5.1
Standard Class
Een Standard Class of kortweg Class is de meest algemene klasse. Ze wordt gebruikt voor alle klassen die de bouwstenen vormen voor alle .NET types en bibliotheken (libraries). Standaard klassen zijn de basis van alle reference types.
Voorbeeld
System.Windows.Forms.Form
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 113
Declaratie van zelf gedefinieerde klasse
Public Class MijnKlasse … End Class
Gebruik
Om een class te instantiëren gebruik je de constructor New.
4.5.2
Structure
Structures zijn value types. Men spreekt wel eens van lichtgewicht klassen. Je kunt een instantie van een structure creëren zonder gebruik te maken van de New operator. (Een structure kan een constructor hebben, maar dat mag alleen als deze ook argumenten heeft.) Er is geen overerving voor structures. Een structure kan niet van een andere structure of van een class erven. Een structure erft echter wel van de base class Object. (Overerving wordt verder in deze cursus besproken). Hoewel een structure ook methodes kan hebben, wordt hij meestal gebruikt als een speciaal datatype dat bestaat uit een combinatie van andere datatypes.
Voorbeeld
System.Drawing.Point
Declaratie van zelf gedefinieerde structure
Public Structure Coördinaat Public X, Y, Z As Integer End Structure
Gebruik
Zoals elke andere Value Type (New niet nodig voor instantiëring).
4.5.3
Class Module
Een Class module of kortweg module is een speciale klasse waar alle variabelen en procedures impliciet als Shared gedeclareerd worden. D.w.z. het gaat om procedures die niet afhangen van een instantie van de klasse. Een module wordt typisch gebruikt als verzameling van code (functies, procedures) die ergens anders, onafhankelijk van een object, toegepast worden.
Voorbeeld
Microsoft.VisualBasic.Strings
Declaratie van zelf gedefinieerde module
Public Module MijnModule … End Module
VVKSO
pagina 114 - Programmeren met .NET
Werkgroep Handel
Gebruik
De Public gedeclareerde variabelen, procedures en functies kunnen overal rechtstreeks gebruikt worden. Er worden geen instanties van een module gecreëerd.
4.5.4
Enumeration
Enums of opsommingen bevatten numerieke constanten zoals Integers, Shorts, Longs en Bytes. Ze worden gebruikt om code beter leesbaar te maken.
Voorbeeld
Extra
System.Drawing.FontStyle
4.5.5
Interface
Interfaces definiëren een set van eigenschappen, methoden en gebeurtenissen, net als classes. Maar in tegenstelling tot een class bevat een interface geen implementatie. Een class die een interface implementeert, moet ieder aspect van deze class implementeren, precies zoals in de interface is vastgelegd.
V oorbeeld
Extra
System.IFormatProvider
4.5.6
Delegate
Een Delegate wordt vaak gedefinieerd als een Type Safe Pointer. Dit type klasse wordt hier niet verder besproken.
4.6
OOP toepassen
Als je een Windows Application project maakt, maak je altijd tenminste één eigen klasse, namelijk het formulier dat als interface met de gebruiker dienst doet. Voor toepassingen met meerdere formulieren maak je per formulier een dergelijke klasse. Of je nog andere klassen moet definiëren hangt van de toepassing af. Het is altijd het beste om bij elkaar horende zaken bijeen te houden in een klasse en om de interface met de gebruiker (formulier) apart te houden van de eigenlijke logica van het programma. In die zin is de programmeerstijl van RekenwonderOO4 beter dan die van Rekenwonder. OOP bewijst echter vooral zijn nut bij grotere toepassingen en bij toepassingen die regelmatig moeten aangepast worden. Hierna volgen enkele grotere toepassingen die geprogrammeerd worden in OOP.
4.7
Array, ArrayList, Collection
Een Array, ArrayList en een Collection object zijn geordende verzamelingen van objecten. Ze bieden een interessante manier om met één enkel object te verwijzen naar een reeks objecten. Ze komen alle drie uit een ander namespace: VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 115
System.Array System.Collections.ArrayList System.VisualBasic.Collection. Het grootste verschil tussen een Array en een ArrayList, is dat een Array uit objecten van hetzelfde type moet bestaan en een ArrayList niet. Een ArrayList en een Collection hebben ongeveer dezelfde doel, maar de functionaliteit van een ArrayList is veel groter . Je creëert een Collection en een ArrayList op dezelfde manier als een ander object: Dim X As New Collection Dim X As New ArrayList Eens dat je een Collectie of een ArrayList gecreëerd hebt, kun je items toevoegen met de Add methode en ze weer verwijderen met de Remove methode. Met de Item methode refereer je naar een specifiek object uit de collection, met een For Each...Next statement doorloop je de hele verzameling. Opmerking In een Array en een ArrayList begint de index van 0 te tellen, in een Collection van 1.
Voorbeeld Project
Gerechten
Type
Windows Application
Doel
- OOP - Structure
Extra
Keuzelijsten
Moeilijkheid
*
Vorm
Volledig uitgewerkt
Probleemstelling In een formulier kunnen maaltijden worden ingevuld (voorgerecht, hoofdgerecht, nagerecht en prijs). Bij een druk op een knop worden de ingevoerde maaltijden getoond.
VVKSO
pagina 116 - Programmeren met .NET
Werkgroep Handel
Probleemanalyse en implementatie Klassen: frmInvoerGerechten, frmGerechtenlijst, Maaltijd Maaltijd Maaltijd Voorgerecht: String Hoofdgerecht: String Nagerecht: String Prijs: Single
Een maaltijd bestaat steeds uit een voor-, hoofd-, nagerecht en prijs. Hiervoor maak je gebruik van een structure. Implementatie Public Structure Maaltijd Public Public Public Public
Voorgerecht As String Hoofdgerecht As String Nagerecht As String Prijs As Single
End Structure frmInvoerGerechten: besturingselementen
Besturingselement
Eigenschap
Waarde
txtVoorgerecht
Text
leeg
txtHoofdgerecht
Text
leeg
txtNagerecht
Text
leeg
txtPrijs
Text
leeg
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 117
Besturingselement
Eigenschap
Waarde
btnNieuwGerecht
Text
Nieuw gerecht
btnLijst
Text
Lijst
frmInvoergerechten: procedures Private Sub btnNieuwGerecht_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNieuwGerecht.Click 'Maaltijd toevoegen End Sub Private Sub btnLijst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLijst.Click 'Maaltijd toevoegen 'lstboxen opvullen 'Formulier frmGerechtenLijst tonen End Sub Vermits in beide gebeurtenisprocedures ‘Maaltijd toevoegen’ voorkomt, wordt de code hiervoor in een aparte procedure geplaatst. Private Sub MaaltijdToevoegen() 'Maaltijd toevoegen aan collectie 'Formulier frmInvoerGerechten klaarmaken voor nieuwe invoer End Sub Implementatie Private Maaltijden As New Collection Private Sub btnNieuwGerecht_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNieuwGerecht.Click 'Maaltijd toevoegen aan collectie MaaltijdToevoegen() End Sub Private Sub btnLijst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLijst.Click Dim frm As New frmGerechtenlijst Dim obj As Maaltijd 'Maaltijd toevoegen aan collectie MaaltijdToevoegen() 'lstboxen opvullen For Each obj In Maaltijden frm.lstVoorgerecht.Items.Add(obj.Voorgerecht) frm.lstHoofdgerecht.Items.Add(obj.Hoofdgerecht) frm.lstNagerecht.Items.Add(obj.Nagerecht) frm.lstPrijs.Items.Add(obj.Prijs.ToString("c")) Next 'formulier Invoergerechten tonen frm.ShowDialog() End Sub Private Sub MaaltijdToevoegen() VVKSO
pagina 118 - Programmeren met .NET
Werkgroep Handel
Dim objMaaltijd As New Maaltijd 'Maaltijd toevoegen objMaaltijd.Voorgerecht = txtVoorgerecht.Text objMaaltijd.Hoofdgerecht = txtHoofdgerecht.Text objMaaltijd.Nagerecht = txtNagerecht.Text objMaaltijd.Prijs = CSng(txtPrijs.Text) Maaltijden.Add(objMaaltijd) 'Formulier klaarmaken voor nieuwe invoer txtVoorgerecht.Clear() txtHoofdgerecht.Clear() txtNagerecht.Clear() txtPrijs.Clear() txtVoorgerecht.Focus() End Sub Hoe wordt de prijs geformatteerd in frmGerechtenlijst? frmGerechtenlijst: besturingselementen
Uitbreiding Voeg Exception handling toe. Pas het project zo aan dat je kunt ingeven en tonen of koffie inbegrepen is in de prijs.
4.8
Uitgewerkte voorbeelden
In deze paragraaf worden drie projecten volledig OOP uitgewerkt. Kies er één uit en bestudeer het.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 119
4.8.1
Puzzel
Project
Puzzel
Type
Windows Application
Doel
Bereik van variabelen OOP Verfijning
Extra
Operator Mod, Timer, Menu, Collection
Moeilijkheid
***
Vorm
Volledig uitgewerkt
Opgave Maak een digitale schuifpuzzel. Opmerking: het is zeker niet de bedoeling dat je volgend voorbeeld zelfstandig kunt oplossen. Probeer wel de opgegeven code te begrijpen. Beantwoord zorgvuldig de vraagjes die over de code gesteld worden. Het voorbeeld is stapsgewijze opgebouwd: eerst wordt het fundamentele probleem opgelost, daarna worden verfraaiingen toegevoegd. Probleemstelling en implementatie Er worden 16 knoppen gebruikt, waarvan er één zwart is om het lege vak aan te duiden. Een klik op een knop naast het lege vak ‘verschuift’ de knop naar dit lege vak. De knoppen verschuiven niet echt, maar de opschriften worden omgewisseld.
Probleemanalyse en implementatie Klassen: Schuifbord, frmPuzzel Schuifbord
VVKSO
pagina 120 - Programmeren met .NET
Werkgroep Handel
Schuifbord + Blokjes: Collection + Leegvakje: Integer (Alleen lezen) + Schudden + Verschuif: Boolean De eigenschap Blokjes is de verzameling van alle knoppen van het schuifbord. Hier word voor een Collection gekozen i.p.v. een ArrayList omdat de index van een Collection start bij 1 en het gemakkelijk is om de nummering van de blokjes hiermee te laten corresponderen. De eigenschap Leegvakje bevat de index, in de Blokjes collectie, van de knop die het lege vak voorstelt. De methode Schudden verplaatst de (opschriften van de) knoppen in willekeurige volgorde. De methode Verschuif heeft een knop als parameter. Ze verwisselt de knop met het lege vak als de knop verschuifbaar is, d.w.z. als de knop grenst aan het lege vak. Implementatie Public Class Schuifbord Public Blokjes As New Collection Public Leegvakje As Integer = 0 Public Sub Schudden() Dim intIndex As Integer Dim objRandom As New Random '500 keer twee willekeurige naast elkaar gelegen blokjes verwisselen Dim i As Integer For i = 1 To 500 intIndex = objRandom.Next(1, 15) Dim btn1, btn2 As Button Dim strNummer As String btn1 = CType(Blokjes(intIndex), Button) btn2 = CType(Blokjes(intIndex + 1), Button) strNummer = btn1.Text btn1.Text = btn2.Text btn2.Text = strNummer Next 'Leegvakje bepalen Dim btn As Button For intIndex = 1 To 16 btn = CType(Blokjes(intIndex), Button) If btn.Text = String.Empty Then btn.BackColor = Color.Black Leegvakje = intIndex Else btn.BackColor = Color.Yellow End If Next End Sub Leg in woorden uit welk mechanisme gebruikt wordt om de blokjes te ‘schudden’. Waarvoor wordt de variabele strNummer gebruikt in de code?
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 121
Public Dim Dim Dim
Function Verschuif(ByRef pKnop As Button) as Boolean btnTeVerplaatsen, btnLeeg As Button intIndex As Integer blnVerschuifbaar As Boolean
'Index in de collectie blokjes bepalen intIndex = Positie(pKnop) 'Nagaan of het blokje verschuifbaar is Select Case intIndex Mod 4 Case 0 If intIndex = Leegvakje + 1 Or intIndex = Leegvakje - 4 Or intIndex = Leegvakje + 4 Then blnVerschuifbaar = True End If Case 1 If intIndex = Leegvakje - 1 Or intIndex = Leegvakje - 4 Or intIndex = Leegvakje + 4 Then blnVerschuifbaar = True End If Case Else If intIndex = Leegvakje - 1 Or intIndex = Leegvakje + 1 Or intIndex = Leegvakje - 4 Or intIndex = Leegvakje + 4 Then blnVerschuifbaar = True End If End Select 'Het blokje verschuiven als het verschuifbaar is If blnVerschuifbaar Then 'Opschriften verwisselen btnTeVerplaatsen = CType(Blokjes(intIndex), Button) btnLeeg = CType(Blokjes(Leegvakje), Button) btnLeeg.Text = btnTeVerplaatsen.Text btnTeVerplaatsen.Text = String.Empty 'Leegvakje aanpassen btnTeVerplaatsen.BackColor = Color.Black btnLeeg.BackColor = Color.Yellow Leegvakje = intIndex
End If Return blnVerschuifbaar End Sub
Private Function Positie(ByRef pKnop As Button) As Integer Dim intIndex As Integer For intIndex = 1 To 16 If Blokjes(intIndex).Equals(pKnop) Then Return intIndex End If Next End Function End Class Leg in algemene bewoordingen uit wat de code in functie Verschuif doet. Waarvoor dient de functie Positie? Opmerkingen
VVKSO
pagina 122 - Programmeren met .NET
Werkgroep Handel
De functie Positie heeft als modifier Private. Ze is enkel binnen de klasse Schuifbord bruikbaar. Het is geen methode van deze klasse. Een ArrayList bevat een methode IndexOf(Object) die de index in de collectie van het object geeft. Pas de eigenschap leegvakje aan zo dat de eigenschap alleen lezen wordt. frmPuzzel frmPuzzel: eigenschappen Eigenschap
Waarde
FormBorderStyle
FixedToolWindow
MaximizeBox
False
MinimizeBox
False
Text
Puzzel
frmPuzzel: besturingselementen
Besturingselement
Eigenschap
Waarde
Alle knoppen
Name
Respectievelijk: Button1, Button2, …
Size
50,50
BackColor
Yellow
Text
Respectievelijk: 1, 2, … (laatste knop: leeg)
Het formulier bevat een menu met 2 items: Nieuw spel en Sluiten. Via menuoptie Nieuw spel wordt een nieuw spel gestart. VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 123
frmPuzzel: procedures Object
Gebeurtenis
Doel
frmPuzzel
Load
De knoppen van het formulier worden in juiste volgorde toegevoegd aan de collectie Blokjes
NieuwSpel
Click
Schudden van schuifbord
Sluiten
Click
Formulier sluiten
Alle knoppen
Click
Verschuif aangeklikte knop
Implementatie Private objSchuifbord As New Schuifbord Private Sub Puzzel_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load objSchuifbord.Blokjes.Add(Button1) objSchuifbord.Blokjes.Add(Button2) objSchuifbord.Blokjes.Add(Button3) objSchuifbord.Blokjes.Add(Button4) objSchuifbord.Blokjes.Add(Button5) objSchuifbord.Blokjes.Add(Button6) objSchuifbord.Blokjes.Add(Button7) objSchuifbord.Blokjes.Add(Button8) objSchuifbord.Blokjes.Add(Button9) objSchuifbord.Blokjes.Add(Button10) objSchuifbord.Blokjes.Add(Button11) objSchuifbord.Blokjes.Add(Button12) objSchuifbord.Blokjes.Add(Button13) objSchuifbord.Blokjes.Add(Button14) objSchuifbord.Blokjes.Add(Button15) objSchuifbord.Blokjes.Add(Button16) objSchuifbord.Schudden() End Sub Private Sub NieuwSpel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles NieuwSpel.Click objSchuifbord.Schudden() End Sub Private Sub Sluiten_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Sluiten.Click Me.Close() End Sub Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click, Button5.Click, Button6.Click, Button7.Click, Button8.Click, Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button14.Click, Button15.Click, Button16.Click Dim btnBlokje As Button btnBlokje = CType(sender, Button) objSchuifbord.Verschuif(btnBlokje) End Sub
VVKSO
pagina 124 - Programmeren met .NET
Werkgroep Handel
Uitbreiding 1 (uitgewerkt) Pas het project aan zo dat er een boodschap verschijnt als alle vakjes de juiste positie hebben. Stap 1 ReadOnly eigenschap EindSituatie toevoegen aan de klasse Schuifbord. Public ReadOnly Property EindSituatie() As Boolean Get
Dim intIndex As Integer Dim btn As Button
intIndex = 1 For Each btn In Blokjes If btn.Text <> intIndex.ToString Then Exit For Else intIndex += 1 End If Next If intIndex = 16 Then Return True Else Return False End If End Get End Property Stap 2 Telkens bij het verplaatsen van een blokje de eigenschap EindSituatie controleren. Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click, Button5.Click, Button6.Click, Button7.Click, Button8.Click, Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button14.Click, Button15.Click, Button16.Click Dim btnBlokje As Button btnBlokje = CType(sender, Button) objSchuifbord.Verschuif(btnBlokje) 'Ga na of doel bereikt is If objSchuifbord.EindSituatie Then MessageBox.Show("Proficiat! Je hebt gewonnen!") End If End Sub Uitbreiding 2 (uitgewerkt) Pas het project aan zo dat als het spel gewonnen is, het aantal zetten en de gebruikte tijd weergegeven wordt. Stap 1 Klasse Spel toevoegen.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 125
Spel + Duur: Double + AantalZetten: Integer + Start + Einde
Public Class Spel Private StartTijd As DateTime Private EindTijd As DateTime Public AantalZetten As Integer = 0 Public Sub Start() StartTijd = Now End Sub Public Sub Einde() EindTijd = Now End Sub Public ReadOnly Property Duur() As Double Get Return Int(DateTime.op_Subtraction(EindTijd, StartTijd).TotalSeconds) End Get End Property End Class Stap 2 De klasse gebruiken in frmPuzzel. Private objSchuifbord As New Schuifbord Private objSpel As Spel Private Sub mnuNieuwSpel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuNieuwSpel.Click NieuwSpelStarten() End Sub Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click, Button5.Click, Button6.Click, Button7.Click, Button8.Click, Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button14.Click, Button15.Click, Button16.Click Dim btnBlokje As Button 'Verschuif het blokje btnBlokje = CType(sender, Button) 'Verhoog het aantal zetten als het blokje verschuift If objSchuifbord.Verschuif(btnBlokje) Then objSpel.AantalZetten += 1 End If 'Ga na of doel bereikt is If objSchuifbord.EindSituatie Then objSpel.Einde()
VVKSO
pagina 126 - Programmeren met .NET
Werkgroep Handel
MessageBox.Show("Proficiat! Je hebt gewonnen!" & vbCrLf & "Aantal zetten: " & objSpel.AantalZetten.ToString & vbCrLf & "Aantal seconden: " & objSpel.Duur.ToString, "Puzzel", MessageBoxButtons.OK) objSpel = Nothing End If End Sub Private Sub Puzzel_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Knoppen op formulier toekennen aan blokjes van het schuifbord objSchuifbord.Blokjes.Add(Button1) objSchuifbord.Blokjes.Add(Button2) objSchuifbord.Blokjes.Add(Button3) objSchuifbord.Blokjes.Add(Button4) objSchuifbord.Blokjes.Add(Button5) objSchuifbord.Blokjes.Add(Button6) objSchuifbord.Blokjes.Add(Button7) objSchuifbord.Blokjes.Add(Button8) objSchuifbord.Blokjes.Add(Button9) objSchuifbord.Blokjes.Add(Button10) objSchuifbord.Blokjes.Add(Button11) objSchuifbord.Blokjes.Add(Button12) objSchuifbord.Blokjes.Add(Button13) objSchuifbord.Blokjes.Add(Button14) objSchuifbord.Blokjes.Add(Button15) objSchuifbord.Blokjes.Add(Button16) 'Het eerste spel klaarzetten NieuwSpelStarten() End Sub Private Sub NieuwSpelStarten() objSchuifbord.Schudden() objSpel = New Spel objSpel.Start() End Sub Uitbreiding 3 (uitgewerkt) Pas het project aan zo dat op elk moment het aantal al gedane zetten en de verlopen tijd van het huidige spel weergegeven worden. Via een menuoptie (Extra, Overzicht) kan het kleinste aantal zetten en de kortste tijdsduur (gemeten vanaf de eerste zet), die nodig waren om een spel succesvol te beëindigen in de huidige spelsessie, geraadpleegd worden. Ook het aantal spelletjes in de sessie wordt weergegeven in het overzicht. Stap 1 Het formulier frmPuzzel aanpassen: nieuwe menuopties toevoegen.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 127
Om de spelduur weer te geven is een timer nodig: tmrTijd (Enabled: False, Interval: 1000). De timer moet beginnen lopen bij de eerste zet. Stap 2 Een klasse (structure) bijmaken voor de sessie. Sessie + Aantal Spelletjes + MinAantalZetten + MinDuur
Public Structure Sessie Public AantalSpelletjes As Integer Public MinAantalZetten As Integer Public MinDuur As Integer End Structure Stap 3 De nodige procedures van frmPuzzel aanpassen en bijmaken. Private objSchuifbord As New Schuifbord Private objSpel As Spel Private objSessie As Sessie Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click, Button5.Click, Button6.Click, Button7.Click, Button8.Click, Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button14.Click, Button15.Click, Button16.Click Dim btnBlokje As Button 'Verschuif het blokje btnBlokje = CType(sender, Button)
VVKSO
pagina 128 - Programmeren met .NET
Werkgroep Handel
'Verhoog het aantal zetten als het blokje verschuift If objSchuifbord.Verschuif(btnBlokje) Then objSpel.AantalZetten += 1 lblAantalZetten.Text = objSpel.AantalZetten.ToString If objSpel.AantalZetten = 1 Then objSpel.Start() objSessie.AantalSpelletjes += 1 tmrTijd.Enabled = True End If End If 'Ga na of doel bereikt is If objSchuifbord.EindSituatie Then objSpel.Einde() tmrTijd.Enabled = False MessageBox.Show("Proficiat! Je hebt gewonnen!" & vbCrLf & "Aantal zetten: " & objSpel.AantalZetten.ToString & vbCrLf & "Aantal seconden: " & objSpel.Duur.ToString, "Puzzel", MessageBoxButtons.OK)
End Sub
'Overzicht aanpassen If objSessie.MinAantalZetten = 0 Or objSpel.AantalZetten < objSessie.MinAantalZetten Then objSessie.MinAantalZetten = objSpel.AantalZetten End If If objSessie.MinDuur = 0 Or objSpel.Duur < objSessie.MinDuur Then objSessie.MinDuur = CInt(objSpel.Duur) End If objSpel = Nothing End If
Private Sub mnuOverzicht_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOverzicht.Click MessageBox.Show("Aantal spelletjes: " _ & objSessie.AantalSpelletjes.ToString & vbCrLf _ & "Minimum aantal zetten: " & objSessie.MinAantalZetten & vbCrLf _ & "Kortste tijd (seconden): " & objSessie.MinDuur) End Sub Private Sub tmrTijd_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrTijd.Tick lblSpelduur.Text = (CInt(lblSpelduur.Text) + 1).ToString End Sub Private Sub NieuwSpelStarten() objSchuifbord.Schudden() objSpel = New Spel lblAantalZetten.Text = "0" lblSpelduur.Text = "0" tmrTijd.Enabled = False End Sub Pas het project aan, zo dat ook het aantal gewonnen spelletjes getoond wordt. Uitbreiding 4 (uitgewerkt) Pas het project aan zodat de gebruiker via een menuoptie (Extra, Kleur) de kleur van de knoppen kan bepalen.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 129
Stap 1 Het formulier frmPuzzel uitbreiden met de nieuwe menuoptie. Om de gebruiker de kleur te laten kiezen voeg je een ColorDialog besturingselement toe: clrdlgKleuren. Stap 2 Aanpassing klasse Schuifbord: toevoeging van de eigenschap Kleur. Private colKleur As Color Public Property Kleur() As Color Get Return colKleur End Get Set(ByVal Value As Color) colKleur = Value KleurAanpassen() End Set End Property Private Sub KleurAanpassen() Dim btn As Button
End Sub
For Each btn In Blokjes btn.BackColor = colKleur Next CType(Blokjes(Leegvakje), Button).BackColor = Color.Black
Stap 3 Aanpassing van de methodes Verschuif en Schudden van de klasse Schuifbord. Public Sub Schudden() … 'Leegvakje bepalen Dim btn As Button For intIndex = 1 To 16 btn = CType(Blokjes(intIndex), Button) If btn.Text = String.Empty Then btn.BackColor = Color.Black Leegvakje = intIndex Else btn.BackColor = Kleur End If Next End Sub Public Function Verschuif(ByRef pKnop As Button) As Boolean … 'Het blokje verschuiven als het verschuifbaar is If blnVerschuifbaar Then … 'Leegvakje aanpassen btnTeVerplaatsen.BackColor = Color.Black btnLeeg.BackColor = Kleur Leegvakje = intIndex End If Return blnVerschuifbaar VVKSO
pagina 130 - Programmeren met .NET
Werkgroep Handel
End Function Stap 4 Aan frmPuzzel de procedure toevoegen die moet uitgevoerd worden bij het klikken op de nieuwe menuoptie. Private Sub mnuKleur_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuKleur.Click If clrdlgKleuren.ShowDialog() = DialogResult.OK Then objSchuifbord.Kleur = clrdlgKleuren.Color End If End Sub Uitbreiding Maak gebruik van dit project om zelf je eigen spelletje te maken. Hieronder volgen enkele mogelijkheden. •
Plaats op de blokjes een deel van een tekening of foto. Door te verschuiven moet de tekening of foto terug samengesteld worden.
•
Pas het spelletje aan zodat het gespeeld kan worden door twee spelers. Eén speler plaats een zin op het schuifbord (één woord per blokje). De andere speler moet proberen door te verschuiven een grammaticaal correcte zin te bekomen.
•
Maak een schuifpuzzel van 5 op 5 blokjes.
Gebruik je fantasie om het spelletje zo leuk mogelijk te maken.
4.8.2
Kasticket
Project
Kasticket
Type
Windows Application
Doel
Bereik van variabelen OOP (properties als public variabelen)
Vorm
Volledig uitgewerkt
Opgave Het project simuleert de werking van een kassa in een winkel van bloemen en planten. De producten worden beperkt tot de aangeboden terras- en oranjerieplanten. Probleemstelling Enkel Jan, Tine en Nele mogen de kassa bedienen. De aangeboden planten worden via een afbeelding weergegeven. Zolang het definitieve kasticket niet wordt weergegeven moeten eventuele verstrooidheidfouten bij de invoer kunnen gecorrigeerd worden.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 131
Bij elke invoer of correctie moet meteen het bedrag van de verkoop en het totale bedrag van het kasticket worden weergegeven. Wordt de invoer afgesloten dan moet een overzichtelijk kasticket worden weergegeven. Vereiste gegevens op dit ticket: datum, naam van kassabediende, lijst van verkochte planten met hoeveelheid, eenheidsprijs en bedrag en het totale bedrag van het kasticket. Probleemanalyse en implementatie Klassen: Verkoper, Verkoop, Product, VerkochtProduct, frmKassa, frmAanmelding, frmKasticket De module Main wordt gebruikt om het project te starten (Sub Main). Verkoper +Naam: String +Login: String +Wachtwoord: String +Inloggen(): String Product +Naam: String +Eenheidsprijs: String +Afbeelding: String
VerkochtProduct +Artikel: Product +Aantal: Integer +Prijs():Single
Verkoop +Kassabediener: String +Tijd: DateTime +VerkochteProducten: ArrayList van VerkochtProduct +TotalePrijs(): Single +Kasticket afdrukken() Product Omdat de klasse Product geen methodes bezit, wordt ze gedeclareerd als een Structure. Public Structure Product Dim Naam As String VVKSO
pagina 132 - Programmeren met .NET
Werkgroep Handel
Dim EenheidsPrijs As Single Dim Afbeelding As String End Structure VerkochtProduct Public Class VerkochtProduct Public Artikel As Product Public Aantal As Integer Public Function Prijs() As Single Return Artikel.EenheidsPrijs * Aantal End Function End Class Verkoop Public Class Verkoop Public Kassabediener As String Public Tijd As DateTime Public VerkochteProducten As New ArrayList Public Function TotalePrijs() As Single Dim obj As VerkochtProduct Dim sngTotaal As Single = 0 For Each obj In VerkochteProducten sngTotaal += obj.Prijs Next Return sngTotaal End Function Public Sub KasticketTonen() Dim frm As New frmKasticket frm.HuidigeKassaBediener = Kassabediener frm.HuidigeTijd = Now frm.HuidigeVerkochteProducten = VerkochteProducten frm.HuidigeTotalePrijs = TotalePrijs() frm.ShowDialog() End Sub End Class Verkoper Public Class Verkoper Public Naam As String = String.Empty Public Login As String = String.Empty Public Wachtwoord As String Public Function Inloggen() As String Dim frm As New frmAanmelding frm.ShowDialog() Return frm.NaamAangemeldeVerkoper End Function End Class frmKassa frmKassa: eigenschappen Eigenschap
VVKSO
Waarde
Werkgroep Handel
Programmeren met .NET - pagina 133
Text
leeg
MinimizeBox
False
MaximizeBox
False
Besturingselement
Belangrijkste Eigenschappen
Waarde
cboPlanten
Text
leeg
picPlant
Image
none
SizeMode
AutoSize
Text
€
TextAlign
MiddleLeft
Text
1
TextAlign
Center
btnInvoeren
Text
Invoeren
lstTicketplanten
SelectionMode
One
lstBerekening
SelectionMode
None
lstBedrag
SelectionMode
None
RightToLeft
Yes
Text
leeg
TextAlign
MiddleRight
Text
Wis geselecteerd product
lblEprijs
txtAantal
lblTotaalBedrag
btnWis VVKSO
pagina 134 - Programmeren met .NET
Werkgroep Handel
Besturingselement
btnTicket
Belangrijkste Eigenschappen
Waarde
Visible
False
Text
Kasticket afdrukken
Enabled
False
Implementatie Private Sub frmKassa_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Aanmelden verkoper 'Titelbalk formulier invullen 'De vaste gegevens van de producten invoeren 'cboPlanten opvullen 'Eerste plant weergeven in keuzelijst End Sub Private Sub cboPlanten_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboPlanten.SelectedIndexChanged 'De geselecteerde plant opzoeken in de collectie Planten 'Afbeelding en prijs van het geselecteerde product tonen End Sub Private Sub btnInvoeren_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInvoeren.Click 'Gekozen plant toevoegen aan verkoop 'Lijsten op het formulier aanvullen met gegevens verkocht product 'Totaal bedrag weergeven 'Aantal terug de standaardwaarde 1 geven 'Knop kasticket beschikbaar stellen End Sub Private Sub btnWis_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWis.Click 'De plant in de drie lijsten wissen 'Verwijderen uit verkoop 'Totale prijs herberekenen 'Wisknop terug uitschakelen End Sub Private Sub btnTicket_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTicket.Click 'Formulier frmkasticket weergeven 'Formulier klaarmaken voor nieuwe ingave 'Eerste plant weergeven 'Items uit de lijsten wissen 'Totaalbedrag wissen 'Wisknop onzichtbaar instellen 'Kasticketknop onbeschikbaar stellen 'Nieuwe verkoop starten End Sub VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 135
Private Sub lstPlant_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPlant.SelectedIndexChanged 'Wisknop ter beschikking stellen End Sub Implementatie Private Planten As New ArrayList 'Aangeboden producten Private objGeselecteerdProduct As Product Private objVerkoop As New Verkoop 'Huidige verkoop Private Sub frmKassa_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim objVerkoper As New Verkoper 'Huidige kassabediener 'Aanmelden verkoper objVerkoop.Kassabediener = objVerkoper.Inloggen() 'Als frmAanmelding gesloten is zonder correcte aanmelding, toepassing afsluiten If objVerkoop.Kassabediener = String.Empty Then Me.Close() Else 'Titelbalk formulier invullen Me.Text = "Kassa: u wordt bediend door " & objVerkoop.Kassabediener 'De vaste gegevens van de producten invoeren InitialisatiePlanten() 'cboPlanten opvullen Dim obj As Product For Each obj In Planten cboPlanten.Items.Add(obj.Naam) Next
End Sub
'eerste plant weergeven in keuzelijst cboPlanten.Text = cboPlanten.Items(0).ToString End If
Private Sub cboPlanten_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboPlanten.SelectedIndexChanged 'De geselecteerde plant opzoeken in de collectie Planten objGeselecteerdProduct = CType(Planten(cboPlanten.SelectedIndex), Product) 'Afbeelding en prijs van het geselecteerde product tonen picPlant.Image = Bitmap.FromFile("..\images\" & objGeselecteerdProduct.Afbeelding) lblEPrijs.Text = objGeselecteerdProduct.EenheidsPrijs.ToString("c") End Sub Private Sub btnInvoeren_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInvoeren.Click Dim objVerkochtProduct As New VerkochtProduct VVKSO
pagina 136 - Programmeren met .NET
Werkgroep Handel
'Gekozen plant toevoegen aan verkoop objVerkochtProduct.Artikel = objGeselecteerdProduct objVerkochtProduct.Aantal = CInt(txtAantal.Text) objVerkoop.VerkochteProducten.Add(objVerkochtProduct) 'Lijsten op het formulier aanvullen met gegevens verkocht product lstPlant.Items.Add(objVerkochtProduct.Artikel.Naam) lstBerekening.Items.Add(objVerkochtProduct.Artikel.EenheidsPrijs. ToString("c") & " x " & txtAantal.Text) lstbedrag.Items.Add(objVerkochtProduct.Prijs ToString("c")) 'Totaal bedrag weergeven lblTotaal.Text = objVerkoop.TotalePrijs.ToString("c")) 'Aantal terug de standaardwaarde 1 geven txtAantal.Text = "1" 'Knop kasticket beschikbaar stellen btnTicket.Enabled = True End Sub Private Sub btnWis_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWis.Click Dim intIndex As Integer intIndex = CInt(lstPlant.SelectedIndex) 'De plant in de drie lijsten wissen lstbedrag.Items.RemoveAt(intIndex) lstBerekening.Items.RemoveAt(intIndex) lstPlant.Items.RemoveAt(intIndex) 'Verwijderen uit verkoop objVerkoop.VerkochteProducten.RemoveAt(intIndex) 'Totale prijs herberekenen lblTotaal.Text = objVerkoop.TotalePrijs.ToString("c")
End Sub
'Wisknop terug uitschakelen btnWis.Enabled = False
Private Sub btnTicket_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTicket.Click Dim obj As VerkochtProduct 'formulier frmkasticket weergeven objVerkoop.KasticketTonen() 'Formulier klaarmaken voor nieuwe ingave 'eerste plant weergeven cboPlanten.Text = CStr(cboPlanten.Items(0)) 'items uit de lijsten wissen lstPlant.Items.Clear() lstBerekening.Items.Clear() lstbedrag.Items.Clear() 'totaalbedrag wissen lblTotaal.Text = String.Empty 'wisknop onzichtbaar instellen btnWis.Enabled = False 'kasticketknop onbeschikbaar stellen VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 137
btnTicket.Enabled = False 'Nieuwe verkoop starten objVerkoop = Nothing objVerkoop = New Verkoop End Sub Private Sub lstPlant_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPlant.SelectedIndexChanged 'Wisknop ter beschikking stellen btnWis.Enabled = True End Sub Private Sub InitialisatiePlanten() Dim pl As New Product pl.Naam = "Mimosa" pl.EenheidsPrijs = 1.5 pl.Afbeelding = "mimosa.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Anthemis" pl.EenheidsPrijs = 3 pl.Afbeelding = "anthemis.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Olijf op stam" pl.EenheidsPrijs = 15.2 pl.Afbeelding = "olijfopstam.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Callistemon" pl.EenheidsPrijs = 5.2 pl.Afbeelding = "callistemon.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Bougainvillea" pl.EenheidsPrijs = 11.6 pl.Afbeelding = "Bougainvillea.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Phoenix" pl.EenheidsPrijs = 6.95 pl.Afbeelding = "Phoenix.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Pelargonium" pl.EenheidsPrijs = 2.8 pl.Afbeelding = "Pelargonium.jpg" Planten.Add(pl) pl = New Product VVKSO
pagina 138 - Programmeren met .NET
Werkgroep Handel
pl.Naam = "Calla" pl.EenheidsPrijs = 7.95 pl.Afbeelding = "Calla.jpg" Planten.Add(pl) pl = New Product pl.Naam = "Washingtonia" pl.EenheidsPrijs = 9 pl.Afbeelding = "Washingtonia.jpg" Planten.Add(pl) End Sub frmAanmelden frmAanmelden:eigenschappen Eigenschap
Waarde
Text
Aanmelding kassa
MinimizeBox
False
MaximizeBox
False
NaamAangemeldeVerkoper
Bijgevoegde eigenschap
Besturingselement
Eigenschap
Waarde
txtNaam
Text
leeg
txtWachtwoord
Text
leeg
PasswordChar * btnOK
Text
OK
Implementatie Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click 'Controle op juistheid van ingevoerde gegevens 'foutmelding weergeven als invoer niet juist is End Sub Public NaamAangemeldeVerkoper As String Private Gebruikers As New ArrayList 'Bestaande verkopers
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 139
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click Dim obj As Verkoper Dim blnCorrecteAanmelding As Boolean Dim blnFout As Boolean 'Foutmelding als geen login is ingevoerd If txtLogin.Text.Equals(String.Empty) Then MessageBox.Show("Naam is vereist!", "INVOERCONTROLE", MessageBoxButtons.OK, MessageBoxIcon.Warning) txtLogin.Focus() blnFout = True End If 'Foutmelding als geen wachtwoord is ingevoerd If txtWachtwoord.Text.Equals(Text.Empty) Then MessageBox.Show("Wachtwoord is vereist!", "INVOERCONTROLE", MessageBoxButtons.OK, MessageBoxIcon.Warning) txtWachtwoord.Focus() blnFout = True End If If Not blnFout Then 'Controle op juistheid van ingevoerde gegevens For Each obj In Gebruikers If obj.Login = txtLogin.Text And obj.Wachtwoord = txtWachtwoord.Text Then blnCorrecteAanmelding = True Me.NaamAangemeldeVerkoper = obj.Naam Me.Close() End If Next
End Sub
'foutmelding weergeven als invoer niet juist is If Not blnCorrecteAanmelding Then MessageBox.Show("Foutieve aanmelding. Probeer opnieuw!", "CONTROLE", MessageBoxButtons.OK, MessageBoxIcon.Stop) 'aanmeldingsgegevens wissen txtWachtwoord.Text = String.Empty txtLogin.Text = String.Empty 'schermcursor weer klaarzetten om nieuwe naam in te voeren txtLogin.Focus() End If End If
Private Sub frmAanmelding_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Initialisatie van de bestaande gebruikers() Dim gebr As New Verkoper gebr.Naam = "Jan" gebr.Login = "jan" gebr.Wachtwoord = "p1r" Gebruikers.Add(gebr) gebr = New Verkoper gebr.Naam = "Tine" gebr.Login = "tine" gebr.Wachtwoord = "pe2" Gebruikers.Add(gebr) gebr = New Verkoper VVKSO
pagina 140 - Programmeren met .NET
Werkgroep Handel
End Sub
gebr.Naam = "Nele" gebr.Login = "nele" gebr.Wachtwoord = "3er" Gebruikers.Add(gebr)
frmKasticket frmKasticket eigenschappen Eigenschap
Waarde
Text
Overzicht
MinimizeBox
False
MaximizeBox
False
HuidigeKassaBediener
Toegevoegde eigenschap
HuidigeTijd
Toegevoegde eigenschap
HuidigeVerkochteProducten
Toegevoegde eigenschap
HuidigeTotalePrijs
Toegevoegde eigenschap
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 141
Besturingselement
Eigenschap
Waarde
txtTicket
Text
KASTICKET
TextAlign
Right
Multiline
True
ScrollBars
Vertical
ReadOnly
True
Private Sub frmKasticket_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
'Aankoopgegevens invullen op kasticket 'Kasticket afsluiten
Implementatie Public HuidigeKassaBediener As String Public HuidigeTijd As DateTime Public HuidigeVerkochteProducten As ArrayList Public HuidigeTotalePrijs As Single Private Sub frmKasticket_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load txtTicket.AppendText(vbCrLf) txtTicket.AppendText(vbCrLf & HuidigeTijd.ToLongDateString & " om " & HuidigeTijd.ToShortTimeString & "u" & vbCrLf) txtTicket.AppendText(vbCrLf) 'Aankoopgegevens invullen op kasticket Dim obj As VerkochtProduct For Each obj In HuidigeVerkochteProducten txtTicket.AppendText(obj.Artikel.Naam & " " & obj.Artikel.EenheidsPrijs.ToString("c") & " x " & obj.Aantal & " = " & obj.Prijs.ToString("c")) txtTicket.AppendText(vbCrLf) Next txtTicket.AppendText(vbCrLf & "Totaal bedrag : " & HuidigeTotalePrijs.ToString("c")) 'Kasticklet afsluiten txtTicket.AppendText(vbCrLf) txtTicket.AppendText(vbCrLf & "U werd bediend door " & HuidigeKassaBediener) txtTicket.AppendText(vbCrLf) txtTicket.AppendText(vbCrLf & "Bedankt en tot weerzien") End Sub
4.9
User Control
Project
Rekentest
Type
Windows Application
VVKSO
pagina 142 - Programmeren met .NET
Werkgroep Handel
Doel
OOP User Control, DataTable
Extra
Panel control
Moeilijkheid
***
Vorm
Volledig uitgewerkt
Probleemstelling Maak een Windows applicatie waarmee het optrekken en aftrekken van getallen, tot een opgegeven bovengrens, kan ingeoefend worden. De oefeningen worden aangeboden in reeksen van 10. De gebruiker kiest vooraf de bewerking: +, - of gemengd. Na verbetering van de oefeningen krijgt de gebruiker de kans om de fouten te verbeteren. De behaalde scores per reeks en per (verbeter)poging worden weergegeven. Probleemanalyse en implementatie Klassen: frmOefeningen, Oefening, Beurt Alle interactie met de gebruiker gebeurt via een instantie van het formulier frmOefeningen. Uit de probleemstelling kun je nog twee andere belangrijke klassen afleiden: Beurt en Oefening.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 143
Beurt Beurt +reeks : Integer +poging : Integer +score : Integer +maximum : Integer +bewerking : String
De klasse Beurt wordt gebruikt voor de gegevens van het overzicht van de resultaten. Alle eigenschappen zijn lezen en schrijven.
Implementatie Public Class Beurt Dim intScore As Integer Dim intPoging As Integer Dim intReeks As Integer Dim intMaximum As Integer Dim strBewerking As String Public Property Score() As Integer Get Return intScore End Get Set(ByVal Value As Integer) intScore = Value End Set End Property Public Property Poging() As Integer Get Return intPoging End Get Set(ByVal Value As Integer) intPoging = Value End Set End Property Public Property Reeks() As Integer Get Return intReeks End Get Set(ByVal Value As Integer) intReeks = Value End Set End Property Public Property Maximum() As Integer Get Return intMaximum End Get Set(ByVal Value As Integer) intMaximum = Value End Set End Property Public Property Bewerking() As String Get Return strBewerking End Get Set(ByVal Value As String) strBewerking = Value End Set End Property End Class VVKSO
pagina 144 - Programmeren met .NET
Werkgroep Handel
Oefening Oefening +getal1 : Integer +getal2 : Integer +resultaat : Integer +operator : String +maximum : Integer -bepaalOperator() -genereerGetal1() -genereerGetal2() -bepaalResultaat() +new()
Een oefening bestaat uit twee te genereren getallen en een bewerking (operator). Als de getallen en de bewerking gekend zijn, kan hiermee de uitkomst (resultaat) bepaald worden. getal1, getal2 en resultaat moeten alleen kunnen gelezen worden.
Oefening: procedures Procedure: New Type
sub
Bereik
public
Argumenten
strType: type bewerking intMax: bovengrens van getallen
Doel
constructor
Algoritme New(strType, intMax) eigenschap maximum ← intMax bepaalOperator(strTypr) genereerGetal1 genereerGetal2 bepaalResultaat Procedure: BepaalOperator Type
sub
Bereik
private
Argumenten
strType waarde: "+", "-" of "gemengd"
Doel
bepalen van de operator
Algoritme Selectiestructuur. Als de waarde "gemengd" is zal de bewerking willekeurig gekozen worden.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 145
Procedure: GenereerGetal1 Type
sub
Bereik
private
Argumenten
geen
Doel
genereren van het eerste getal
Algoritme Het te genereren getal mag niet groter zijn dan het opgegeven maximum. Procedure: GenereerGetal2 Type
sub
Bereik
private
Argumenten
geen
Doel
genereren van het tweede getal
Algoritme genereerGetal2 operator="+" Ja
Nee
te genereren getal moet kleiner zijn dan maximum - getal1
te genereren getal moet kleiner zijn dan getal1
Procedure: BepaalResultaat Type
sub
Bereik
private
Argumenten
geen
Doel
uitkomst bepalen
Algoritme bepaalResultaat operator="+" Ja
Nee
resultaat ← getal1 + getal2
VVKSO
pagina 146 - Programmeren met .NET
resultaat ← getal1 - getal2
Werkgroep Handel
Implementatie Friend Class Oefening Private intGetal1 As Integer Private intGetal2 As Integer Private intResultaat As Integer Private strOperator As String Private intMaximum As Integer Private intWillekeurigGetal As New Random Public Sub New(ByVal strType As String, ByVal intMax As Integer) intMaximum = intMax BepaalOperator(strType) GenereerGetal1() GenereerGetal2() BepaalResultaat() End Sub Public ReadOnly Property Getal1() As Integer Get Return intGetal1 End Get End Property Public ReadOnly Property Getal2() As Integer Get Return intGetal2 End Get End Property Public ReadOnly Property Resultaat() As Integer Get Return intResultaat End Get End Property Public Property Operator() As String Get Return strOperator End Get Set(ByVal Value As String) strOperator = Value End Set End Property Public Property Maximum() As Integer Get Return intMaximum End Get Set(ByVal Value As Integer) intMaximum = Value End Set End Property Private Sub BepaalOperator(ByVal strType As String) Select Case strType Case "+" strOperator = "+" Case "-" strOperator = "-" Case Else If Rnd() < 0.5 Then strOperator = "+" Else strOperator = "-" End If End Select
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 147
End Sub Private Sub GenereerGetal1() intGetal1 = intWillekeurigGetal.Next(0, intMaximum) End Sub Private Sub GenereerGetal2() If strOperator = "+" Then intGetal2 = intWillekeurigGetal.Next(0, intMaximum - intGetal1) Else intGetal2 = intWillekeurigGetal.Next(0, intGetal1) End If End Sub Private Sub BepaalResultaat() If strOperator = "+" Then intResultaat = intGetal1 + intGetal2 Else intResultaat = intGetal1 - intGetal2 End If End Sub End Class
4.10
DataGrid, DataTable
De resultaten van de verschillende pogingen, kunnen op verschillende manieren weergegeven worden. Je kunt bijvoorbeeld een tekstvak gebruiken waarvan je de eigenschap Multiline op True hebt gezet, of één of meer keuzelijsten. Je verkrijgt een mooie weegave met een DataGrid. Een DataGrid geeft gegevens weer in tabelvorm. De gegevens worden met de DataGrid verbonden via de eigenschap DataSource. De DataSource is meestal van het type DataTable. Je kunt een DataTable zien als een tabel, m.a.w. een DataTable is opgebouwd uit rijen: DataRows. In het voorbeeld wordt hiervan gebruik gemaakt. frmOefening frmOefening:eigenschappen Eigenschap
Waarde
Text
Oefeningen op som en verschil
VVKSO
pagina 148 - Programmeren met .NET
Werkgroep Handel
frmOefening: besturingselementen
Besturingselement
Eigenschap
Waarde
txtGrootsteGetal
Text
20
GroupBox1
Text
leeg
rdbPlus
Checked
True
btnNieuweReeks
Text
Nieuwe reeks
btnVerbeteren
Text
Verbeteren
Enabled
False
Text
Nieuwe poging
Enabled
False
btnStoppen
Text
Stoppen
dgrResultaat
ReadOnly
True
pnlOefeningen
rdbMin rdbGemengd
btnNieuwePoging
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 149
pnlOefening is een paneel. Hierop komen de oefeningen. Door de besturingselementen voor de oefeningen op een paneel te plaatsen, worden ze als geheel apart aanspreekbaar (pnlOefening.Controls). Elke oefening moet er hetzelfde uitzien. Je definieert hiervoor een User Control. Voeg een User Control ctrOefening (bestandsnaam) toe aan het project (Solution Explorer: Add, Add User Control in het snelmenu van het project). Noem de control zelf Oef.
Besturingselement
Eigenschap
Waarde
lblGetal1
Text
leeg
lblOp
Text
leeg
lblGetal2
Text
leeg
lblGelijkheidsteken
Text
=
txtResultaat
Text
leeg
Voor je dit nieuwe besturingselement kunt gebruiken, moet je eerst een build maken van het project. Doe dit. Als je frmOefening activeert in Design, zie je in Tools een nieuwe Tab My User Controls. Hierin staat de nieuwe control.
Plaats 10 dergelijke controls op pnlOefeningen in frmOefening.
VVKSO
pagina 150 - Programmeren met .NET
Werkgroep Handel
frmOefening: procedures Object
Gebeurtenis
Doel
frmOefening
Load
- een instantie van Beurt maken - DataTable dgrResultaat
btnNieuweReeks
Click
maken
voor
DataSource
Click
Datagrid
- bewerking en maximum bepalen - oefeningen op het formulier besturingselementen activeren
btnVerbeteren
van
plaatsen
en
nodige
- oefeningen verbeteren en gepaste actie nemen - score tonen
btnNieuwePoging
Click
- poging met 1 verhogen - nodige besturingselementen activeren
btnStoppen
Click
- formulier sluiten
Implementatie Private objBeurt As Beurt Private dttResultaat As DataTable Private Sub btnNieuweReeks_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNieuweReeks.Click Dim Dim Dim Dim
intGrootsteGetal As Integer strBewerking As String objOef As Oefening ctrlOef As Oef
'Bewerking en maximum bepalen intGrootsteGetal = CInt(Val(txtGrootsteGetal.Text)) Select Case True Case btnPlus.Checked strBewerking = "+" Case btnMin.Checked strBewerking = "-" Case Else strBewerking = "+/-" End Select 'Oefeningen op formulier plaatsen en opmaak aanpassen For Each ctrlOef In Me.pnlOefeningen.Controls objOef = New Oefening(strBewerking, intGrootsteGetal) ctrlOef.lblGetal1.Text = objOef.Getal1.ToString ctrlOef.lblOp.Text = objOef.Operator ctrlOef.lblGetal2.Text = objOef.Getal2.ToString ctrlOef.Tag = objOef.Resultaat 'Bijhouden voor gebruik bij het verbeteren ctrlOef.txtResutaat.Text = String.Empty ctrlOef.txtResutaat.BackColor = Color.Yellow ctrlOef.txtResutaat.Enabled = True ctrlOef.Visible = True objOef = Nothing Next objBeurt.Reeks += 1 VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 151
objBeurt.Poging = 1 objBeurt.Bewerking = strBewerking objBeurt.Maximum = intGrootsteGetal
End Sub
btnNieuwePoging.Enabled = False btnVerbeteren.Enabled = True pnlOefeningen.Enabled = True
Private Sub btnVerbeteren_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnVerbeteren.Click Dim ctrlOef As Oef 'Oefeningen verbeteren en gepaste actie nemen objBeurt.Score = 0 For Each ctrlOef In pnlOefeningen.Controls If ctrlOef.txtResutaat.Text = ctrlOef.Tag.ToString Then ctrlOef.txtResutaat.BackColor = Color.LightGreen ctrlOef.txtResutaat.Enabled = False objBeurt.Score += 1 Else ctrlOef.txtResutaat.BackColor = Color.Red End If Next ScoreTonen() btnVerbeteren.Enabled = False btnNieuwePoging.Enabled = True pnlOefeningen.Enabled = False End Sub Private Sub ScoreTonen() Dim objRij(4) As Object 'DataTable opvullen met gegevens huidife beurt objRij(0) = objBeurt.Reeks objRij(1) = objBeurt.Poging objRij(2) = objBeurt.Score objRij(3) = objBeurt.Maximum objRij(4) = objBeurt.Bewerking dttResultaat.Rows.Add(objRij) dgrResultaat.DataSource = dttResultaat End Sub Private Sub frmOefening_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load objBeurt.Reeks = 0 'DataTable als DataSource voor dgrResultaat dttResultaat = New DataTable dttResultaat.Columns.Add("Reeks") dttResultaat.Columns.Add("Poging") dttResultaat.Columns.Add("Score") dttResultaat.Columns.Add("GG") dttResultaat.Columns.Add("+/-") End Sub
VVKSO
pagina 152 - Programmeren met .NET
Werkgroep Handel
Private Sub btnNieuwePoging_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNieuwePoging.Click objBeurt.Poging += 1 btnVerbeteren.Enabled = True btnNieuwePoging.Enabled = False pnlOefeningen.Enabled = True End Sub Private Sub btnStoppen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStoppen.Click Me.Close() End Sub Waar wordt de DataTable die als DataSource van de DataGrid moet dienen aangemaakt? Waarom daar? Waar wordt het DataTable object gedeclareerd? Waarom? Hoe wordt een kolom toegevoegd aan een DataTable? Hoe wordt een rij toegevoegd aan een DataTable? Uitbreiding Gebruik je fantasie om dit programma aantrekkelijker te maken voor de doelgroep: kinderen van het eerste en tweede leerjaar.
4.11
Een Class Library maken
In de hiervoor besproken voorbeelden werden zelfgedefinieerde klassen telkens in een apart bestand geplaatst. Dit is niet echt nodig, maar biedt het voordeel dat ze gemakkelijk op te vissen zijn in andere projecten: je voegt ze gewoon toe in Solution Explorer via Add, Add Existing Item. Wil je klassen op een professionelere manier beschikbaar stellen, dan maak je een Class Library. Projecten van dit type kunnen meerdere codebestanden met klassen bevatten. Het spreekt vanzelf dat dit enkel nuttig is als je grotere projecten gaat maken. Voorbeeld Open een nieuw project Persoonsgegevens, kies als type een Class Library.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 153
Maak in het project een klasse Persoon. Persoon +Voornaam: String +Familienaam: String +Geboortedatum: Date +Geslacht: String +Leeftijd: Integer (Readonly)
Public Class Persoon Dim Dim Dim Dim
strVoornaam As String strFamilienaam As String dteGeboortedatum As Date strGeslacht As String
Public Property Voornaam() As String Get Return strVoornaam End Get Set(ByVal Value As String) strVoornaam = Value End Set End Property Public Property Familienaam() As String Get Return strFamilienaam End Get Set(ByVal Value As String) strFamilienaam = Value End Set End Property Public Property Geboortedatum() As Date VVKSO
pagina 154 - Programmeren met .NET
Werkgroep Handel
Get
Return dteGeboortedatum End Get Set(ByVal Value As Date) dteGeboortedatum = Value End Set End Property Public Property Geslacht() As String Get Return strGeslacht End Get Set(ByVal Value As String) If Value.ToUpper = "M" Then strGeslacht = "M" Else strGeslacht = "V" End If End Set End Property Public ReadOnly Property Leeftijd() As Integer Get Dim intGeboortejaar, intGeboortemaand, intGeboortedag As Integer Dim intJaar, intMaand, intDag As Integer Dim intAantaljaar As Integer intGeboortejaar = dteGeboortedatum.Year intGeboortemaand = dteGeboortedatum.Month intGeboortedag = dteGeboortedatum.Day intJaar = Date.Today.Year intMaand = Date.Today.Month intDag = Date.Today.Day intAantaljaar = intJaar - intGeboortejaar If intMaand < intGeboortemaand Or (intMaand = intGeboortemaand And intDag < intGeboortedag) Then intAantaljaar -= 1 End If Return intAantaljaar End Get End Property End Class Maak een Build van het project (zet de Active Solution Configuration op Release).
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 155
De Class Library Persoonsgegevens.dll is aangemaakt in de map Bin van de map Persoonsgegevens.
4.12
Een zelfgemaakte Class Library gebruiken
Als je klassen uit een Class Library wilt gebruiken in een project, dan moet je deze library toevoegen aan de References van het project. Maak een Windows Application project Personen. Voeg in Solution Explorer een reference toe naar Persoonsgegevens.dll.
De klasse Persoon is nu beschikbaar voor het project. Probeer dit uit in het codevenster.
4.13
Oefeningen
1
Maak een klasse voor een zwembad. Een zwembad heeft een lengte, breedte en diepte. Een zwembad kan tot 20 cm van de bovenrand gevuld worden met water. Via de klasse moet o.a. de maximale hoeveelheid water bekomen worden (in liter). Test de klasse.
2
Maak een klasse voor een softwareproject. Voorzie o.a. projectnummer, doel, opdrachtgever, uitvoerders (een of meerdere personeelsleden), manuur, prijs per uur, startdatum, (berekende) einddatum, (berekende) prijs. Maak voor de uitvoerders gebruik van de klasse Persoon in Persoonsgegevens.dll. Test de klasse.
3
Maak een programma (Lingo) om Lingo te spelen. In het spelletje voor twee spelers, moet de speler zo snel mogelijk een door de tegenspeler ingegeven 5 letterwoord raden. Beide spelers wisselen elkaar af bij het raden en ingeven van het woord.
4
Na elke poging krijgt de speler een aanduiding over de door hem gebruikte letters: groene achtergrond: juiste letter, juiste positie; rode achtergrond: juiste letter maar foute positie (er wordt geen rekening gehouden met het meerdere keren voorkomen van een letter in het te raden woord of het opgegeven woord). Als een letter niet voorkomt in het te raden woord, blijft de achtergrondkleur ongewijzigd. De speler krijgt maximaal 5 beurten om het woord te raden. De score is als volgt:
VVKSO
pagina 156 - Programmeren met .NET
Werkgroep Handel
VVKSO
Werkgroep Handel
Geraden bij poging
Punten
1
20
2
15
3
10
4
5
5
3
Programmeren met .NET - pagina 157
4.14
Overzicht
4.14.1
Een klasse definiëren
Een klasse bevat de definities van een object. Op basis daarvan worden de objecten gemaakt. Elk object dat men op die manier maakt is een instantie van de klasse. De klasse definieer je uiteraard buiten een procedure of functie.
Voorbeeld
Public Class Persoon End Class Hierdoor kan je een instantie maken van die klasse: Dim objTestpersson As New persoon
4.14.2
Eigenschappen
Eigenschappen van een klasse worden gedeclareerd via een Get- en een Set procedureblok. Elke Set-clausule geeft een waarde aan de eigenschap. Elke Get-clausule leest de waarde van de eigenschap.
Voorbeeld Public Property X () As Integer Get Return intX End Get Set(ByVal Value As Integer) intX = Value End Set End Property
Een alleen-lezen eigenschap laat je voorafgaan door het sleutelwoord ReadOnly en je definieert alleen een Get-blok. Public ReadOnly Property X () As Integer Een alleen-schrijven eigenschap laat je voorafgaan door het sleutelwoord WriteOnly en definieert alleen een Set-blok.
je
Public WriteOnly Property X () As Integer
4.14.3
Methoden
Methoden zijn subroutines of functies die binnen de klasse gedefinieerd zijn met het sle utelwoord Public.
VVKSO
pagina 158 - Programmeren met .NET
Werkgroep Handel
5
Belangrijke kenmerken van OOP Polymorfisme Overerving Constructor/destructor
5.1
Herbruikbaarheid
Een van de belangrijkste voordelen van OOP is de herbruikbaarheid van de code. In dit verband zijn twee begrippen belangrijk: overerving en polymorfisme.
5.1.1
Overerving
Overerving (inheritance) is een belangrijk principe van OO. Volgens dit principe kan men nieuwe klassen maken, gebaseerd op al bestaande klassen, door methodes en eigenschappen te wijzigen en/of toe te voegen. Dit resulteert in een hiërarchische structuur (ook wel boomstructuur genoemd) die zeer groot kan worden. Persoon +voornaam +familienaam +geboortedatum
Leerling +afdeling +klas
Personeel +loon
OnderwijzendPers
AdminstratiefPers
+vakken
+bureel
+geeftPunten()
OnderhoudsPers +poetst()
Leerlingen en personeel hebben (onder andere) als gemeenschappelijke eigenschappen dat ze allemaal een naam en een geboortedatum hebben. Deze gemeenschappelijke eigenschappen worden aan de klasse Persoon toegekend. Personeelsleden hebben een loon, leerlingen (spijtig genoeg) niet. Leerlingen behoren wel tot een bepaalde afdeling en zitten in een bepaalde klas. De eigenschappen in de subklassen Leerling en Personeel zijn extra eigenschappen. De eigenschappen van de superklasse Persoon zijn ook gekend in de subklasse. De klasse Personeel heeft op haar beurt ook weer subklassen. Elke subklasse bevat specifieke eigenschappen en methoden die enkel van toepassing zijn op die klasse. In dit voorbeeld is de klasse Persoon de "basisklasse" (base class) of superklasse en de klasse Leerling de "afgeleide klasse" (derived class) of subklasse. Men gebruikt ook de terminologie "parent class" en "child class". Behalve het toekennen van extra eigenschappen en functies, bestaat ook de mogelijkheid om een functie van de hogergelegen klasse in de hiërarchie te herdefiniëren. Dit principe noemt men overriding en wordt later besproken. Voorbeeld VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 159
Elk nieuw formulier dat je aanmaakt erft de eigenschappen en methodes System.Windows.Forms.Form. Dit wordt bij de definitie van de klasse aangegeven.
van
Public Class frmMijnFormulier Inherits System.Windows.Forms.Form … End Class
5.1.2
Polymorfisme
Polymorfisme betekent dat eenzelfde methode (of eigenschap) meerdere vormen kan hebben. Een methode van een basisklasse kan bijvoorbeeld in een afgeleide klasse ‘overschreven’ worden. D.w.z. dezelfde naam wordt behouden, maar de inhoud, de code is anders. Polymorfisme kan ook optreden binnen één klasse: een procedure met dezelfde naam komt meerdere keren voor, maar het aantal of het type van de argumenten is anders. Met polymorfisme, word je vaak geconfronteerd in de IDE. Als je de naam van een methode intikt, dan kun je die op verschillende manieren gebruiken door andere argumenten mee te geven. Voorbeeld De methode Show van MessageBox heeft 12 vormen.
5.2
System.Object
De klassenbibliotheken van CLR zijn georganiseerd in een hiërarchische boomstructuur van namespaces. De top (root) hiervan is de System namespace die diverse klassen bevat waaronder de gegevenstypes. Alle klassen van System bevinden zich in Mscorlib.dll en kunnen gebruikt worden door alle .NET applicaties. Je kunt deze klassen gebruiken zoals ze zijn of je kunt er afgeleide klassen mee maken. Aan de top van alle standaard klassen staat de klasse Object. In VB.NET erven alle standaard klassen van Object, inclusief de klassen die je zelf maakt. Object is m.a.w. de ultieme base class of superklasse. Het is de enige klasse in het .NET Framework die niet erft van een andere klasse. De methodes van Object zijn daarom automatisch beschikbaar in alle klassen van VB.NET, ook in de klassen die je zelf maakt. VVKSO
pagina 160 - Programmeren met .NET
Werkgroep Handel
Methode
Beschikbaarheid
Beschrijving
Equals
Public
Neemt een ander object als argument en geeft een Boolean terug die aangeeft of beide objecten gelijk zijn (zelfde instanties van een klasse).
GetHashCode
Public
Geeft een integer hash code die de waarde van het object representeert. (Wordt bijvoorbeeld gebruikt als key bij het toevoegen van het object aan een ArrayList.) Twee identieke objecten hebben dezelfde code.
Finalize
Protected
Destructor
MemberwiseClone
Protected
Creëert een kopie van het object.
GetType
Public
Geeft een instantie van System.Type terug
ToString
Public
Geeft een string-representatie van het object.
De modifier Protected betekent: enkel beschikbaar in child classes. E
Voorbeeld
X
Project
KlasseObject
T
Type
Windows applicatie
R
Doel
Nieuwe klasse erft van System.Object
A
Extra Moeilijkheid
**
Vorm
Oplossing
Probleemstelling Klassen: Form1, KindKlasse Je maakt een klasse KindKlasse met twee eigenschappen: Familienaam en Voornaam en één methode Kloon. Die een kloon maakt van het object. Op een formulier toon je waarden van alle eigenschappen/methoden van een instantie van de klasse, ook de geërfde.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 161
Probleemanalyse en implementatie Klassen: Kindklasse, Form1 Kindklasse +Familienaam: String +Voornaam: String +Kloon() Implementatie KindKlasse Public Class KindKlasse Public Voornaam As String Public Familienaam As String Public Function Kloon() As KindKlasse Return CType(MyBase.MemberwiseClone(), KindKlasse) End Function End Class Form1 Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click Dim obj As New Kindklasse Dim objKloon As KindKlasse obj.Voornaam = txtVoornaam.Text obj.Familienaam = txtFamilienaam.Text VVKSO
pagina 162 - Programmeren met .NET
Werkgroep Handel
txtToString.Text = obj.ToString txtGetType.Text = obj.GetType.ToString txtgetHashcode.Text = obj.GetHashCode.ToString
End Sub
objKloon = obj.Kloon() txtkloonVoornaam.Text = objKloon.Voornaam txtKloonFamilienaam.Text = objKloon.Familienaam txtGelijk.Text = obj.Equals(objKloon).ToString
Voeg aan KindKlasse de volgende methode toe. Public Overrides Function ToString() As String Return String.Concat(Familienaam, Space(1), Voornaam) End Function Test opnieuw. Het sleutelwoord Overrides duidt aan dat je de oorspronkelijke methode van Object wijzigt in de afgeleide klasse. Wijzig het statement objKloon = obj.Kloon() in objKloon = obj Waarom krijg je nu de waarde True in txtGelijk?
5.3
Overerving: uitgewerkt voorbeeld
Project
Personen
Type
Windows Application
Doel
OOP: overerving
Extra
Listbox
Moeilijkheid
**
Vorm
Volledig uitgewerkt
Probleemstelling Familienaam, Voornaam, geboortedatum en klas van een leerling worden ingevoerd. Bij het drukken op de knop OK wordt de volledige naam van de leerling, gevolg door zijn leeftijd, ingevuld in de kolom van de aangeduide klas.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 163
Probleemanalyse en implementatie Klassen: Leerling, frmKlassen Leerling De klasse Persoon, beschikbaar in Persoonsgegevens (in project aan Persoonsgegevens.dll toevoegen) kan uitgebreid worden tot een klasse Leerling.
References,
Persoon +Voornaam: String +Familienaam: String +Geboortedatum: Date +Geslacht: String +Leeftijd: Integer (Readonly)
Leerling + Klas: String +VolledigeNaam: String (ReadOnly)
VVKSO
pagina 164 - Programmeren met .NET
Werkgroep Handel
Implementatie Public Class Leerling Inherits Persoonsgegevens.Persoon Private strKlas As String Public Property Klas() As String Get Return strKlas End Get Set(ByVal Value As String) strKlas = Value End Set End Property Public ReadOnly Property VolledigeNaam() As String Get Return MyBase.Familienaam & Strings.Space(1) & MyBase.Voornaam End Get End Property End Class frmKlassen
Implementatie Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click Dim objLeerling As New Leerling Dim strGegevens As String 'Gegevens opvragen objLeerling.Voornaam = txtVoornaam.Text objLeerling.Familienaam = txtFamilienaam.Text objLeerling.Geboortedatum = CType(txtgeboortedatum.Text, Date) objLeerling.Klas = cboKlas.SelectedItem.ToString 'Textboxen leegmaken txtVoornaam.Clear() txtFamilienaam.Clear() txtgeboortedatum.Clear()
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 165
'weg te schrijven tekst samenstellen strGegevens = objLeerling.VolledigeNaam & " (" & objLeerling.Leeftijd.ToString & " jaar)" 'Tekst in juiste kolom schrijven Select Case cboKlas.SelectedItem Case "6A" lst6A.Items.Add(strGegevens) Case "6B" lst6B.Items.Add(strGegevens) Case "6C" lst6C.Items.Add(strGegevens) End Select End Sub
5.4
Polymorfisme: uitgewerkte voorbeelden
Polymorfisme kan in VB.NET op verschillende manieren geïmplementeerd worden. In volgende voorbeelden worden twee verschillende manieren besproken: Overriding en Overloading.
5.4.1
Overriding
Project
Figuren0/Figuren1
Type
Windows Application
Doel
Polymorfisme : overriding
Extra
Werken met grafische objecten
Moeilijkheid
**
Vorm
Volledig uitgewerkt
Probleemstelling
Op een tekenblad wordt door een klik op de linkermuisknop een ellips of een rechthoek getekend afhankelijk van de keuze van de gebruiker. Vorm en kleur van de figuur zijn willekeurig.
VVKSO
pagina 166 - Programmeren met .NET
Werkgroep Handel
Probleemanalyse en implementatie Klassen: frmTekenen, Figuur, Rechthoek, Ellips Een ellips en een rechthoek zijn allebei figuren. Ze hebben gemeenschappelijke kenmerken: breedte, lengte, kleur en de positie op het tekenblad (gedefinieerd door de top). Bij een klik met de linkermuisknop moeten beide figuren getekend worden, maar de code die hiervoor gebruikt moet worden is voor beide figuren verschillend. Dit wordt weergegeven door volgende klasse hiërarchie. Figuur +Top +Breedte : Integer +Lengte : Integer +Kleur
Rechthoek +Teken()
Ellips +Teken()
Implementatie 1 (Figuren0) Public Class Figuur Public Top As Point Public Lengte As Integer Public Breedte As Integer Public Kleur As Color End Class Public Class Ellips Inherits Figuur Public Sub Teken(ByVal graOppervlak As System.Drawing.Graphics) Dim objPen As New Pen(MyBase.Kleur) graOppervlak.DrawEllipse(objPen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub End Class Public Class Rechthoek Inherits Figuur Public Sub Teken(ByVal graOppervlak As System.Drawing.Graphics) Dim objPen As New Pen(MyBase.Kleur) graOppervlak.DrawRectangle(objPen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub End Class Implementatie 2 (Figuren1) De klasse hiërarchie kan ook als volgt voorgesteld en geïmplementeerd worden.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 167
Figuur +Top +Breedte : Integer +Lengte : Integer +Kleur +Teken()
Rechthoek +Teken()
Ellips +Teken()
Klasse Figuur kan nog de base class worden van een aantal andere figuren. Al deze figuren zullen een methode Teken hebben. Het is gebruikelijk om dan in de base class een abstracte methode Teken te declareren, d.w.z. de naam wordt gedeclareerd, maar de methode heeft geen code. De eigenlijke code wordt ingegeven in de subklassen. Het voordeel hiervan is dat de corresponderende methode in alle subklassen dezelfde naam zal hebben. Public MustInherit Class Figuur Public Public Public Public
Top As Point Lengte As Integer = 100 Breedte As Integer = 100 Kleur As Color = Color.Black
Public MustOverride Sub Teken(ByVal graOppervlak As Graphics) End Class Public Class Ellips Inherits Figuur Public Overrides Sub Teken(ByVal graOppervlak As System.Drawing.Graphics) Dim objPen As New Pen(MyBase.Kleur) graOppervlak.DrawEllipse(objPen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub End Class Public Class Rechthoek Inherits Figuur Public Overrides Sub Teken(ByVal graOppervlak As System.Drawing.Graphics) Dim objPen As New Pen(MyBase.Kleur) graOppervlak.DrawRectangle(objPen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub End Class
VVKSO
pagina 168 - Programmeren met .NET
Werkgroep Handel
frmTekenen
frmTekenen: besturingselementen Besturingselement
Eigenschap
Waarde
picTekening
BackColor
White
rdbRechthoek
Checked
True
rdbEllips Implementatie Private pntPositie As Point Private Sub picTekening_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picTekening.MouseDown 'Positie van muisaanwijzer bepalen pntPositie.X = e.X pntPositie.Y = e.Y 'TekenFiguur If rdbRechthoek.Checked Then TekenRechthoek() Else TekenEllips() End If End Sub Private Function RandomRGBKleur() As Color Dim rnd As New Random Return Color.FromArgb(255, _ rnd.Next(0, 255), _ rnd.Next(0, 255), _ rnd.Next(0, 255)) End Function Private Function RandomGrootte(ByVal intMax As Integer) As Integer VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 169
Dim rnd As New Random Return rnd.Next(1, intMax) End Function Private Sub TekenRechthoek() Dim objRechthoek As New Rechthoek 'Figuur initialiseren With objRechthoek .Top = pntPositie .Breedte = RandomGrootte(picTekening.Width - pntPositie.X) .Lengte = RandomGrootte(picTekening.Height - pntPositie.Y) .Kleur = RandomRGBKleur()
End Sub
.Teken(picTekening.CreateGraphics) End With
Private Sub TekenEllips() Dim objEllips As New Ellips 'Figuur initialiseren With objEllips .Top = pntPositie .Breedte = RandomGrootte(picTekening.Width - pntPositie.X) .Lengte = RandomGrootte(picTekening.Height - pntPositie.Y) .Kleur = RandomRGBKleur() .Teken(picTekening.CreateGraphics) End With End Sub
5.4.2
Overloading
Project
Figuren2
Type
Windows Application
Doel
Polymorfisme : overloading
Extra
Werken met grafische objecten
Moeilijkheid
**
Vorm
Volledig uitgewerkt
Opgave Pas het voorgaande project aan zodat de gebruiker kan kiezen tussen het tekenen van een figuur met een dikke of een dunne rand. Probleemanalyse en implementatie Klassen: Figuur, Rechthoek, Ellips
VVKSO
pagina 170 - Programmeren met .NET
Werkgroep Handel
Bij het tekenen van een figuur wordt een Pen gebruikt. De constructor hiervan is polymorf: je kunt een kleur opgeven, of een kleur en een lijndikte. De klassen Rechthoek en Ellips krijgen twee methoden Teken, die elk een andere pen gebruiken.
Implementatie Public Class Figuur Public Public Public Public
Top As Point Lengte As Integer Breedte As Integer = Kleur As Color
End Class Public Class Ellips Inherits Figuur Public Overloads Sub Teken(ByVal graOppervlak As Graphics) Dim objPen As New Pen(MyBase.Kleur) graOppervlak.DrawEllipse(objPen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub Public Overloads Sub teken(ByVal graOppervlak As Graphics, ByVal psngDikte As Single) Dim objpen As New Pen(MyBase.Kleur, psngDikte) graOppervlak.DrawEllipse(objpen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub End Class
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 171
Public Class Rechthoek Inherits Figuur Public Overloads Sub Teken(ByVal graOppervlak As System.Drawing.Graphics) Dim objPen As New Pen(MyBase.Kleur) graOppervlak.DrawRectangle(objPen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub Public Overloads Sub teken(ByVal graOppervlak As Graphics, ByVal psngDikte As Single) Dim objpen As New Pen(MyBase.Kleur, psngDikte) graOppervlak.DrawRectangle(objpen, MyBase.Top.X, MyBase.Top.Y, MyBase.Breedte, MyBase.Lengte) End Sub End Class frmTekenen Implementatie (enkel de gewijzigde procedures worden weergegeven) Const csngPenDikte As Single = 10 Private Sub TekenRechthoek() Dim objRechthoek As New Rechthoek 'Figuur initialiseren With objRechthoek .Top = pntPositie .Breedte = RandomGrootte(picTekening.Width - pntPositie.X) .Lengte = RandomGrootte(picTekening.Height - pntPositie.Y) .Kleur = RandomRGBKleur() End With If chkDikte.Checked Then objRechthoek.Teken(picTekening.CreateGraphics, csngPenDikte) Else objRechthoek.Teken(picTekening.CreateGraphics) End If End Sub Private Sub TekenEllips() Dim objEllips As New Ellips 'Figuur initialiseren With objEllips .Top = pntPositie .Breedte = RandomGrootte(picTekening.Width - pntPositie.X) .Lengte = RandomGrootte(picTekening.Height - pntPositie.Y) .Kleur = RandomRGBKleur() End With If chkDikte.Checked Then objEllips.Teken(picTekening.CreateGraphics, csngPenDikte) Else objEllips.Teken(picTekening.CreateGraphics) End If End Sub Uitbreiding (uitgewerkt) Breid het project uit zo dat de gebruiker tussen een aantal randdiktes kan kiezen.
VVKSO
pagina 172 - Programmeren met .NET
Werkgroep Handel
5.5
Oefeningen
Maak een klasse voor een bankrekening. Een bankrekening heeft een nummer, een bedrag (positief of negatief), een kredietlimiet en een rekeninghouder. Aan de bankrekening kan al dan niet een ongevallenverzekering verbonden zijn. Het bedrag kan vermeerderd worden met interest (intrestpercentage en looptijd worden opgegeven) of door storting van een opgegeven bedrag. Het bedrag kan verminderd worden met een kredietbedrag (kredietpercentage en looptijd worden opgegeven) of met een opgegeven bedrag als de kredietlimiet hierdoor niet overschreden wordt. Maak een formulier waarmee je de werking van de klasse kunt controleren.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 173
5.6
Overzicht
5.6.1
Overerving
Een subklasse kan de members van een superklasse erven via de clausule Inherits Klassenaam
5.6.2
Polymorfisme
Zelfde methodenaam, maar verschillende werking. •
In dezelfde klasse: overloading.
De verschillende definities moeten een verschil hebben in de argumenten. •
In subklasse: overriding.
In de superklasse wordt bij de declaratie het sleutelwoord Overridable gebruikt, in de subklasse wordt Overrides gebruikt. Public Overridable Sub Methodenaam Public Overrides Sub Methodenaam
VVKSO
pagina 174 - Programmeren met .NET
Werkgroep Handel
ASP.NET • • • •
Betekenis van ASP.NET Server controls Validation controls Werken met een tekstbestand
http://samples.gotdotnet.com/quickstart/aspplus/
5.7
Een webserver
Tot hiertoe heb je Windows toepassingen gemaakt. Je kunt op analoge wijze binnen dezelfde ontwikkelomgeving ook ASP.NET Web toepassingen maken, m.a.w. toepassingen voor gebruik op het Internet of een intranet. Grosso modo zijn er drie soorten webpagina's: -
gewone statische html-pagina's;
-
dynamische html-pagina's, dit zijn pagina's waarin code (VBScript, JavaScript, …) verwerkt zit die client-side uitgevoerd wordt;
-
dynamische pagina's met code die server-side uitgevoerd wordt.
ASP staat voor Active Server Pages, een technologie voor het creëren van dynamische webpagina's waarbij code uitgevoerd wordt op de server. ASP.NET is de specifieke invulling van deze technologie in de .NET omgeving. Voor het creëren van dergelijke toepassingen heb je een webserver nodig. In deze cursus wordt gebruikt gemaakt van IIS, Internet Information Services. IIS wordt niet automatisch geïnstalleerd bij een standaard installatie van Windows, maar zit wel in de Windows besturingssoftware. Installeer indien nodig IIS via Start, Configuratiescherm, Software, Windowsonderdelen toevoegen. Selecteer Internet Information Services en volg de installatiewizard.
Open Configuratiescherm, Systeembeheer en selecteer Internet Information Services.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 175
De standaardwebsite is meteen aangemaakt.
Bekijk de voornaamste standaardeigenschappen van de standaardwebsite. Standaard wordt poort 80 gebruikt
VVKSO
pagina 176 - Programmeren met .NET
Werkgroep Handel
In de basismap C:\Inetpub\wwwroot worden alle sites aangemaakt. Selecteer voor een goede werking de opties Schrijven en Bladeren door mappen. Klik op de knop Configuratie. Het volgende venster verschijnt.
Op het tabblad Toewijzingen staat een lijst van uitvoerbare bestanden en dll’s die zorgen voor de uitvoering van bestanden met bepaalde extensies. Merk hier onder meer de extensies asax, config en aspx op. Deze ASP.NETextensies worden uitgevoerd door: C:\Windows\Microsoft.NET\F ramework\v1.1.4322\aspnet_i sapi.dll.
Door de installatie van IIS is de PC een Internet/Intranetserver. Test je dit uit op de PC zelf, dan kan je die server aanspreken als localhost. Open Internet Explorer en typ als adres localhost. Test je dit uit op een werkstation in het servernetwerk, dan kan je als adres ofwel de naam van de server opgeven ofwel het server-IP-adres.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 177
Opmerking Als je een ASP.NET Web project creëert in een (sub)map van de map wwwroot, creëer je automatisch een ASP.NET toepassing voor IIS. Als je een project overbrengt van een andere webserver, bijvoorbeeld van de school naar thuis of omgekeerd, dan moet je er zelf voor zorgen dat dit een toepassing wordt. •
Open Configuratiescherm, Systeembeheer, Internet Information Services.
•
Open het dialoogvenster Eigenschappen van de map via het snelmenu van de map.
•
Klik op de knop Maken.
In het venster Internet Information Services, herken je de toepassingen aan het pictogram:
VVKSO
pagina 178 - Programmeren met .NET
Werkgroep Handel
5.8
De samenstelling van een ASP.NET Web project
Om meteen kennis te maken met een Web Applicatie maak je een eenvoudige oefening. Project
Kleuren
Type
ASP.NET Web Application
Doel
Gebruik van servercontrols
Extra
Gebruik van IsPostback, Response
Moeilijkheid
*
Vorm
Oplossing
Probleemstelling Naam en voornaam van de gebruiker worden gevraagd. Na het opgeven hiervan wordt de gebruiker begroet en krijgt hij/zij de kans een kleur te kiezen van de knop Verzenden op de pagina. Maak een nieuw Visual Basic Project met als sjabloon ASP.NET Web Application.
Kies als locatie http://localhost/Kleuren. In plaats van de webserver op je eigen computer (localhost), kun je ook werken met een webserver die elders in het netwerk actief is. Bij de creatie van het project worden er een map Kleuren gemaakt (C:/)Inetpub/wwwroot. Deze map bevat de verschillende projectbestanden.
in
de
map
Controleer dit. In Visual Studio wordt een scherm gelijkaardig aan het volgende geopend.
VVKSO
Werkgroep Handel
Programmeren met .NET - pagina 179
Welke namespaces staan er in References. In het ontwerpvenster (Design) staat een webformulier klaar: WebForm1. Tot welke klasse behoort dit object? Er zijn twee manieren om een webformulier te ontwikkelen: •
Grid Layout mode (standaard optie) gebruikt absolute posities om elementen op een webformulier te plaatsen en is erg vergelijkbaar met de manier dat je besturingselementen op een gewoon Windows Form plaatst.
•
Flow Layout mode positioneert de besturingselementen op de webpagina zoals in een gewone HTML-editor. Dit betekent dat een nieuw element ofwel net onder ofwel net naast een ander element verschijnt. Roep via Solution Explorer het code-ontwerpvenster op.
WebForm1.aspx.vb wordt geopend. De gegenereerde code is in tegenstelling tot deze van een Windows formulier minimaal. Open het html-venster. Hierin staat reeds de basis html-code voor een formulier. Een ASP.NET webformulier heeft als extensie aspx. Het bestaat uit twee delen: -
het document (WebForm1.aspx) met de opmaak (html-pagina)
-
de codebehind met de code (vb-pagina).
VVKSO
pagina 180 - Programmeren met .NET
Werkgroep Handel
De code zal uitgevoerd worden op de server zoals aangegeven door het attribuut runat van form: