You are on page 1of 67

1

Inleiding

Computerprogramma = Een reeks instructies die aan de computer vertellen hoe taak uitgevoerd moet worden. Programmeertaal? Machinetaal 1 e generatie Assembleertaal 2e generatie Hogere programmeertalen 3e generatie Hogere programmeertalen 4e generatie Fasen bij het programmeren Probleemdefinitie (Wat moet het programma kunnen?) Probleemanalyse (Top down!) Opstellen schema (Pseudo code) Schrijven bronprogramma Testen programma (Syntax & logica) Documenteren programma (Commentaar!) Gestructureerd programmeren Elk programma bestaat uit een combinatie van: Sequenties Selecties Iteraties Modules Pseudocode = Een verbale schematechniek; programmeren op papier, los van een concrete programmeertaal om zo eerst na te

denken over de structuur van het programma dat we moeten schrijven.


Programmas in pseudocode Het eenvoudigste programma dat we kunnen schrijven bevat slechts n opdracht. Dit kleine programma drukt op het scherm eerste hoofdstuk af. begin voorbeeld1() output eerste hoofdstuk end Data en variabelen Meestal schrijven we programmas die gegevens (of data) gaan verwerken. Gegevens worden bewaard in het geheugen van de computer. Het geheugen kunnen we vergelijken met een enorme wand brievenbussen waarin men post kan pla atsen. Wanneer deze brievenbussen geen label dragen met een adres, dan is het een onbegonnen zaak om elke brief juist te plaatsen. Om gegevens te kunnen verwerken, moeten we die data kunnen bereiken. Daarvoor gebruiken we variabelen. Wanneer we in pseudocode een variabele nodig hebben, dan moeten we: Een naam voor deze variabele kiezen Duidelijk maken tot welk primitief datatype de variabele hoort Bijvoorbeeld: Naam, voornaam: string Leeftijd: int isGevonden: bool heeftZus: bool Een dergelijke opdracht noemen we de declaratie van een variabele Sequenties Wanneer we gebruik maken van variabelen, dan kunnen we al zinvollere programmas schrijven. De eerste basisvorm is de sequentie. De sequentie is een elementair programmadeel dat bestaat uit een aanta l opdrachten die worden uitgevoerd in de volgorde waarin ze voorkomen. Standaardschrijfwijze: begin sequentie() opdracht 1 opdracht 2 opdracht 3 opdracht n end We hebben bijvoorbeeld een programma nodig waarmee een boer kan uitrekenen hoeveel meter prikk eldraad hij nodig heeft voor zijn weiland: begin Voorbeeld1() lengte, breedte, omtrek: double input lengte, breedte omtrek 2 * (lengte + breedte) output Benodigd aantal meter prikkeldraad = , omtrek end

Kennismaking met C# Eens we de pseudocode voor een programmaprobleem hebben, kunnen we het bronprogramma schrijven. Start Alle programmas Microsoft Visual Studio 2010 Microsoft Visual Studio 2010 Link New Project Vervolgens kies je Console Application Vervolledig: Installed Templates: Visual C# Templates: Console Application Name: H1VB1 Vervolgens klik je op OK IDE-ontwikkelomgeving, dus 1 omgeving om: de schermen te creren de programmacode te schrijven het programma te testen Ons eerste programma wordt een console applicatie = een programma voor de DOS-box. Woorden in het blauw zijn woorden uit de C#-taal. Tussen { } van de procedure Main schrijven we programmacode. Elke lijn sluiten we af met een puntkomma. Een lijn die met // begint, wordt door de computer genegeerd. Het is een commentaarlijn. We moeten de klasse Console gebruiken om iets in een DOS-venster te printen of te lezen: Write(): om tekst in het DOS-venster te drukken WriteLine(): om een lijn tekst in het DOS-venster te drukken en naar de volgende lijn te gaan ReadLine(): om de tekst te lezen die de gebruiker typt in het DOS-venster gevolgd door de ENTER-toets
namespace H1VB1 { class Program { static void Main(string[] args) { //gegevens op het scherm brengen Console.WriteLine(Hoi); Console.Write(Mooi weer ); Console.Write(vandaag!); //wachten op een druk op de enter-toets Console.ReadLine(); } } }

Wat valt op bij het coderen? Ordelijke code met insprongen Commentaarlijnen in het groen Karakterstrings tussen dubbele aanhalingstekens IntelliSense keuzelijstjes bij het intikken van code. Met de tabtoets en pijltjestoetsen kan je je keuze maken. Met Ctrl + spatiebalk kan je een keuzelijst vragen. Let op de hoofdletter C van Console. Pas je code aan: We willen een wit achtergrondkleur en een zwart voorgrondkleur
namespace H1VB1 { class Program { static void Main(string[] args) { //eerste voorbeeld //schermkleuren aanpassen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); ...

Methode Clear() zorgt ervoor dat de consolebuffer wordt leeggemaakt en dat het overeenkomstig consolescherm gewist wordt. Alle methoden sluiten af met () Declaratie in C# Hoe variabelen declareren in C#? Een paar voorbeelden: string naam, voornaam; int aantalWerknemers; double totaalBedrag = 50.8; bool isJuist; bool heeftZus; Het datatype gevolgd door een zelfgekozen betekenisvolle naam voor de variabele. Deze naam moet voldoen aan enkele voorwaarden, namelijk: De eerste letter is een kleine letter Alle eerste letters van de volgende deelwoorden zijn hoofdletters Er worden geen underscores gebruikt om deelwoorden te scheiden Geen afkortingen! (dus wel: aantalStudenten & niet: aantStdn)

Hoe variabelen declareren en initialiseren in C#? Een paar voorbeelden: string naam = Jos ; double totaalBedrag = 50.8; bool heeftZus = true; Je kan meteen een beginwaarde geven door na de naam een '=' te typen, gevolgd door de beginwaarde Opgelet: datatypes beginnen met een kleine letter! Voorbeeld 1 in C# We gaan het prikkeldraadprobleem oplossen
//declaratie van variabelen double lengte, breedte, omtrekWei; //schermkleur wijzigen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //lengte opvragen Console.WriteLine("Lengte?"); lengte = Convert.ToDouble(Console.ReadLine()); //breedte opvragen Console.WriteLine("Breedte?"); breedte = Convert.ToDouble(Console.ReadLine()); //formule omtrek toepassen omtrekWei = (lengte + breedte) * 2; //resultaat afbeelden Console.WriteLine("De omtrek van de wei is " + omtrekWei + " meter");

Console.ReadLine() geeft een string terug. Deze string moet bewaard worden in een variabele van het datatype double. String moet dus omgezet worden naar double via: Convert.ToDouble()

Selectie

Gestructureerd programmeren Elk programma bestaat uit een combinatie van: Sequenties Selecties Iteraties Modules Selectie of keuzestructuur De tweede basisvorm is de selectie: De selectie is een elementair programmadeel dat bestaat uit een selectievoorwaarde gecombineerd met twee verschillende componenten waarvan er (afhankelijk van de voorwaarde) slechts n wordt uitgevoerd. In programmas maken we vaak gebruik van opdrachten die uitgevoerd wor den als er aan een bepaalde voorwaarde is voldaan. We werken dit voorbeeld uit: Als je 18 of ouder bent, dan mag je je rijbewijs halen. Ben je jonger dan 18, dan moet je nog wachten. if leeftijd >= 18 then stappen ondernemen om rijbewijs te halen else nog even geduld uitoefenen endif H2VB1 Indien resultaat >= 50 wordt de naam van de student afgedrukt met de vermelding "is geslaagd". In het andere geval verschijnt eveneens de naam, maar nu met de vermelding "is niet geslaagd".
namespace H2VB1 { class Program { static void Main(string[] args) { //declaratie van variabelen string naam; int resultaat; //schermkleuren wijzigen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //opvragen naam en resultaat Console.WriteLine("Wat is je naam?"); naam = Console.ReadLine(); Console.WriteLine("Wat is je resultaat op 100?"); resultaat = Convert.ToInt32(Console.ReadLine()); Console.Write("\n" + naam + "is "); if (resultaat >= 50) { Console.Write("wel"); } else { Console.Write("niet"); } Console.WriteLine(" geslaagd"); Console.Write("\nDruk op enter om verder te gaan"); Console.ReadLine(); } } }

Debuggen in C# Wie een bug programmeert, moet in eerste instantie proberen zelf te achterhalen waar het fout gaat: Waarom doet je programma niet wat je verwacht? Waarom krijg je een foutmelding? Waarom stopt je programma niet? De editor van C# biedt je op dit vlak heel wat ondersteuning. Om de fout op te sporen, kan je geb ruik maken van het menu Debug. Druk op F11 om het stapsgewijs debuggen te starten. Zorg er vervolgens via Debug Windows Locals voor dat je de variabelen en de inhoud te zien krijgt. Controleer de inhoud van het venster Locals: Zijn dit de variabelen die op dit punt in het programma gekend moeten zijn? Is het gegevenstype juist? Klopt de inhoud? Ga verder door het programma door telkens op F11 te drukken. Voer de gewenste informatie in, druk op enter en klik terug in j e codevenster om daar verder te debuggen. Om een fout op te sporen bestudeer je de inhoud van de variabelen in het venste Locals. Als je met de muisaanwijzer over een variabele gaat in de code, krijg je de inhoud van de variabele op dat moment te zien. Als je in een lang programma een fout moet opsporen, kan je beter een breekpunt inlassen op het punt waar je vermoedt dat de fout zich situeert. Dat doe je door in de kantlijn voor de code te klikken. Je ziet dan een rode bol.

Vervolgens gebruik je de gewone startknop om het programma te starten. Op het breekpunt stopt de snelle uitvoering en kan je overgaan op stap voor stap debuggen. Een breekpunt verwijderen doe je door op de rode bol te klikken. Via Debug Delete All Breakpoints kan je meerdere breakpoints tegelijkertijd verwijderen. Eenzijdige selectie (geen else-tak) We kunnen het voorbeeld zodanig herschrijven dat we geen else blok nodig hebben. Bijvoorbeeld: enkel wanneer een student 50 of meer heeft, drukken we zijn naam af.
if (resultaat >= 50) { Console.Write(naam + "is geslaagd "); } Console.Write("\nDruk op enter om verder te gaan"); Console.ReadLine();

H2VB2 Wanneer Jef Klabas minimum 50% behaalt en hij geen buispunten heeft, krijgt hij 4% verhoging van zijn zakgeld. In de andere g evallen zal hij gedurende 2 maanden 2% minder zakgeld krijgen als compensatie voor het verlies aan leerkredieten.
Hoeveel bedraagt je huidig zakgeld / maand? 100 Wat is je resultaat? 50 Hoeveel buispunten heb je? 2 Je zakgeld voor de volgende 2 maanden is 98 euro Druk op enter om verder te gaan Hoeveel bedraagt je huidig zakgeld / maand? 100 Wat is je resultaat? 55 Hoeveel buispunten heb je? 0 Je zakgeld voor de volgende 2 maanden is 104 euro Druk op enter om verder te gaan namespace H2VB2 { class Program { static void Main(string[] args) { //declaratie double resultaat, oudZakgeld, nieuwZakgeld; int buispunten, percentage; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //inlezen Console.Write("Hoeveel bedraagt je huidig zakgeld / maand? "); oudZakgeld = Convert.ToDouble(Console.ReadLine()); Console.Write("Wat is je resultaat? "); resultaat = Convert.ToDouble(Console.ReadLine()); Console.Write("Hoeveel buispunten heb je? "); buispunten = Convert.ToInt32(Console.ReadLine()); Console.Write("\nJe zakgeld voor de volgende 2 maanden is "); //juiste percentage en kleur bepalen if (resultaat >= 50 && buispunten == 0) { percentage = 4; Console.ForegroundColor = ConsoleColor.Blue; } else { percentage = -2; Console.ForegroundColor = ConsoleColor.Red; } //nieuw zakgeld berekenen nieuwZakgeld = oudZakgeld * (1 + (percentage / 100.0)); //resultaat afbeelden Console.Write(nieuwZakgeld); Console.ForegroundColor = ConsoleColor.Black; Console.WriteLine(" euro"); //wachten op enter Console.Write("\nDruk op enter om verder te gaan"); Console.ReadLine(); } } }

Zelfstudie 1
H2VB3
PI EN E Math.PI Math.E ABSOLUTE WAARDEN Math.Abs(-12.34) MINIMUM EN MAXIMUM Math.Min(-12.34, 10) Math.Max(-12.34, 10)

De klasse Math
--> --> 3,14159265358979 2,71828182845905

-->

12,34

--> -->

-12,34 10

AFRONDEN Math.Round(10.5) Math.Round(10.51) Math.Round(11.5) Math.Round(-12.51) Math.Round(-12.3456, 2) Math.Ceiling(-11.5) Math.Ceiling(12.5) Math.Floor(-11.5) Math.Floor(12.5)

--> --> --> --> --> --> --> --> -->

10 11 12 -13 -12,35 -11 13 -12 12

MACHTSVERHEFFING, LOGARITME, VIERKANTSWORTEL Math.Pow(2, 3) --> 8 Math.Log(8, 2) --> 3 Math.Sqrt(16) --> 4

In dit voorbeeld wordt gebruik gemaakt van de klasse Math(). De klas se Math bevat heel wat interessante methodes zoals Math.Sqrt() en Math.Pow() die in de theorie van H1 al aan bod kwamen. De klasse Math kan dus gebruikt worden om bijvoorbeeld het getal Pi op t e vragen, de absolute waarde te berekenen, iets af te ronden, de vierkantswortel te berekenen enz

Geneste en meervoudige selectie

Gestructureerd programmeren Elk programma bestaat uit een combinatie van: Sequenties Selecties Geneste selectie Meervoudige selectie Iteraties Modules Geneste selectie Soms kan het voorkomen dat er een tweede vraag gesteld moet worden om te weten wat er moet gebeuren. H3VB1
namespace H3VB1 { class Program { static void Main(string[] args) { //declaratie variabelen string naam; int resultaat; //schermkleur wijzigen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //opvragen naam en resultaat Console.WriteLine("Wat is je naam?"); naam = Console.ReadLine(); Console.WriteLine("Wat is je resultaat op 100?"); resultaat = Convert.ToInt32(Console.ReadLine()); //beoordeling bepalen en afdrukken Console.WriteLine(); Console.Write(naam + " is "); if (resultaat >= 60) { Console.WriteLine("geslaagd"); } else { if (resultaat >= 50) { Console.WriteLine("gedelibereerd"); } else { Console.WriteLine("gebuisd"); } } //wachten op enter Console.Write("\nDruk op enter om verder te gaan"); Console.ReadLine(); } } }

Meervoudige selectie De meervoudige selectie is een vereenvoudigde structuur voor opeenvolgende selecties van een zelfde variabele We kiezen voor een meervoudige selectie als de voorwaarden elkaar uitsluiten en als de kans bestaat dat er later nog mogelijkheden moeten worden toegevoegd. Een meervoudige selectie is overzichtelijker en er moet steeds maar 1 tak doorlopen worden. Meervoudige selectie in C#
switch (variabele) { case constante: opdracht n; break; default: opdracht m; break; }

H3VB2
namespace H3VB2 { class Program { static void Main(string[] args) { //declaratie variabelen string naam, code, resultaat; //schermkleur wijzigen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //opvragen naam en code Console.WriteLine("Wat is je naam?"); naam = Console.ReadLine(); Console.WriteLine("A, B of C?"); code = Console.ReadLine(); //meervoudige selectie resultaat = ""; switch (code) { case "a": case "A": resultaat = "ochtend"; break; case "b": case "B": resultaat = "middag"; break; default: resultaat = "avond"; break; } //resultaat tonen Console.WriteLine(naam + " het is nu " + resultaat); //wachten op enter Console.ReadLine(); } } }

Als aan geen enkele voorwaarde is voldaan, wordt de code van de default tak uitgevoerd. De invoer is ni et lettergevoelig (zowel case a en b als case A en B zijn gedefinieerd). Lege case takken krijgen geen break. Bij een lege case tak gaat de uitvoering verder in de eerstvolgende case tak die niet leeg is.

Iteratie met teller

Gestructureerd programmeren Elk programma bestaat uit een combinatie van: Sequenties Selecties Iteraties Iteratie met teller Gewone iteratie Modules Iteraties Bijvoorbeeld: Als ik elke morgen 4 boterhammen eet, dan zou het programma in pseudo code er als volgt uitzien: begin voorbeeld() eet een boterham eet een boterham eet een boterham eet een boterham end Oplossing: Met iteratie met teller begin voorbeeld() zet teller op 1 eet een boterham verhoog de inhoud van de teller met 1 eet een boterham verhoog de inhoud van de teller met 1 eet een boterham verhoog de inhoud van de teller met 1 eet een boterham end Of korter: begin voorbeeld() teller: Integer for teller 1 to 4 step 1 eet een boterham endfor end Iteraties zijn herhalingsstructuren. We willen ons programma bepaalde opdrachten meer dan 1 keer laten uitvoeren op een effic inte manier. De iteratie met teller is een elementair programmadeel dat opgebouwd is uit een teller, een beginwaarde, een eindwaarde en een stapgrootte. De iteratie wordt een bepaald aantal keren uitgevoerd afhankelijk van de evolute van de waarde van de teller. We kennen hier het EXACT AANTAL herhalingen. Iteratie met teller in C#
for ([initialisatie instructie]; [voorwaarde]; [iteratie instructie];) { [instructies;] }

Dezelfde actie wordt 4 keer herhaald. Wat als er 30 boterhammen zouden gegeten worden?

Bijvoorbeeld: for (teller = 1; teller <= 10; teller++) Initialisatie instructie: Hier komt een instructie te staan die 1 keer wordt uitgevoerd, voorda t de lus begint. Dit is meestal het initialiseren van een variabele die nodig is om te bepalen hoeveel keer de herhaling al is uitgevoerd. Voorwaarde: De voorwaarde geeft aan hoe lang er nog een iteratie (herhaling) ma gebeuren. Als de voorwaarde waar is, wordt de inhoud van de lus nog een keer uitgevoerd. Als de voorwaarde niet waar is, wordt de inhoud van de lus overgeslagen. Iteratie instructie: Hier komt een instructie te staat die wordt uitgevoerd nadat de inhoud van de lus 1 keer is uitgevoerd. Meestal wordt hier de variabele met 1 opgehoogd om te tellen hoe vaak de lus al is uitgevoerd.

H4VB1 De gebruiker geeft een willekeurig getal in waarvan hij de tafel van vermenigvuldiging wil zien. Op het scherm zien we de taf el, beginnend bij 1 x dat getal, eindigend bij 10 x dat getal.
namespace H4VB1 { class Program { static void Main(string[] args) { //declaratie variabelen int getal = 0, teller = 0, product = 0; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //getal inlezen Console.Write("Van welk geheel getal wenst u de tafel te zien? "); getal = Convert.ToInt32(Console.ReadLine()); //scherm wissen Console.Clear(); //verwerking for (teller = 1; teller <= 10; teller++) { product = teller * getal; Console.WriteLine(\t + teller + " * " + getal + " = " + product); } //wachten op entertoets Console.WriteLine("\nDruk op enter om te stoppen"); Console.ReadLine(); } } }

Opmerking:

"\t" stuurt 1 druk op de tabtoets naar het scherm "\n" stuurt 1 enter naar het scherm "\"" stuurt een dubbel aanhalingsteken naar het scherm Console.Clear() wist het scherm. Het resultaat wordt op een proper scherm weergegeven.

10

Gewone arrays

Vaak moeten we grote hoeveelheden woorden of getallen in het geheugen bewaren. Bijvoorbeeld: We willen een programma schrijven dat voor elke dag van de week de temperatuur opvraagt en dat daarna de gemid delde temperatuur afbeeldt. We kunnen vervolgens nog detailinformatie opvragen over een bepaalde dag. Array = Gegevensstructuur die bestaat uit een reeks variabelen die bij elkaar horen en die allemaal onder eenzelfde naam in het ge heugen bewaard worden. Om een array te kunnen gebruiken, moet je deze declareren. Bij d e declaratie geef je de array een naam en bepaal je uit hoeveel elementen de array zal bestaan. Array declareren
int[] temperatuurDagArray = new int[7]

In temperatuurDagArray[0] kan je de temperatuur van de 1 e dag stoppen. In temperatuurDagArray[1] kan je de temperatuur van de 2 e dag stoppen.

H5VB2
namespace H5VB2 { class Program { static void Main(string[] args) { //declaratie variabelen int[] temperatuurDagArray = new int[7]; int detail, index, totaalTemperatuurDag; double gemiddelde; //schermkleuren ... //initialiseren totaalTemperatuurDag = 0; //gegevens opvragen for (index = 0; index <= temperatuurDagArray.GetUpperBound( 0); index++) { Console.Write("Temperatuur dag " + (index + 1) + "? "); temperatuurDagArray[index] = Convert.ToInt32(Console.ReadLine()); totaalTemperatuurDag += temperatuurDagArray[index]; } //gemiddelde berekenen + tonen gemiddelde = totaalTemperatuurDag / (temperatuurDagArray.GetUpperBound(0) + 1); Console.WriteLine("\nDe gemiddelde temperatuur voor deze week is: " + gemiddelde); //vragen van welke dag detailinformatie getoond moet worden Console.Write("\nVan welke dag wenst u detailinformatie te zien? "); detail = Convert.ToInt32(Console.ReadLine()); //controle invoer if (detail - 1 >= 0 && detail - 1 <= temperatuurDagArray.GetUpperBound(0)) { //antwoord geven Console.WriteLine("Dag " + detail + ": " + temperatuurDagArray[detail - 1]); else { //foutmelding geven Console.WriteLine("Ongeldige invoer"); } //wachten op entertoets Console.ReadLine(); } } }

Via de methode .GetUpperBound() kan je te weten komen hoeveel array -ingangen er zijn. Omdat we met een 1-dimensionale array werken (1 index volstaat om te verwijzen naar een concreet gegeven), moeten we daarom tussen de haakjes 0 vermelden, want de verwijzing naar een dimensie begint ook bij 0. De methode .GetLowerBound() bestaat ook, maar zal in C# altijd als resultaat 0 geven. Uitbreiding declaratie We kunnen de elementen van een array initialiseren bij het instantiren. Hierbij mag je geen aantal tussen de vierkate haakje s plaatsen:
int[] getallenArray = new int[] {55, 63, 29, 25, 40, 16};

Door bovenstaande instructie wordt een 1-dimensionale array getallenArray aangemaakt en meteen opgevuld met 6 integers.

11

Zelfstudie 2

De klasse Array

H5VB3 In dit voorbeeld wordt gebruik gemaakt van de klasse Array(). De klasse Array bevat heel wat interessante methodes zoals Arra y.Sort() en Array.Reverse(). De klasse Array kan dus onder andere gebruikt worden om de inhoud van een array is het geheugen te sorteren of om te keren. Methode Array.Sort() Met de Sort() methode kan je de inhoud (of een deel) van een array sorteren van klein naar groot. Het komt er op neer dat je tussen haakjes moet opgeven welke array je wil sorteren van klein naar groot. Indien je niet de hele array wil sorteren, kan je opgeven vanaf welk punt je wil beginnen te sorteren en hoeveel elementen je vervolgens wil sorteren. Bij sorteren van getallen wordt het kleinste getal gezocht. Dit mag negatief zijn. Tijdens het sorteren van strings wordt er gezocht naar het woord dat het dichtst bij de kleine letter a ligt. Hoofdletters en kleine letters hebben een verschillende waarde! Bijvoorbeeld: els elS eLs Els Methode Array.Reverse() De Reverse() methode gebruik je om een (deel van) een 1-dimensionele array om te keren. Als je van groot naar klein wil sorteren, moet je eerst de Sort() methode gebruiken om te sorteren van klein naar groot en vervolgens het geheel omkeren via de methode Reverse(). H5VB3 Namenlijst sorteren
Namenlijst niet gesorteerd 1: Jos 2: Els 3: Inge 4: Anna Namenlijst van A naar Z 1: Anna 2: Els 3: Inge 4: Jos Namenlijst van Z naar A 1: Jos 2: Inge 3: Els 4: Anna Druk op een toets // declaratie int index = 0, indexVanaf = 3, aantalElementen = 5, teller string[] namenArray = new string[] { "Jos", "Els", "Inge", string[] voorwerpenArray = new string[] { "vork", "emmer", "aardappelmes", "anker", "lepel" }; string[] woonplaatsenArray = new string[] { "Geel", "Mol", "Herentals", "Turnhout", "Beerse", "Hasselt" }; //schermkleuren ... // tonen inhoud Console.WriteLine("Namenlijst niet gesorteerd\n"); for (index = 0; index <= namenArray.GetUpperBound(0); index++) { Console.WriteLine((index + 1) + ": " + namenArray[index]); // sorteren Console.WriteLine("\nNamenlijst van A naar Z\n"); Array.Sort(namenArray); for (index = 0; index <= namenArray.GetUpperBound(0); index++) { Console.WriteLine((index + 1) + ": " + namenArray[index]); // omkeren Console.WriteLine("\nNamenlijst van Z naar A\n"); Array.Reverse(namenArray); for (index = 0; index <= namenArray.GetUpperBound(0); index++) { Console.WriteLine((index + 1) + ": " + namenArray[index]); // wachten op enter Console.WriteLine("\nDruk op een toets"); Console.ReadLine(); Console.Clear(); } } = 0; "Anna" }; "taartschep", "zandvorm", "zonnehoed", "Zaventem", "Beveren", "Zulte", "Antwerpen",

12

H5VB3 Voorwerpenlijst sorteren


Voorwerpenlijst niet gesorteerd 1: vork 2: emmer 3: taartschep 4: zandvorm 5: zonnehoed 6: aardappelmes 7: anker 8: lepel Voorwerpenlijst sorteren vanaf element 4 1: vork 2: emmer 3: taartschep 4: aardappelmes 5: anker 6: lepel 7: zandvorm 8: zonnehoed Druk op een toets // tonen inhoud Console.WriteLine("Voorwerpenlijst niet gesorteerd\n"); for (index = 0; index <= voorwerpenArray.GetUpperBound(0); index++) { Console.WriteLine((index + 1) + ": " + voorwerpenArray[index]);

// array sorteren vanaf element 4 Console.WriteLine("\nVoorwerpenlijst sorteren vanaf element " + (indexVanaf + 1) + "\n"); Array.Sort(voorwerpenArray, indexVanaf, voorwerpenArray.GetUpperBound(0) - (indexVanaf - 1)); for (index = 0; index <= voorwerpenArray.GetUpperBound(0); index++) { if (index == indexVanaf) { Console.ForegroundColor = ConsoleColor.Red; } Console.WriteLine((index + 1) + ": " + voorwerpenArray[index]); } Console.ForegroundColor = ConsoleColor.Black; // wachten op enter Console.WriteLine("\nDruk op een toets"); Console.ReadLine(); Console.Clear();

H5VB3 Woonplaatsen sorteren


Woonplaatsen niet gesorteerd 1: Geel 2: Mol 3: Zaventem 4: Beveren 5: Zulte 6: Antwerpen 7: Herentals 8: Turnhout 9: Beerse 10: Hasselt Woonplaatsen sorteren - vanaf element 4 aantal elementen 5 1: Geel 2: Mol 3: Zaventem 4: Antwerpen 5: Beveren 6: Herentals 7: Turnhout 8: Zulte 9: Beerse 10: Hasselt Woonplaatsen omgekeerd - vanaf element 4 aantal elementen 5 1: Geel 2: Mol 3: Zaventem 4: Zulte 5: Turnhout 6: Herentals 7: Beveren 8: Antwerpen 9: Beerse 10: Hasselt Druk op een toets // tonen inhoud Console.WriteLine("Woonplaatsen niet gesorteerd\n"); for (index = 0; index <= woonplaatsenArray.GetUpperBound(0); index++) { Console.WriteLine((index + 1) + ": " + woonplaatsenArray[index]);

// array sorteren vanaf element 4 en dit voor 5 elementen Console.WriteLine("\nWoonplaatsen sorteren - vanaf element " + (indexVanaf + 1) + " - aantal elementen = " + aantalElementen + "\n"); Array.Sort(woonplaatsenArray, indexVanaf, aantalElementen);

13

for (index = 0; index <= woonplaatsenArray.GetUpperBound(0); index++) { if (index == indexVanaf) { Console.ForegroundColor = ConsoleColor.Red; teller = 0; } Console.WriteLine((index + 1) + ": " + woonplaatsenArray[index]); teller++; if (teller >= aantalElementen) { Console.ForegroundColor = ConsoleColor.Black; } // omkeren vanaf element 4 en dit voor 5 elementen Console.WriteLine("\nWoonplaatsen omgekeerd - vanaf element " + (indexVanaf + 1) + " - aantal elementen = " + aantalElementen + "\n"); Array.Reverse(woonplaatsenArray, indexVanaf, aantalElementen); for (index = 0; index <= woonplaatsenArray.GetUpperBound(0); index++) { if (index == indexVanaf) { Console.ForegroundColor = ConsoleColor.Red; teller = 0; } Console.WriteLine((index + 1) + ": " + woonplaatsenArray[index]); teller++; if (teller >= aantalElementen) { Console.ForegroundColor = ConsoleColor.Black; } // wachten op enter Console.WriteLine("\nDruk op een toets"); Console.ReadLine(); Console.Clear(); } }

H5VB4 De klasse Array heeft nog methodes die we erg goed kunnen gebruiken. In dit voorbeeld wordt gebruik gemaakt van Array.Copy(). Er wordt een deel van een bronarray gekopierd naar een doelarray die axact even groot gedeclareerd is als de bronarray.
Oorspronkelijke array index index index index index 0: 1: 2: 3: 4: Jean Louis Julien Pierre Franois

Gekopieerde array index index index index index 0: Jean 1: Louis 2: Julien 3: 4:

Druk op enter om verder te gaan //declaratie string[] namenArray = new string[] { "Jean", "Louis", "Julien","Pierre","Franois" }; string[] kopieArray = new string[namenArray.GetUpperBound(0) + 1]; int index; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //verwerken Array.Copy(namenArray, kopieArray, 3); //tonen oorspronkelijke gegevens Console.WriteLine("Oorspronkelijke array\n"); for (index = 0; index <= namenArray.GetUpperBound(0); index++) { Console.WriteLine("index " + index + ": " + namenArray[index]); } //tonen gekopieerde gegevens Console.WriteLine("\nGekopieerde array:\n"); for (index = 0; index <= kopieArray.GetUpperBound(0); index++) { Console.WriteLine("index " + index + ": " + kopieArray[index]); } //wachten op enter Console.WriteLine("\nDruk op enter om verder te gaan"); Console.ReadLine();

14

H5VB5 In dit voorbeeld wordt er gebruik gemaakt van Array.Sort() om 2 arrays samen te sorteren. Je vindt hier een array met namen en een array met bijhorende leeftijden. Eerst worden de gegevens niet gesorteerd getoond en vervolgens gesorteerd van jong naar oud. De sorteermethode die we in H5VB3 gebruikten, voldoet hier niet. De namen en leeftijden moeten samen blijven horen. Array.Sort(Array, Array) De 1ste array die je opgeeft bevat de sleutelwaarden. Dit zijn de waarden d ie je wil gebruiken om te sorteren. De 2de array die je opgeeft bevat de waarden die mee gesorteerd moeten worden.
Niet gesorteerde gegevens: Pieter-Jan -> 17 jaar Steven -> 20 jaar Roos -> 5 jaar Jean-Luc -> 55 jaar Jelle -> 18 jaar Fons -> 70 jaar Gesorteerd volgens leeftijd: Roos -> 5 jaar Pieter-Jan -> 17 jaar Jelle -> 18 jaar Steven -> 20 jaar Jean-Luc -> 55 jaar Fons -> 70 jaar Druk op enter om verder te gaan //declaratie int[] leeftijdenArray = new int[] {17,20,5,55,18,70 }; string[] namenArray = new string[] {"Pieter-Jan","Steven","Roos","Jean-Luc","Jelle","Fons"}; int index; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //tonen oorspronkelijke volgorde Console.WriteLine("Niet gesorteerde gegevens:\n"); for (index = 0; index <= namenArray.GetUpperBound(0);index++ ) { Console.WriteLine("\t" + namenArray[index] + "-> " + leeftijdenArray[index] + " jaar"); } //sorteren Array.Sort(leeftijdenArray, namenArray); //tonen nieuwe volgorde Console.WriteLine("\nGesorteerd volgens leeftijd:\n"); for (index = 0; index <= namenArray.GetUpperBound(0); index++) { Console.WriteLine("\t" + namenArray[index] + "-> " + leeftijdenArray[index] + " jaar"); } //wachten op enter Console.WriteLine("\nDruk op enter om verder te gaan"); Console.ReadLine();

15

Gewone iteratie

Gestructureerd programmeren Elk programma bestaat uit een combinatie van: Sequenties Selecties Iteraties Iteratie met teller Gewone iteratie Modules Iteratie met teller Je weet EXACT hoeveel keer je een actie moet herhalen. Bijvoorbeeld: Ik eet elke morgen 5 boterhammen. De actie eet een boterham moet dus 5 keer herhaald worden. Iteratie Je weet NIET EXACT hoeveel keer je een actie wil herhalen. Je kan dus geen iteratie met teller gebruiken. Oplossing: Iteratie met een voorwaarde gebruiken. Toegepast op het voorbeeld: je eet nog een boterham zolang je nog honger hebt. begin voorbeeld() isHongerig: boolean while isHongerig = True do eet een boterham end drink een tas koffie end Variabele van het type boolean kan slechts 2 toestanden aannemen, namelijk True of False. De iteratie is een elementair programmadeel dat opgebouwd is uit een iteratievoorwaarde en een component. De component wordt uitgevoerd zolang (while) aan de voorwaarde voldaan is. De component kan uit meerdere instructies bestaan. Gewone iteratie (eerste vorm) while voorwaarde do component ewd (end while do) H6VB1 Gebruiker geeft een beginkapitaal en de rentevoet in. Op het scherm wordt een overzicht gemaakt van het eindka pitaal per jaar. Dit gebeurt tot het eindkapitaal meet dan het dubbel van het beginkapitaal is. Er wordt gewerkt met samengestelde interest: Je krijgt ook interest op de interest van de voorbije jaren. Formule van samengestelde interest: eindkapitaal = beginkapitaal * (1 + rente/100)^jaar
Geef beginkapitaal in: 200 Geef rentevoet in: 10 1 220 2 242 3 266,2 4 292,82 5 322,102 6 354,3122 7 389,74342 8 428,717762 Druk enter om verder te gaan.

Kan je een iteratie met teller gebruiken? Nee! Als de rentevoet hoger is, heb je minder dan 8 jaar nodig. Als de rentevoet la ger is, heb je meer dan 8 jaar nodig. Dus iteratie gebruiken, maar met welke voorwaarden? Voorwaarde halen uit de opdracht: tot het eindkapitaal meer dan het dubbel van het beginkapitaal is Zolang het eindkapitaal <= 2 * beginkapitaal
//declaratie variabelen double beginKapitaal, eindKapitaal = 0.0, rente; int jaar = 0; //inlezen van variabelen Console.Write("Geef beginkapitaal in: "); beginKapitaal = Convert.ToDouble(Console.ReadLine()); Console.Write("Geef rentevoet in: "); rente = Convert.ToDouble(Console.ReadLine()); //lus die wordt uitgevoerd zolang de voorwaarde voldaan is while (eindkapitaal <= 2 * beginkapitaal) { jaar += 1; eindKapitaal = beginKapitaal * Math.Pow((1 + rente / 100), jaar); Console.WriteLine(jaar + " - " + eindKapitaal); } //wachten op entertoets Console.WriteLine("\nDruk op enter om verder te gaan"); Console.ReadLine();

16

Uitleg verkorte notatie Tellers/getallen verhogen of verlagen: getal += 1 getal = getal + 1 getal = 5 getal = getal 5 getal *= 1,5 getal = getal * 1,5 getal /= deler getal = getal / deler getal++ getal = getal + 1 getal- getal = getal 1 Gewone iteratie (tweede vorm)
do { statements; break; } while (expression);

Puntkomma niet vergeten!

ZOLANG aan de voorwaarde voldaan is testen we achteraan. Lus wordt MINIIMAAL 1 KEER doorlopen. H6VB2 De gebruiker geeft namen in via het scherm. De gebruiker moet minstens 1 keer de vraag krijgen om een naam in te geven, vervolgens kan hij aangeven met enter dat hij wil stoppen met het ingeven van namen.
//declaratie variabelen string naam; //lus die minimaal 1 keer wordt uitgevoerd do { Console.WriteLine("Geef een naam in"); Console.WriteLine("Druk enter om verder te gaan"); naam = Console.ReadLine(); } while (naam != ""); //wachten op entertoets Console.WriteLine("\nDruk op enter om te stoppen"); Console.ReadLine();

Priming Read Wanneer je een herhalingsstructuur hebt waarin je meer dan 1 vraag gaat stellen aan de gebruiker of waarin je alleen maar ver der werkt met het antwoord als dat correct is, dan moet je voor je in de lus gaat, de informatie inlezen die bepaalt of je al dan niet aan de herhalingsstructuur gaat beginnen. Stappenplan: Voor de lus lees je de kritieke waarde in Bij het begin van de lus test je op de kritieke waarde In de lus lees je de rest van de informatie in Net voor het einde van de lus vraag je opnieuw de kritieke waarde op H6VB3
Geef een naam in, ENTER om te stoppen Elke Woonplaats van ELKE? Mol Leeftijd? 25 Geef een naam in, ENTER om te stoppen Kurt Woonplaats van KURT? Geel Leeftijd? 18 De gemiddelde leeftijd voor deze mensen is 21 jaar Druk enter om verder te gaan

Hier moeten we priming read toepassen! Als we geen naam invullen, worden de andere vragen niet gesteld.
Geef een naam in, ENTER om te stoppen Druk op enter om verder te gaan //declaratie variabelen string naam, woonplaats; int leeftijd, gemiddeldeLeeftijd, aantalNamen=0, totaalLeeftijd=0; //kritieke waarde inlezen Console.WriteLine("Geef een naam in, ENTER om te stoppen\n"); naam = Console.ReadLine(); //kritieke waarde inlezen while (naam != ""); { //overige gegevens inlezen Console.ForegroundColor = ConsoleColor.Blue; Console.Write("\tWoonplaats van " + naam.ToUpper() + "? "); woonplaats = Console.ReadLine(); Console.Write("\tLeeftijd? "); leeftijd = Convert.ToInt32(Console.ReadLine()); Console.ForegroundColor = ConsoleColor.Black; //teller en subtotaal verhogen aantalNamen++;

17

totaalLeeftijd += leeftijd; //kritieke waarde opnieuw lezen Console.WriteLine("\nGeef een naam in, ENTER om te stoppen\n"); naam = Console.ReadLine(); } //uitvoer op scherm brengen if (aantalNamen > 0) { //berekening gemiddeldeLeeftijd = totaalLeeftijd / aantalNamen; Console.ForegroundColor = ConsoleColor.Red; Console.Write("De gemiddelde leeftijd voor deze mensen is " + gemiddeldeLeeftijd + " jaar"); Console.ForegroundColor = ConsoleColor.Black; } //wachten op entertoets Console.WriteLine("\n\nDruk op enter om verder te gaan"); Console.ReadLine();

Methode ToUpper() en ToLower() ToUpper() om tekst om te vormen naar hoofdletters. ToLower() om tekst om te vormen naar kleine letters.

18

Invoercontrole

H7VB1 De gebruiker moet een geheel getal ingeven tussen 0 en 10. Wanneer de gebruiker iets anders dan een getal ingeeft of een geta l dat niet binnen de grenzen ligt, blijft het programma een geheel getal vragen totdat de gebruiker een geheel getal ingeeft dat voldoet aan de voorwaarden.
//declaratie variabelen string antwoord; int antwoord; //lus tot een getal binnen de grenzen ligt do { //inlezen //lus tot een getal ingevuld wordt do { Console.Write("Geef een getal tussen 0 en 10 (incl. grenzen): "); Console.ForegroundColor = ConsoleColor.Blue; antwoord = Console.ReadLine(); Console.ForegroundColor = ConsoleColor.Black; } while (int.TryParse(antwoord, out getal) == false); } while (getal < 0 || getal > 10); Console.WriteLine("\n" + getal + " is een geheel getal binnen de opgegeven grenzen\n"); //wachten op entertoets Console.WriteLine("\n\nDruk op enter om verder te gaan"); Console.ReadLine();

TryParse methode Als je moet controleren of de invoer een geheel getal is, dan moet je het antwoord opvangen in een variabele van het type string. Pas als de invoer correct is, breng je de invoer onder in een geschikte variabele van het type int. Je kan dit op twee manieren coderen: while (int.TryParse(antwoord, out getal) == false);
while (!int.TryParse(antwoord, out getal));

Probeer de invoer (antwoord) over te brengen naar de variabele getal van het datatype int. Deze methode geeft true terug in dien de omzetting lukt, false indien de omzetting niet lukt. In voorbeeld 1 gaat de lus door zolang antwoord geen geheel getal is. Dubbele invoercontrole Wanneer je eerst moet controleren of de invoer van een bepaald gegevenstype is en daarna moet controleren of die invoer bin nen bepaalde grenzen ligt, dan spreken we over een dubbele invoercontrole. Voor dubbele invoercontrole werken we altijd een gestructureerde oplossing uit volgens een vast stramien met geneste lussen. Stappenplan: Declareer 2 variabelen: 1 variabele van het type string, 1 variabele van het vereiste type Schrijf geneste lussen van het volgende type: do { do {...} while(...); } while(...); In de binnenste lus lees je de stringvariabele in en test je while of het gegevenstype OK is via TryParse In de buitenste lus test je bij while of de grenzen gerespecteerd werden. H7VB2 We vragen een geboortedatum die geldig is en voor de huidige datum ligt.
Geef Geef Geef Geef Geef je je je je je geboortedatum geboortedatum geboortedatum geboortedatum geboortedatum in: in: in: in: in: 11 aap 2001 jas 11/45/1200 12/12/2012 9 mei 90

Deze invoer was correct: 9/05/1990 Druk op een toets... //declaratie variabelen string antwoord; DateTime datum; //dubbele invoercontrole - datum do { //inlezen //lus tot een getal ingevuld wordt do { Console.Write("Geef je geboortedatum: "); antwoord = Console.ReadLine(); } while (DateTime.TryParse(antwoord, out datum) == false); } while ((datum < DateTime.Today) == false); Console.WriteLine("\nDeze invoer wa correct: " + datum.ToShortDateString()); //wachten op entertoets Console.WriteLine("\nDruk op een toets..."); Console.ReadLine();

19

DateTime Het gegevenstype DateTime gebruik je voor datums. Testen of iets een datum is, doe je met de methode DateTime.TryParse(). Deze methode herkent datums en tijdstippen in alle mogelijke formaten. De methode werkt vergelijkbaar met de int.Tryparse die we al eerder zagen. Om de huidige systeemdatum op te vragen, gebruik je de klasse DateTime. Daarin vind je onder andere de eigenschap Today. Om een datum in een bepaald formaat te tonen, kan je volgende methodes gebruiken: datum.ToShortDateString() 9/05/1990 datum.ToLongDateString() woensdag 9 mei 1990 datum 9/05/1990 0:00:00

20

List<T>

Gewone arrays Declaratie: string[] namenArray = new string[4] Bij deze declaratie worden exact 4 ingangen gemaakt. Deze array kan je niet vergroten, anders krijg je fouten. H8VB1 LIST<T> Soms weet je niet op voorhand hoe groot je een array moet maken. Als de afmetingen niet op voorhand vaststaat, declareer je best een List<T>. De omvang van een List<T> wordt automatisch aangepast aan het aantal elementen.
Aantal opgenomen items in List<T> = 0 Geef naam van 1ste geslaagde student in: Ann Peeters Geslaagde student: Ann Peeters Aantal opgenomen items in List<T> = 1 //declaratie variabelen List<string> geslaagdenList = new List<string>(); string naam = null; int index = 0; //SCHERM 1 //aantal opgenomen items in list Console.WriteLine("Aantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n"); Console.Write("Geef naam van 1ste geslaagde student in: "); naam = Console.ReadLine(); //naam toevoegen aan list geslaagdenList.Add(naam); Console.WriteLine("\nGeslaagde student: " + geslaagdenList[0]); Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n");

H8VB1 ADD()
Toevoegen van 4 studenten Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde student: student: student: student: student: Ann Peeters Jacobus Franken Corneel Claes s502334 Frank Delvaux

Aantal opgenomen items in List<T> = 5 //SCHERM 2 Console.WriteLine("Toevoegen van 4 studenten\n"); geslaagdenList.Add("Jacobus"); geslaagdenList.Add("Jacobus Franken"); geslaagdenList.Add("Corneel Claes"); geslaagdenList.Add("s502334"); geslaagdenList.Add("Frank Delvaux"); for (index = 0; index < geslaagdenList.Count; index++) { Console.WriteLine("Geslaagde student " + (index + 1) + ": " + geslaagdenList[index]); Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n"); }

H8VB1 ADDRANGE() Methode AddRange() voegt achteraan alle elementen van een collec tie toe aan de List<T>. Collectie kan zijn:

string[] namenArray = new string[] {"Walter Pruts", "Peggy Aerts"}; geslaagdenList.AddRange(namenArray); geslaagdenList.AddRange(new string[] {"Walter Pruts", "Peggy Aerts"});

Toevoegen van een reeks studenten Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde Geslaagde student: student: student: student: student: student: student: student: student: student: Ann Peeters Jacobus Franken Corneel Claes s502334 Frank Delvaux Marla Cools Piet Oeyen Annie Put Greet Deferm Zulna Eerdekens

Aantal opgenomen items in List<T> = 10 //SCHERM 3 Console.WriteLine("Toevoegen van een reeks studenten\n"); geslaagdenList.AddRange(new string[] {"Karla Cools", "Piet Oeyen", "Annie Put", "Greet Deferm", "Zulna Eerdekens"}); for (index = 0; index < geslaagdenList.Count; index++) { Console.WriteLine("Geslaagde student " + (index + 1) + ": " + geslaagdenList[index]); Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n"); }

21

H8VB1 INSERT(), INSERTRANGE(), FOREACH Methode Insert(): Voegt een item toe aan de List op een bepaalde plaats. Methode InsertRange(): Voegt items toe aan de List vanaf een bepaalde plaats.

string[] namenArray = new string[] {"Walter Pruts", "Peggy Aerts"}; geslaagdenList.InsertRange(4, namenArray); geslaagdenList.InsertRange(4, new string[] {"Walter Pruts", "Peggy Aerts"});

Foreach: Voor elk element van een collectie worden de statements horend bij foreach uitgevoerd. Geen controle nodig om het einde van de iteratie te bepalen. break; kan gebruikt worden om de foreach vroegtijdig te stoppen. continue; kan gebruikt worden om een item over te slaan.
foreach (string student in geslaagdenList)

string: datatype van n element student: naam van n element geslaagdenList: collectienaam

Tussenvoegen van Marjan Iven na element 3 Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Ann Peeters Jacobus Franken Corneel Claes Marjan Iven s502334 Frank Delvaux Marla Cools Piet Oeyen Annie Put Greet Deferm Zulna Eerdekens

Aantal opgenomen items in List<T> = 11 //SCHERM 4 Console.WriteLine("Tussenvoegen van \Marjan Iven\ na element 3\n"); geslaagdenList.Insert(3, "Marjan Iven"); foreach (string student in geslaagdenList) { Console.WriteLine("Geslaagd: " + student); } Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n");

H8VB1 REMOVE(), REMOVEAT() Methode Remove(): Verwijdert het eerste element dat voldoet aan de parameterwaarde. Methode RemoveAt(): Verwijdert het object waarvan de index als parameter wordt vermeld.
Verwijderen van s5052334 Verwijderen van laatste item Zulma Eerdekens Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Ann Peeters Jacobus Franken Corneel Claes Marjan Iven Frank Delvaux Marla Cools Piet Oeyen Annie Put Greet Deferm

Aantal opgenomen items in List<T> = 11 //SCHERM 5 Console.WriteLine("Verwijderen van \s5052334\\n"); geslaagdenList.Remove("s5052334"); Console.WriteLine("Verwijderen van laatste item " + geslaagdenList[geslaagdenList.Count - 1] + "\n"); geslaagdenList.RemoveAt(geslaagdenList.Count - 1);

22

H8VB1 SORT(), REMOVERANGE() Methode Sort(): Sorteren van een List<T> heeft dezelfde mogelijkheden als van een array (zie H5 zelfstudie). Methode RemoveRange(): Verwijdert een aantal elementen bepaald door count vanaf de opgegeven index.
Gesorteerde list (Voor) Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Ann Peeters Annie Put Corneel Claes Frank Delvaux Greet Deferm Jacobus Franken Karla Cools Marjan Iven Piet Oeyen Zulna Eerdekens

Aantal opgenomen items in List<T> = 10 Verwijderen van items 2 t/m 4 Annie Put Corneel Claes Frank Delvaux Gesorteerde list (Na) Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Geslaagd: Ann Peeters Greet Deferm Jacobus Franken Karla Cools Marjan Iven Piet Oeyen Zulna Eerdekens

Aantal opgenomen items in List<T> = 7 //SCHERM 6 geslaagdenList.Sort(); Console.WriteLine("Gesorteerde lost (Voor)\n"); foreach (string student in geslaagdenList) { Console.WriteLine("Geslaagd: " + student); } Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n"); Console.WriteLine("\nVerwijderen van items 2 t/m 4\n"); for (index = 1; index <= 3; index++) { Console.WriteLine("\t" + geslaagdenList[index]); } geslaagdenList.RemoveRange(1, 3); Console.WriteLine("Gesorteerde lost (Na)\n"); foreach (string student in geslaagdenList) { Console.WriteLine("Geslaagd: " + student);

Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n");

H8VB1 CLEAR() Methode Clear(): Verwijdert ALLE elementen van de List<T>


List leegmaken Aantal opgenomen items in List<T> = 0 //SCHERM 7 Console.WriteLine("List leegmaken\n"); geslaagdenList.Clear(); foreach (string student in geslaagdenList) { Console.WriteLine("Geslaagd: " + student); } Console.WriteLine("\nAantal opgenomen items in List<T> = " + geslaagdenList.Count + "\n");

23

Inleiding Windows Applicaties

Doel van dit hoofdstuk? Met de programmeerkennis die we opgebouwd hebben, gaan we werken aan programmas met een mooiere interface. Sequenties, selectie, iteraties, arrays, lists blijven belangrijk! Bij Windowsapplicaties horen nieuwe taalelementen, die introduceren we nu. DEEL 1 LABELS, TEKSTVAKKEN EN KNOPPEN H9VB1 Start C# op Start Page Create Project Windows Form Application In de Solution Explorer zie je welke bestanden er gemaakt zijn. We gaan nu een Windows Applicatie make en hebben daarvoor een Gebruikersinterface nodig Form1.cs, Program.cs User interface Solution Explorer (verschillende knoppen) Properties Show all files Refresh View Code View Designer Viw Class Diagram Algemeen Om een applicatie te kunnen runnen heb je volgende bestanden nodig: Program.cs: Statische klasse waarvan de Main-methode wordt uitgevoerd bij het runnen van de applicatie DIT BESTAND WORDT NIET AANGEPAST! Form1.cs: Bevat alle objecten en code om het gewenste formulier te kunnen runnen. Pas de naam van het formulier aan naar FormH9VB1.cs Klik op Ja Alle verwijzingen naar Form1 worden aangepast naar FormH9VB1. Bewaar project via File Save All Doel van H9VB1 Formulier met knop en tekst. Als je klikt op de knop, komt er een tekstje in het tekstvak. Stap 1: Controls in orde brengen Je moet de juiste controls aanbrengen in het ontwerpvenster. Je kan hier ook eigenschappen van controls regelen. Controls toevoegen aan formulier via Toolbox. Voeg een knop toe aan formulier: button1 (dubbelklik in toolbox of via slepen) Name: buttonKlik Text: Klik hier Voeg een tekstvak toe aan het formulier: Name: textBoxTekst Breedte in aanpasbaar, de hoogte voorlopig niet. Pas de Text-eigenschap van het formulier aan: Text: H9 Voorbeeld 1 (verschijnt in titelbalk) Naamgeving Controls Naam van Control gevolgd door een naam die je zelf kiest, beginnend met een hoofdletter buttonKlik textBoxTekst labelTitel Eigenschappen aanpassen doe je nu in het Properties window (of later via code). Het resultaat van de aanpassing van de Text -eigenschap zie je in het formulierontwerp. Stap 2 H9VB1: Programmacode schrijven Doel van het programma Indien de gebruiker op de knop klikt, verschijnt er in het tekstvak de tekst Hallo. Hiervoor schrijven we een stukje progra mmacode. Klikken op de knop is een gebeurtenis of event. In formulieren programmeren we gebeurtenissen: Wat moet er gebeuren als een gebruiker op de knop klikt Wat moet er gebeuren als een gebruiker een keuzerondje aanvinkt De lijst van de gebeurtenissen bij een Control vind je in het eigenschappenvenster. Klik bij Properties van buttonKlik op de knop met de bliksem. Dubbelklik nu bij de gebeurtenis Click in het witte gedeelte. Volgende gebeurtenissenprocedure wordt toegevoegd. Het codevenster gaat open:

24

namespace H9VB1 { public partial class FormH9VB1: Form { public FormH9VB1() { InitializeComponent(); } private void buttonKlik_Click(object sender, EventArgs e) { ... }

} } Tussen de accolades van private void programmeer je wat er moet gebeuren als de gebruiker op de knop met naam buttonKlik geklikt heeft.
private void buttonKlik_Click(object sender, EventArgs e) { //tekst tonen in tekstvak textBoxTekst.Text = "Hallo"; }

Conclusie In het codevenster zorg je voor code voor elke gebeurtenis die zich kan voordoen. Alle code voor gebeurtenissen moet tussen de accolades van public partial class geschreven worden. TIP: Tools Options Text Editor All laguages General Line Numbers Stap 3 H9VB1: Programma testen Als je klikt op de knop, verschijnt de tekst Hallo in het tekstvak. Uitbreiding H9VB1 Voeg een label toe: Naam: labelGetal Text: Geef een getal in Grootte van label is afhankelijk van de inhoud Voe textBoxGetal toe, let op de blauwe lijnen bij uitlijning! Selecteer textBoxTekst en stel de eigenschap Multiline in op True. Het tekstvak kan nu ook hoger gemaakt worden. De gebruiker geeft nu een getal in textBoxGetal. De gebruiker klikt op de knop buttonKlik en het getal wordt getoond in textBoxTekst op een nieuwe lijn na de tekst Hallo Pas de code aan en test uit:
private void buttonKlik_Click(object sender, EventArgs e) { //tekst tonen in tekstvak textBoxTekst.Text = "Hallo" + "\r\n" + textBoxGetal.Text; }

OF BETER:
private void buttonKlik_Click(object sender, EventArgs e) { //tekst tonen in tekstvak textBoxTekst.Text = "Hallo" + Environment.NewLine + textBoxGetal.Text; }

Voeg nog twee extra knoppen toe: buttonWissen Text: Wissen buttonEinde Text: Einde Maak eventprocedures aan, vul de code aan en test uit:
private void buttonWissen_Click(object sender, EventArgs e) { //tekstvakken leegmaken textBoxTekst.Clear() textBoxGetal.Clear() } private void buttonKlik_Click(object sender, EventArgs e) { //toepassing afsluiten Application.Exit(); }

Ook het laden van het formulier is een gebeurtenis waaraan je code kan koppelen. Genereer de eventcode via het eigenschappenvenster. We passen bij het opstarten van de applicatie de titelbalk van FormH9VB1 aan:
private void FormH9VB1_Load(object sender, EventArgs e) { //titelbalk van formulier aanpassen this.Text = "Formulier H9VB1"; }

Als je een Control wilt opvullen met waarden, dan heb je twee mogelijkheden: Ofwel pas je de eigenschappen (properties) aan: in het ontwerp wordt de waarde ingevuld Ofwel zet je de gewenste waarde in de code

25

DEEL 2 MESSAGEBOX H9VB2

Control Form Label TextBox Button Label

Eigenschap FormH9VB2.cs labelDatum tekstBoxDatum buttonVerwerk labelResultaat Text: Text: Geboortedatum Verwerk gegevens

Programma om een datum in te lezen en daarna te verwerken in een berichtvenster. Afhankelijk van welke knop men in het berichtvenster klikt, berekent men de leeftijd of toont men de geboortedatum. Klikken op buttonVerwerk Er wordt gecontroleerd of er een datum werd ingevuld. Indien er geen datum werd ingevuld, verschijnt er:

Indien er wel een datum werd ingevuld, verschijnt er:

Wanneer de gebruiker Ja antwoord, berekent het programma de leeftijd. Wanneer de gebruiker Nee antwoord, toont het progra mma de geboortedatum met een lange schrijfnotatie. Bij het opstarten van de applicatie wordt de titelbalk van het formulier aangepast en wordt de label leeggemaakt. De gebruiker vult al of niet een datum in en klikt op de knop Verwerk gegevens. We controleren nu of er een correcte datum werd ingegeven en tonen een gepaste boodschap.
private void H9VB2_Load(object sender, EventArgs e) { //initialiseren labelResultaat.Text = ""; this.Text = "H9 Voorbeeld 2"; } private void buttonVerwerk_Click(object sender, EventArgs e) { //declaratie DateTime datum; DialogResult antwoord; int leeftijd = 0; //datum ingevuld? if (DateTime.TryParse(textBoxDatum.Text, out datum) == false) { MessageBox.Show("Sorry, geen correcte datum ingevuld", "Keuze", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxDatum.Clear(); textBoxDatum.Focus(); } else { //leeftijd of geboortedatum antwoord = MessageBox.Show(this, "Wens je de leeftijd of de geboortedatum", "Ingevulde datum: " + textBoxDatum.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question, messageBoxDefaultButton.Button2); if (antwoord == DialogResult.Yes) { leeftijd = DateTime.Now.Year - datum.Year; labelResultaat.Text = "Je leeftijd is " + leeftijd; } else { labelResultaat.Text = "Geboortedatum: " + datum.ToLongDateString(); } } }

26

Methode textBox.Focus(): Zorgt ervoor dat de cursor in het tekstvak komt te staan. Methode textBox.Clear(): Zorgt ervoor dat het tekstvak wordt leeggemaakt. MessageBox.Show(): Om een berichtvenster te tonen gebruik je de methode Show() van de klasse
MessageBox.Show Method (string Tekst, string Caption, MessageBoxButtons, MessageBoxIcon)

Caption: Tekst van titelbalk Tekst: Tekst die in berichtvenster komt Buttons: Knoppen (AbortRetryIgnore, OK, OKCancel, RetryCancel, YesNo, YesNoCancel) Icon: Pictogrammen (Asterisk, Error, Exclamation, Hand, Information, None, Question, Stop, Warning )

public static DialogResult Show(string Text, string Caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton, defaultButton, MessageBoxOptions options ) Resultaat is van het type DialogResult, dus opvangen in een variabele van dat type.

Defaultbutton: Standaardknop instellen Options: Weergave opties en associatie opties

DateTime Properties
datum.Date datum.Day datum.DayOfWeek datum.DayOfYear datum.Hour datum.Millisecond datum.Minute datum.Month DateTime.Now datum.Second datum.Ticks datum.TimeOfDay DateTime.Today DateTime.UtcNow datum.Year 13/01/2011 0:00:00 13 Thursday 13 21 502 52 1 13/01/2011 21:52:05 5 634305523255027999 21:52:0.5027999 13/01/2011 0:00:00 13/01/2011 20:52:05 2011

27

Zelfstudie 3

Opmaakeigenschappen

Letterstijl instellen this.Font = new Font ("Verdana", 12, FontStyle.Bold); Werken met kleuren Je kan werken met voorgedefinieerde kleuren uit de Color-emuratie: labelRood.ForeColor = Color.Red; Je kan ool zelf kleuren mengen met Color.FromArgb(hoeveel rood, hoeveel groen, hoeveel blauw) Geldige waarden voor de hoeveelheden van een bepaalde kleur: 0 t/m 255 labelRood.ForeColor = Color.FromArgb(255, 0, 0); Met de eigenschap BackColor kan je de achtergrondkleur van een control instellen this.BackColor = Color.FromArgb(255, 255, 255); Met de eigenschap ForeColor kan je de tekstkleur van een control instellen this.BackColor = Color.FromArgb(0, 0, 0); Dock-property Om een control te verankeren aan formulier (Bottom, Fill, Left, None, Right, Top) buttonKleuradvies.Dock = DockStyle.Bottom; Positie bepalen Eigenschappen ivm grootte: Height (hoogte van een object); Width (breedte van een object) labelRood.Height = 30;
labelRood.Width = 150;

Eigenschappen ivm positie: Top (afstand tov bovenzijde van formulier/scherm); Left (afstand tov linkerzijde) labelRood.Top = 0;
labelRood.Left = 0;

In plaats van met Left, Top, Width en Height te werken, kan je de verzameleigenschappen Location en Size of de methode SetBounds() gebruiken. labelGroen.Location = new Point (150, 0);
labelGroen.Size = new Size (150, 30); labelGroen.Text = "Groen (0-255)";

labelBlauw.SetBounds = (300, 0, 150, 30);


labelBlauw.Location = "Blauw (0-255)";

Complementaire kleuren Complementaire kleuren zijn kleuren die tegenover elkaar staan in de kleurencirkel. In het RGB-systeem zijn complementaire kleuzen gemakkelijk te berekenen: De som van de waarden in beide kleuren voor RGB is telkens 255. Bijvoorbeeld: Cyaan rgb(0, 255, 255) Rood rgb(255, 0, 0) H9VB3
private void Form1_Load(object sender, EventArgs e) { //applicatie om kleuradvies te geven //formulier regelen this.Text = "Complementaire kleuren"; this.Font = new Font("Verdana", 12, FontStyle.Bold); //knop regelen buttonKleuradvies.Text = buttonKleuradvies.Font = buttonKleuradvies.Dock = buttonKleuradvies.Height "Kleuradvies"; new Font("Verdana", 14, FontStyle.Italic); DockStyle.Bottom; = 100;

//labels regelen labelRood.Top = 0; labelRood.Left = 0; labelRood.Height = 30; labelRood.Width = 150; labelRood.Text = "Rood (0-255)"; labelGroen.Location = new Point(150, 0); labelGroen.Size = new Size(150, 30); labelGroen.Text = "Groen (0-255)"; labelBlauw.SetBounds(300, 0, 150, 30); labelBlauw.Text = "Blauw (0-255)"; //tekstvakken regelen textBoxRood.Location = new Point(20, 50); textBoxGroen.Location = new Point(170, 50); textBoxBlauw.Location = new Point(320, 50); } private void buttonKleuradvies_Click(object sender, EventArgs e) { //declaratie Color kleur1, kleur2; int rood, groen, blauw; rood = Convert.ToInt32(textBoxRood.Text); groen = Convert.ToInt32(textBoxGroen.Text); blauw = Convert.ToInt32(textBoxBlauw.Text); // kleuren invullen kleur1 = Color.FromArgb(rood,groen, blauw); kleur2 = Color.FromArgb(255 - rood, 255 - groen, 255 - blauw); this.BackColor = kleur1; buttonKleuradvies.BackColor = kleur2; labelRood.ForeColor = kleur2; labelGroen.ForeColor = kleur2; labelBlauw.ForeColor = kleur2; }

28

10

Operaties met in-parameters zonder returnwaarde

Operaties zonder returnwaarde In dit hoofdstuk gaan we code nog compacter, efficinter en overzichtelijker maken met behulp van operaties. Je programmeert operaties om je programmacode in stukjes te kunnen verdelen die elk een duidelijk omschreven taak uitvoeren. De operaties die we H10 programmeren zijn ZONDER RETURNWAARDE, dit betekent dat ze niets teruggeven aan het oproepend programma. H10VB1
Datum: Tijd: 28/06/2010 10:23:36

Gebruikersnaam: hannah Paswoord: code37 ****************************** Toepassing geactiveerd Datum: 28/06/2010 Tijd: 10:24:29 ****************************** Datum: Tijd: 28/06/2010 10:25:44

Gebruikersnaam: jan Paswoord: code45 ****************************** Toepassing geblokkeerd Datum: 28/06/2010 Tijd: 10:26:02 ****************************** namespace H10VB1 { class Program { static void Main(string[] args) { //declaratie string gebruikersnaam, paswoord; int teller; //schermkleuren ... //weergeven datum en tijd Console.WriteLine("Datum: \t" + DateTime.Now.ToShortDateString()); Console.WriteLine("Tijd: \t" + DateTime.Now.ToLongTimeString()); Console.WriteLine(); //inlezen Console.Write("Gebruikersnaam: "); gebruikersnaam = Console.ReadLine(); Console.Write("Paswoord: "); paswoord = Console.ReadLine(); Console.WriteLine(); //* drukken for (teller = 1; teller <= 30; teller++) { Console.Write("*"); } Console.WriteLine(); //controle login if (gebruikersnaam.ToLower() == "hannah" && paswoord == "code37") { Console.WriteLine("Toepassing geactiveerd"); } else { Console.WriteLine("Toepassing geblokkeerd"); } Console.WriteLine(); //weergeven datum en tijd Console.WriteLine("Datum: \t" + DateTime.Now.ToShortDateString()); Console.WriteLine("Tijd: \t" + DateTime.Now.ToLongTimeString()); //* drukken for (teller = 1; teller <= 30; teller++) { Console.Write("*"); } //wachten op enter Console.ReadLine(); } } }

Bespreking We hebben de code de * lijn te drukken 2 keer geschreven dubbele code vermijden! OPLOSSING: Werken met een string lijn en die opvullen OF BETER: De identieke lijnen code afzonderen en hergebruiken

29

Operatie In dit hoodstuk werken we de oplossing uit met een operatie Drukken() waarin we de identieke lijnen code plaatsen. Waar nodig roepen we de operatie op. De operatie Drukken() is een nieuwe operatie zonder returnwaa rde met als operatiedefinitie: private static void Drukken() In de main-operatie roep je deze operatie op met Drukken(). Datum en tijd worden 2 keer op het scherm getoond. Codeer ook een operatie DatumTijd() om de huidige datum en tijd op het scherm te tonen. Vervang in operatie Main() de bestaande code door een oproep van deze operatie. H10VB1 MET OPERATIE
namespace H10VB1 { class Program { static void Main(string[] args) { //declaratie string gebruikersnaam, paswoord; int teller; //schermkleuren ... //operatie oproepen DatumTijd(); Console.WriteLine(); //inlezen Console.Write("Gebruikersnaam: "); gebruikersnaam = Console.ReadLine(); Console.Write("Paswoord: "); paswoord = Console.ReadLine(); Console.WriteLine(); //operatie oproepen Drukken(); //controle login if (gebruikersnaam.ToLower() == "hannah" && paswoord == "code37") { Console.WriteLine("Toepassing geactiveerd"); } else { Console.WriteLine("Toepassing geblokkeerd"); } Console.WriteLine(); //operatie oproepen DatumTijd(); Drukken(); //toepassing beindigen Console.ReadLine(); } private static void Drukken() { //declaratie int teller; //* drukken for (teller = 1; teller <= 30; teller++) { Console.Write("*"); } Console.WriteLine(); private static void DatumTijd() { //weergeven datum en tijd Console.WriteLine("Datum: \t" + DateTime.Now.ToShortDateString()); Console.WriteLine("Tijd: \t" + DateTime.Now.ToLongTimeString()); } } }

H10VB1 (uitbreiding) Codeer dat er een stippellijn (30 keer ) wordt gedrukt boven en onder de eerste datum/tijd melding. Een nieuwe procedure DrukStippelLijn() Deze wordt twee keer opgeroepen in Main()
static void Main(string[] args) { ... //- drukken DrukStippelLijn(); //operatie oproepen DatumTijd(); //- drukken DrukStippelLijn(); ... } private static void DrukStippelLijn() { //declaratie int teller; //* drukken for (teller = 1; teller <= 30; teller++) { Console.Write("-"); } Console.WriteLine(); }

30

Enige verschil tussen de twee operaties Drukken() en DrukStippelLijn() is het teken (* of -) dat 30 keer moet herhaald worden. Alle overige code in de twee operaties is gelijk. 1 OPERATIE LijnTekenen() waaraan we via een parameter doorgeven welk teken gedrukt moet worden. Als we informatie (* of -) doorgeven aan de operatie, dan moet de operatie deze informatie opvangen. Bij de operatie definitie staan dus GEEN LEGE HAAKJES. Binnen de haakjes wordt de variabele geschreven die de informatie opvangt. private static LijnTekenen(string teken) string: het datatype van de waarde die we doorgeven teken: de IN-PARAMETER of de naam van de variabele waarin we de doorgestuurde informatie opvangen We geven een waarde door. De operatie mag die waarde gebruiken, maar kan die niet gewijzigd terugsturen naar het programma dat LijnTekenen() oproept.
private static void LijnTekenen(string teken) { //declaratie int teller; //teken drukken for (teller = 1; teller <= 30; teller++) { Console.Write(teken); } Console.WriteLine(); }

Vervang in Main() de oproep van zowel Drukken() als DrukkenStipelLijn() door LijnTekenen(). Drukken() wordt vervangen door: LijnTekenen("*") DrukkenStippelLijn() wordt vervangen door: LijnTekenen("-")

Terminologie Operatiedefinitie: private static void LijnTekenen(string teken) In-parameter of formele parameter: (string teken) Operatieoproep: LijnTekenen( "*"); Uitbreiden LijnTekenen() We willen aan de operatie kunnen doorgeven met welk teken de lijn moet gedrukt worden EN hoeveel keer het teken herhaald moe t worden (nu standaard 30 keer) 2 IN-PARAMETERS: TEKEN EN AANTAL
private static void LijnTekenen(string teken, int aantal) { //declaratie int teller; //teken drukken for (teller = 1; teller <= aantal; teller++) { Console.Write(teken); } Console.WriteLine(); }

Aanpassen operatieoproep in Main(): Bijvoorbeeld 20 keer - LijnTekenen("-", 20);

31

11

Operaties met in-parameters en met returnwaarde

Operaties met returnwaarde In dit hoofdstuk gaan we opnieuw code nog compacter, efficinter en o verzichtelijker maken met behulp van operaties. De operaties die we in H11 programmeren zijn MET RETURNWAARDE, dit betekent dat ze een waarde teruggeven aan het oproepend programma. H11VB1
Wat hebt u gekocht? peren Wat is de prijs exclusief BTW? 10 BTW-code 1 of 2? 1 Prijs inclusief BTW: 10,6 Wat hebt u gekocht? boek Wat is de prijs exclusief BTW? 10 BTW-code 1 of 2? 2 Prijs inclusief BTW: 12,1 namespace H11VB1 { class Program { static void Main(string[] args) { //declaratie string artikel = null; double prijsExclusief = 0.0, prijsInclusief = 0.0; int code = 0; const double BTW_VOEDING = 6.0; const double BTW_OVERIGE = 21.0; //schermkleuren ... //inlezen Console.Write("Wat hebt u gekocht? "); artikel = Console.ReadLine(); Console.Write("Wat is de prijs exclustief BTW? "); prijsExclusief = Convert.ToInt32(Console.ReadLine()); Console.Write("BTW-code 1 of 2? "); code = Convert.ToInt32(Console.ReadLine()); //verwerken if (code == 1) { prijsInclusief = BerekenBTW(prijsExclusief, BTW_VOEDING); else { prijsInclusief = BerekenBTW(prijsExclusief, BTW_OVERIGE); Console.WriteLine("\nPrijs Inclusief BTW: " + prijsInclusief); //toepassing sluiten Console.ReadLine(); } private static double BerekenBTW(double bedragExclusiefBTW, double hoeveelBTW) { //declaratie double bedragInclusiefBTW = 0.0; //bereken bedragInclusiefBTW = bedragExclusiefBTW * (1 + hoeveelBTW / 100); //terugkeerwaarde return bedragInclusiefBTW; } } }

} }

Constanten Constanten zijn gegevens die vastliggen en die in de loop van het programma niet gewijzigd worden. We declareren constanten met het woord const. We initialiseren cons tanten meteen. Namen van constanten worden volledig in hoofdletters geschreven? Deelwoorden worden gescheiden met _ Operatie: private static double BerekenBTW(double bedragExclusiefBTW, double hoeveelBTW) Private static double want er is nu wl een returnwaarde en die heeft het formaat double. Hier zijn er twee formele parameters om informatie te kunnen doorgeven aan BerekenBTW. De operatie geeft een bedrag inclusief BTW terug. Operatie met returnwaarde Concrete werkwijze in de operatie: Declareer een variabele van het type van de returnwaarde Bereken het eindresultaat Return om de berekende waarde aan het oproepend programma door te geven

32

H11VB2
Prijs? Test Prijs? Prijs? -20 Prijs? 100 Aantal? Test Aantal? Aantal? -10 Aantal? 10 Te betalen exclusief BTW: 1000 Te betalen inclusief BTW: 1210

Twee keer dubbele invoercontrole, daarna berekening en tonen van het resultaat.
static void Main(string[] args) { //declaratie string prijsTekst, aantalTekst; int prijs, aantal; double teBetalenInclusief = 0.0, teBetalenExclusief = 0.0; const double BTW = 21.0; //inlezen do { do { Console.Write("Prijs? "); prijsTekst = Console.ReadLine(); } while (int.TryParse(prijsTekst, out prijs) == false); } while (prijs <= 0); do { do { Console.Write("Aantal? "); aantalTekst = Console.ReadLine(); } while (int.TryParse(aantalTekst, out aantal) == false); } while (aantal <= 0); //verwerken teBetalenExclusief = prijs * aantal; teBetalenInclusief = BerekenBTW(teBetalenExclusief, BTW); //resultaat tonen Console.WriteLine("\nTe betalen exclusief BTW: " + teBetalenExclusief); Console.WriteLine("Te betalen inclusief BTW: " + teBetalenInclusief); Console.ReadLine(); }

private static double BerekenBTW(double bedragExclusiefBTW, double hoeveelBTW) { //declaratie double bedragInclusiefBTW = 0.0; //bereken bedragInclusiefBTW = bedragExclusiefBTW * (1 + hoeveelBTW / 100); //terugkeerwaarde return bedragInclusiefBTW; }

Dubbele invoercontrole in operatie met returnwaarde We kunnen de dubbele code in dit voorbeeld vermijden door een operatie met returnwaarde te schrijven waarin invoercontrole g ebeurt in plaats van berekening. Het doel van de operatie is een correct getal teruggeven aan het hoofdprogramma. Schrijf de volgende operatiedefinitie:
private static int GeldigGeheelGetalOpvragen(string tekst)

static void Main(string[] args) { ... //inlezen prijs = GeldigGeheelGetalOpvragen("Prijs? "); aantal = GeldigGeheelGetalOpvragen("Aantal? "); ... } private static int GeldigGeheelGetalOpvragen(string tekst) { //declaratie string getalTekst = null; int getal = 0; //inlezen do { do { Console.Write(tekst); getalTekst = Console.ReadLine(); } while(int.TryParse(getalTekst, out getal) == false); } while(getal <= 0); //terugkeerwaarde return getal; }

33

H11VB3
Aantal Aantal Aantal Aantal Aantal Aantal Aantal Aantal Aantal Aantal kilometer? (9999 kilometer? (9999 kilometer? (9999 kilometer? (9999 liter? test liter? -10 liter? 50 kilometer? (9999 liter? 10 kilometer? (9999 om om om om te te te te stoppen) stoppen) test stoppen) -10 stoppen) 500

om te stoppen) 100 om te stoppen) 9999

U tankte 2 keer. U reed totaal 600 kilometer. U tankte in totaal 60 liter. Verbruik: 10 liter/100km Druk op enter static void Main(string[] args) { //declaratie double kilometer = 0, liter = 0, totaalKilometer = 0, totaalLiter = 0, verbruik = 0; int aantalTankbeurten = 0; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //inlezen, priming read kilometer = GeldigGeheelGetalOpvragen("Aantal kilometer? (9999 om te stoppen) ", ConsoleColor.Blue); //verwerken // bij het begin van de lus kritieke waarde controleren while (kilometer != 9999) { //verder werken met correcte waarde totaalKilometer += kilometer; aantalTankbeurten++; liter = GeldigGeheelGetalOpvragen("Aantal liter? ", ConsoleColor.Red); totaalLiter += liter; //opnieuw kritieke waarde opvragen kilometer = GeldigGeheelGetalOpvragen("Aantal kilometer? (9999 om te stoppen) ", ConsoleColor.Blue); } if (aantalTankbeurten > 0) { verbruik = Math.Round(totaalLiter / totaalKilometer * 100, 2); //resultaat op nieuw scherm tonen Console.Clear(); Console.WriteLine("U tankte " + aantalTankbeurten + " keer."); Console.WriteLine("U reed in totaal " + totaalKilometer + " kilometer."); Console.WriteLine("U tankte in totaal " + totaalLiter + " liter."); Console.WriteLine("\nVerbruik: " + verbruik + " liter/100km."); } //wachten op enter Console.WriteLine("\nDruk op enter"); Console.ReadLine(); } private static int GeldigGeheelGetalOpvragen(string tekst, ConsoleColor kleur) { //declaratie string getalTekst; int getal; //verwerken do { do { Console.Write(tekst); Console.ForegroundColor = kleur; getalTekst = Console.ReadLine(); Console.ForegroundColor = ConsoleColor.Black; } while (int.TryParse(getalTekst, out getal) == false); } while (getal <= 0); //terugkeerwaarde return getal; }

34

12

Operaties met in/uit-parameters of referentieparameters

H12VB1 Dit project is een klein onderdeel van een programma dat de puntenregistratie op school regelt. In het hoofdprogramma lezen we een score van een student in. In de operatie NieuweScore wordt de nieuwe score van de student opgevraagd. In het hoofdprogramma krijg je na de wijziging te zien wat de score geworden is.
De huidige score is: 77 Wat is de nieuwe score? 85 De score is nu 85

OPLOSSING 1 MET RETURNWAARDE WERKEN


static void Main(string[] args) { //declaratie int score = 77, nieuweScore; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //resultaat op scherm afbeelden nieuweScore = NieuweScore(score); Console.WriteLine("De score is nu " + nieuweScore); //wachten op enter Console.ReadLine(); } private static int NieuweScore(int punten) { Console.WriteLine("De huidige score is: " + punten); Console.Write("Wat is de nieuwe score? "); punten = Convert.ToInt32(Console.ReadLine()); return punten; }

Deze oplossing werkt, maar we kunnen slechts n terugkeerwaarde terugsturen. Als we meerdere variaben in ons hoofdprogram ma wensen aan te passen vanuit onze operatie, dan volstaat deze techniek niet! OPLOSSING 2 OPERATIE MET IN/UIT-PARAMETERS Van waardeparameter of in-parameter naar referentieparameter of in/uit-parameter: Waarde parameter of in-parameter De waarde van de variabele op het moment van de aanroep wordt doorgegeven aan de operatie, de operatie mag die waarde gebruiken. Referentieparameter of in/uit-parameter Bij de aanroep van de operatie wordt de variabele vanuit het hoofdprogramma gekoppeld aan de variabele in de operatie. Eigenlijk zijn ze dezelfde variabele. De operatie mag de inhoud van die variabele wijzigen.
static void Main(string[] args) { //declaratie int score = 77; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); //resultaat op scherm afbeelden NieuweScore(ref score); Console.WriteLine("De score is nu " + score); //wachten op enter Console.ReadLine(); } private static void NieuweScore(ref int punten) { Console.WriteLine("De huidige score is: " + punten); Console.Write("Wat is de nieuwe score? "); punten = Convert.ToInt32(Console.ReadLine()); }

Er is n plaats in het geheugen die wordt aangesproken door: Main() via score en NieuweScore() via punten. In Main() wordt de score genitialiseerd In de operatie NieuweScore() lezen we de nieuwe waarde in enn wordt die in de variabele punten gezet. We kunnen met deze techniek een variabele aanpassen in de operatie en deze waarde in ons hoofdprogramma gebruiken. Als we meerdere variabelen in ons hoofdprogramma wensen aan te passen vanuit onze operatie, dan kan dit door van deze variabelen in/uit -parameters te maken. De parameter mag niet als waarde ingelezen worden (in-parameter), we moeten ook een referentie naar de oorspronkelijke variabele meegeven (ref in/uit-parameter).

35

In versus in/uit In een operatie zonder returnwaarde en in een operatie met returnwaarde kunnen meerdere parameters voorkomen . Deze parameters moeten niet allemaal van dezelfde soort zijn, je kan n of meerdere waardeparameters combineren met n of meerdere referentieparameters (ref). Let op! Operaties moeten afgeschermde, zo zelfstandig mogelijke gehelen vormen! Alle waarden van buiten de operatie worden via waarde- of referentieparameters binnengebracht. Schrijf de operatiedefinitie zo nauwkeurig mogelijk. Gebruik ref alleen als dat strikt noodzakelijk is. De operatie oproep moet overeenkomen met de operatiedefinitie: Aantal parameters Type parameters Parameters in de juiste volgorde Terugkeerwaarde H12VB1 (uitbreiding) We willen in deze applicatie nog extra lijnen en blancos:
************************************************************ De huidige score is: 77 Wat is de nieuwe score? 85 ************************************************************ De score is nu 85

De sterlijnen zijn 60 tekens breed, voor de laatste zin staan 6 blancos. Programmeurs moeten vaak lijnen maken. In C# is er daarom een constructor voorzien om snel lijnen te genereren. Voordeel: Je moet zelf de for-lus niet meer schrijven. Nadeel: C# heeft de controle, voor ons is die constructor als een zwarte doos. Constructor new String(char c, int count) Een char is een variabele die als inhoud maar n teken heeft. Dit kan dus of n letter, n cijfer of n leesteken zijn. De inhoud van een char staat ALTIJD tussen enkele quotes ' ' en heeft als waarde ALTIJD maar 1 teken. Hoe gebruik je die constructor? BIJ DECLARATIE meteen instantiren:
string lijn = new String('*', 60);

OF LATER in het programma nog instantiren:


Console.WriteLine(new String(' ', 6) + "De score is nu " + score);

36

Zelfstudie 4

De klasse Array Deel 2

H12VB2 In dit voorbeeld is niet op voorhand geweten hoeveel namen er ongelezen gaan worden. Er wordt hier niet met een list gewerkt, maar wel met een array. Een array declareren zonder echte inhoud doe je door die bij het declareren gelijk te stellen aan null. Je kan die vermelding = null niet weglaten, anders krijg je foutmeldingen.
//declaratie string[] namenArray = null; string antwoord; int aantal = 1;

Wanneer je een geldig antwoord gekregen hebt, kan je dat in de array stoppen. Je moet er wel zelf voor zorgen dat die array groot genoeg wordt. Dit kan je doen door de methode Resize() van de klasse Array te gebruiken. Je gebruikt Array.Resize() dus om de afmetingen van een array naar een nieuwe grootte te brengen. Eerst geef je de naam van de array die aangepast moet worden, daarna zeg je hoeveek ingangen de array moet krijgen. De methode komt nu pas aan bod omdat de array als in/uit-parameter moet meegegeven worden. Je moet dus ref schrijven voor de naam van de array die je wil aanpassen. Eens de array de juiste afmetingen heeft, kan je met de volgende code op de laatste ingang van de array iets wegschrijven
namenArray[namenArray.GetUpperBound(0)] = antwoord; //kritieke waarde lezen Console.Write("Naam " + aantal + " aub: "); antwoord = Console.ReadLine(); //lus met controle vooraan while (antwoord != "") { //array uitbreiden en vullen Array.Resize(ref namenArray, aantal); namenArray[namenArray.GetUpperBound(0)] = antwoord; //aantal ophogen aantal++; //opnieuw vraag stellen Console.Write("Naam " + aantal + " aub: "); antwoord = Console.ReadLine(); }

Je kan hier ook gebruik maken van Environment.NewLine, die we tot nu toe enkel in Windowsapplicaties gebruikt hebben. Tot slo t wordt er ook gellustreerd dat de foreach-lus ook gebruikt kan worden voor een gewone array. Tot hiertoe gebruikten we deze alleen nog maar bij een List.
//overzicht tonen indien er namen opgenomen zijn if (aantal > 1) { Console.Clear(); Console.WriteLine("Overzicht" + Environment.NewLine); foreach (string naam in namenArray) { Console.WriteLine(new string(' ', 10) + naam); } //wachten op enter Console.WriteLine("\nDruk op enter om de toepassing te beindigen"); Console.ReadLine(); }

H12VB3 Dit programma laat je toe op een eenvoudige en snelle manier gegevens in een array op te zoeken. Deze array moet hiervoor niet gesorteerd zijn. Array.IndexOf(): Zoekt in array het eerste element met de waarde van value en geeft de index van het gevonden element terug indien value voorkomt in array. Als value niet voorkomt in array geeft het de waarde -1 terug. Array.Length(): Hiermee kan je opvragen uit hoeveel elementen een array bestaat.
//declaratie string[] voornaamArray = { "Jan", "Bart", "Ann", "Bart", "Frank", "Bart", "Ann", "Chris" }; string[] naamArray = { "Peeters", "Claes", "Oeyen", "Peeters", "Mertens", "Maes", "Janssens", "Claes" }; string[] woonplaatsArray = { "Geel", "Mol", "Herentals", "Olen", "Mol", "Geel", "Geel", "Oevel" }; string voornaam; int index = 0, gevondenIndex, startZoekIndex; //lijst tonen Console.WriteLine("VOORNAAM EN NAAM" + "\t" + "WOONPLAATS"); for (index = 0; index <= naamArray.GetUpperBound(0); index++) { Console.Write(voornaamArray[index] + " " + naamArray[index] + "\t\t" + woonplaatsArray[index] + "\n"); } //naam opvragen Console.Write("\n" + "Welke voornaam wens je op te zoeken? "); voornaam = Console.ReadLine(); Console.WriteLine(); //EERSTE INDEX ZOEKEN gevondenIndex = Array.IndexOf(voornaamArray, voornaam); if (gevondenIndex != -1) {

37

Console.WriteLine(voornaam + " komt de eerste keer voor in element " + (gevondenIndex + 1)); //startZoekIndex aanpassen voor volgende te zoeken index startZoekIndex = gevondenIndex + 1; //VOLGENDE INDEX ZOEKEN gevondenIndex = Array.IndexOf(voornaamArray, voornaam, startZoekIndex); while (gevondenIndex != -1 && startZoekIndex < naamArray.Length - gevondenIndex) { //tonen volgende index Console.WriteLine(voornaam + " komt de volgende keer voor in element " + (gevondenIndex + 1)); //opnieuw volgende index zoeken startZoekIndex = gevondenIndex + 1; gevondenIndex = Array.IndexOf(voornaamArray, voornaam, startZoekIndex); } //LAATSTE GEVONDEN INDEX if (gevondenIndex != -1 && startZoekIndex < naamArray.Length) { gevondenIndex = Array.LastIndexOf(voornaamArray, voornaam); Console.WriteLine(voornaam + " komt de laatste keer voor in element " + (gevondenIndex + 1)); } } else { Console.WriteLine(voornaam + " komt niet voor in de lijst."); //wachten op enter Console.ReadLine();

H12VB4 Dit programma laat je toe om drie arrays, namelijk voornaamArray, naamArray en woonplaatsArray, te sorteren volgens naamArray . Om drie arrays te sorteren, moet je een copy maken van de array die de volgorde bepaalt. Array.Copy(): Enkel bruikbaar in een 1-dimensionele array, er moet een doelarray gedimemsioneerd zijn en de doelarray mag niet leeg zijn!
//declaratie string[] voornaamArray = { "Jan", "Bart", "Ann", "Bart", "Frank", "Bart", "Ann", "Chris" }; string[] naamArray = { "Peeters", "Claes", "Oeyen", "Peeters", "Mertens", "Maes", "Janssens", "Claes" }; string[] woonplaatsArray = { "Geel", "Mol", "Herentals", "Olen", "Mol", "Geel", "Geel", "Oevel }; string[] hulpArray = new string[naamArray.GetUpperBound(0) + 1]; int index = 0; //schermkleur aanpassen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //ongesorteerde lijst tonen Console.WriteLine("NIET GESORTEERD" + Environment.NewLine); for (index = 0; index <= naamArray.GetUpperBound(0); index++) { Console.Write(voornaamArray[index] + " " + naamArray[index] + "\t" + "\t" + woonplaatsArray[index] + "\n"); } //kopiren van naamArray naar hulpArray Array.Copy(naamArray, hulpArray, naamArray.Length); //sorteren van 3 arrays in volgorde van naam Array.Sort(naamArray, voornaamArray); Array.Sort(hulpArray, woonplaatsArray); //lijst tonen op naam gesorteerd Console.WriteLine(Environment.NewLine + "WEL GESORTEERD" + Environment.NewLine); for (index = 0; index <= naamArray.GetUpperBound(0); index++) { Console.Write(voornaamArray[index] + " " + naamArray[index] + "\t" + "\t" + woonplaatsArray[index] + "\n"); } Console.ReadLine();

38

H12VB5 Dit programma laat je toe om een string te splitsen. Het resultaa t komt in een array.
//declaratie string[] woordenArray = null; int index = 0; //EERSTE VOORBEELD string zin = "We gaan via deze weg de split uitleggen :)"; //zin splitsen met scheidingsteken (van type char!) spatie woordenArray = zin.Split(' '); //resultaat tonen Console.WriteLine("scheidingsteken = blanco"); Console.WriteLine("zin = " + zin + "\n"); //inhoud array tonen for (index = 0; index <= woordenArray.GetUpperBound(0); index++) { Console.WriteLine("woord " + (index + 1) + ". " + woordenArray[index]); //wachten op enter Console.ReadLine(); Console.Clear(); //TWEEDE VOORBEELD string kommaZin = "Jan,Piet,Joris,Corneel,Jet,Peter"; //zin splitsen met scheidingsteken komma woordenArray = kommaZin.Split(','); //resultaat tonen Console.WriteLine("scheidingsteken = komma"); Console.WriteLine("zin = " + kommaZin + "\n"); //inhoud array tonen for (index = 0; index <= woordenArray.GetUpperBound(0); index++) { Console.WriteLine("voornaam " + (index + 1) + ". " + woordenArray[index]); //wachten op enter Console.ReadLine(); Console.Clear(); //DERDE VOORBEELD string cijferZin = "een twee,drie:vier.vijf"; //zin splitsen met scheidingstekens spatie, komma, dubbel punt, punt woordenArray = cijferZin.Split(' ', ',', ':', '.'); //resultaat tonen Console.WriteLine("scheidingstekens zijn ' ' , : ."); Console.WriteLine("zin = " + cijferZin + "\n"); //inhoud array tonen for (index = 0; index <= woordenArray.GetUpperBound(0); index++) { Console.WriteLine("cijfer " + (index + 1) + ". " + woordenArray[index]); //wachten op enter Console.ReadLine();

39

13

Optionele parameters

Optionele parameters zijn parameters die je bij oproepen van een operatie niet verplicht moet meegeven. Als je ze niet meegeeft, gebruikt de operatie standaardwaarden (nieuw in Visual C# 2010!) H13VB1 We willen een programma schrijven om het ideale gewicht van een persoon te berekenen. Een bekende vuistregel hiervoor is: ideaal gewicht in kg = (lengte 100 + 4 *polsomtrek) / 2 We willen in ons programma voorzien dar als de gebruiker de polsomtrek niet invult, de functie IdeaalGewicht met 15 cm polsomtrek gaat rekenen. In de operatiedefinitie moeten we aangeven dat voor deze functie de lengte een VERPLICHTE parameter is. De polsomtrek mag opgegeven worden en is een OPTIONELE parameter.
static void Main(string[] args) { //declaratie int lengte = 0; int pols = 0; double gewichtIdeaal = 0; //kleuren aanpassen Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //opvragen parameter lengte Console.Write("Geef lengte in cm: "); lengte = Convert.ToInt32(Console.ReadLine()); //al dan niet polsomtrek opvragen Console.Write("Ken je je polsomtrek? J/N "); if (Console.ReadLine().ToUpper() == "J") { Console.Write("Geef polsomtrek in cm: "); pols = Convert.ToInt32(Console.ReadLine()); gewichtIdeaal = IdeaalGewicht(lengte, pols); else { gewichtIdeaal = IdeaalGewicht(lengte); }

//resultaat afdrukken Console.WriteLine("Je ideaal gewicht in kilogram " + gewichtIdeaal.ToString()); Console.ReadLine(); } private static double IdeaalGewicht(int lengte, int optionalPols = 15) { //declaratie double gewicht = 0; //berekenen gewicht = (lengte - 100 + 4 * optionalPols) / 2; //resultaat terugsturen return gewicht; }

Twee parameters: int lengte, int optionalPols = 15 lengte is een verplichte parameter optionalPols is een optionele parameter: als er geen waarde doorgegeven wordt, dan wordt de waarde 15 genomen. Optionele parameters in C# zijn parameters die VERPLICHT een beginwaarde krijgen in de operatiedefinitie. Vanaf het punt in de operatiedefinitie waar een optionele parameter gebruikt wordt, zijn alle volgende parameters optioneel! H13VB1 (uitbreiding) We willen een programma schrijven om het ideaal gewicht van een persoon te berekenen. Er bestaan nogal wa verschillende formu les als alternatief voor onze vuistregel, bijvoorbeeld de Hamwi-methode: Ideaal gewicht in kg = 45,4 + 0,89 * (lengte in cm 152,4) Als de gebruiker GEEN POLSOMTREK opgeeft, willen we de Hamwi-methode gebruiken, in het andere geval de vuistregel die we tot nu toe toepasten. PROBLEEM: Hoe kunnen we weten of polsomtrek opgegeven werd? De optionele parameter moet immers verplicht genitialiseerd worden in de operatiedefinitie OPLOSSING: private static double IdeaalGewicht(int lengte, object optionalPols = null) Twee parameters: int lengte, object optionalPols = null lengte is een verplichte parameter optionalPols is een optionele parameter met datatype object en genitialiseerd op null Optionele parameter optionalPols: Invullen van parameter: de waarde wordt opgevangen in de variabele pols Niet invullen van parameter: de waarde null wordt ingebracht in de variabele pols Omdat null geen integer waarde is, wordt deze waarde opgevangen in het meest algemene gegevenstype, namelijk object.

40

Vervolledig de code:
static void Main(string[] args) { //declaratie int lengte = 0; int pols = 0; double gewichtIdeaal = 0; //schermkleur Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Black; Console.Clear(); //opvragen parameter lengte Console.Write("Geef lengte in cm: "); lengte = Convert.ToInt32(Console.ReadLine()); //al dan niet polsomtrek opvragen Console.Write("Ken je je polsomtrek? J/N"); if (Console.ReadLine().ToUpper() == "J") { Console.Write("Geef polsomtrek in cm: "); pols = Convert.ToInt32(Console.ReadLine()); gewichtIdeaal = IdeaalGewicht(lengte, pols); } else { gewichtIdeaal = IdeaalGewicht(lengte); } //resultaat afdrukken Console.WriteLine("Je ideaal gewicht in kilogram " + gewichtIdeaal.ToString()); Console.ReadLine(); } private static double IdeaalGewicht(int lengte, object optionalPols = null) { //declaratie double gewicht = 0; //berekenen if (optionalPols == null) { gewicht = 45.4 + 0.89 * (lengte - 152.4); } else { gewicht = (lengte - 100 + 4 * Convert.ToInt32(optionalPols)) / 2; } //resultaat terugsturen return gewicht; }

We zijn verplicht een beginwaarde op te geven voor alle optionele parameters in de operatiedefinitie. We geven als beginwaarde null in plaats van een concrete waarde. null kan niet ingevuld worden in een variabele van het type integer, want null wordt daarin vertaald als 0. Daarom moeten we het meest algemene gegevenstype kiezen uit C#, namelijk object. Nu kunnen we testen met == null of een parameter opgegeven werd of niet. EXTRA TIPS EN WEETJES OVER OPERATIES IN WINDOWSAPPLICATIES H13VB2 We kunnen niet alleen variabelen gebruiken als actuele parameters, maar ook objecten (knoppen, tekstvakken,) Bij het laden van het formulier worden alle knoppen op dezelfde manier opgemaakt. We programmeren dit efficicint met behulp van een operatie waarbij we als parameter een knop mee doorgeven. Voeg een operatie MaakControlOp toe met als parameter knop:
private void MaakControlOp(Button knop) { //opmaak knop.BackColor = Color.FromArgb(150, 0, 0); knop.ForeColor = Color.White; knop.Font = new Font("arial", 10, FontStyle.Italic); }

Codeer nu voor het laden van het formulier:


private void FormH13VB2_Load(object sender, EventArgs e) { MaakControlOp(Button1); MaakControlOp(Button2); MaakControlOp(Button3); MaakControlOp(Button4); MaakControlOp(Button5); }

OPGELET: We kunnen enkel knoppen opgeven, geen labels of andere controls. Als je wel andere controls wil kunnen meegeven, moeten de operatiedefinitie en de code van de operatie aangepast worden. Pas de operatie aan tot:
private void MaakControlOp(Control control) { //opmaak willekeurig type control control.BackColor = Color.FromArgb(150, 0, 0); control.ForeColor = Color.White; control.Font = new Font("arial", 10, FontStyle.Italic); }

41

Als je dezelfde operatie wil gebruiken om verschillende controls op een andere manier op te maken, moet je in de operatie tes ten op het soort van control dat opgegeven werd. Wij willen dat het label wel het lettertype krijgt, maar niet de kleuren die die knoppen krijgen. Pas de code aan en test uit:
private void MaakControlOp(Control control) { //font voor alle controls control.Font = new Font("arial", 10, FontStyle.Italic); //opmaak alleen voor buttons if (control is Button) { control.BackColor = Color.FromArgb(150, 0, 0); control.ForeColor = Color.White; } }

De operator is geeft True indien het opgegeven object van de klasse is waarmee vergelekend wordt.
if (control is Button)

if is Button

test speciale operator om op niveau van type te vergelijken klassenaam

Bekijk de code in Load event van het formulier. Wat bij formulier met zeer veel controls MaakControlOp() moeten opgemaakt worden? Lus schrijven voor oproepen MaakControlOp
private void FormH13VB2_Load(object sender, EventArgs e) { //alle besturingselementen opmaken foreach (Control besturingsElement in this.Controls) { MaakControlOp(besturingsElement); } }

Foreach is een variant op de for-structuur waarmee je een collectie kan overlopen (zie eerder). Met foreach worden alle elementen van een verzameling doorlopen. Hier wordt de code herhaald voor elke control uit de verzameling Controls op het huidige formulier (this).
foreach (Control besturingsElement in this.Controls) { MaakControlOp(besturingsElement); }

foreach besturingsElement in this.Controls MaakControlOp()

voor elke control in de verzameling controls van het formulier stuurt die control door naar operatie

42

14

Afbeeldingen gebruiken - Werken met keuzerondjes Werken met InitializeComponentExtra()

Inleiding In dit hoofdstuk komen allerlei afbeeldingen aan bod: Achtergrondafbeeldingen Icoontjes Gewone afbeeldingen H14VB1 Eerst maken we het formulierontwerp klaar. Vervolgens voegen we de benodigde afbeeldingen toe aan de Resources van ons proje ct. Er staan verschillende soorten afbeeldingen klaar in de map met afbeeldingen ( verschillende formaten, verschillende functies: 1 achtergrond, 2 icoontjes, 1 gewone afbeelding).

Voeg achtergrond.jpg en prent.png toe

Voeg skater.ico en scater2.ico toe. Let erop dat je in het venster kiest voor icons.

Bij het laden van het formulier: Maak je het formulier grijs Verander je het icoon van de applicatie in skater.ico Breng je de tekst: Afbeeldingen aan in de titelbalk Hang je de checkboxen onderaan het formulier vast met een witte achtergrond Selecteer je checkBoxToon Wordt PicturBoxPrent gevuld met prent.jpg
private void FormH14VB1_Load(object sender, EventArgs e) { //lay-out regelen this.BackColor = Color.Gray; this.Icon = Properties.Resources.skater; this.Text = "Afbeeldingen"; checkBoxToon.Checked = true; checkBoxToon.Dock = DockStyle.Bottom; checkBoxToon.BackColor = Color.White; checkBoxAchtergrond.Dock = DockStyle.Bottom; checkBoxAchtergrond.BackColor = Color.White; //prent laden pictureBoxPrent.SizeMode = PictureBoxSizeMode.Zoom; pictureBoxPrent.Image = Properties.Resources.prent; }

We kunnen de resources van ons project nu gebruiken via namespace Properties. Let op de naamgeving in Resources: de extentie wordt niet vermeld! Selectievakjes Selectievakjes (CheckBox) hebben een eigenschap Checked waarin bijgehouden wordt of het selectievakje gekozen werd of niet. Afbeeldingen laden Heel wat controls (knop, picturebox,) hebben de eigenschap .Image

43

.SizeMode Met de eigenschap .SizeMode leg je vast wat er met de afmetingen van de figuur moet gebeuren: AutoSize: De grootte van de picturebox wordt aangepast aan de werkelijke grootte van de afbeelding CenterImage: De afbeelding wordt in het midden van de picturebox geplaatst Normal: De afbeelding wordt in de linkerbovenhoek van de picturebox geplaatst StretchImage: De afbeelding wordt ingekrompen/uitgerokken tot formaat van picturebox (evt. vervormd!) Zoom: De afbeelding wordt ingekrompen/uitgerokken, maar de verhoudingen blijven kloppen H14VB1 De code die uitgevoerd moet worden als we andere keuzes maken in de selectievakjes, ontbreekt nog. De skater moet verborgen worden als checkBoxToon niet aangevinkt is. Anders moet skater wel getoond worden.
private void checkBoxToon_Click(object sender, EventArgs e) { //reageren op de keuze van de gebruiker if (checkBoxToon.Checked) { pictureBoxPrent.Show(); } else { pictureBoxPrent.Hide(); } }

Show Hide Heel veel controls hebben een methode Show om zich zichtbaar te maken en Hide om de control te verbergen. Je zou eventueel ook kunnen werken met de eigenschap Visible, maar dat wordt afgeraden als er ook een methode bestaat met die taak. H14VB1 De code die uitgevoerd moet worden als we andere keuzes maken in de selectievakjes, ontbreekt nog. Je toont de achtergrondafbeelding als checkBoxAchtergrond aangevinkt is. Anders haal je deze weg.
private void checkBoxAchtergrond_Click(object sender, EventArgs e) { //reageren op de keuze van de gebruiker if (checkBoxAchtergrond.Checked) { this.BackgroundImage = Properties.Resources.achtergrond; this.BackgroundImageLayout = ImageLayout.Tile; } else { this.BackgroundImage = null; } }

.BackgroundImage Laden via: Properties.Resources.achtergrond; Een achtergrondafbeelding verbergen gaat niet, weghalen wel: this.BackgroundImage = null; Standaard wordt de achtergrondafbeelding herhaald, zowel horizontaal als verticaal. Als je hiervan wil afwijken, gebruik je de eigenschap .BackgroundImageLayout (Center, None, Stretch, Tile, Zoom) H14VB1 We passen nu nog het icoontje van het exe-bestand aan. Ga naar Project H14VB1 Properties In de tab Application kan je het icoontje aanpassen Gebruik de rode skater skater2.ico als icoon H14VB2 We zien twee knoppen, n met daarop een tekening. Het formulier is op een speciale manier opgemaakt. Open de startsolution. Het formulierontwerp is in orde, de rest moet via code gebeuren. Voeg de afbeelding hand.png toe aan de Resources van je project.

Bij het klikken op de knop moet de applicatie gesloten worden.


private void buttonEinde_Click(object sender, EventArgs e) { //toepassing sluiten Application.Exit(); }

Bij het laden van het formulier verberg je de knoppen rechtsboven. Zorg er ook voor dat het formulier niet vergoot of verkleind kan worden door aan de randen te slepen.
private void FormH14VB2_Load(object sender, EventArgs e) { //formulier aanpassen this.ControlBox = false; this.FormBorderStyle = FormBorderStyle.Fixed3D; }

44

.ControlBox Om aan te geven of je in de rechterbovenhoek van het formulier knopjes wil of niet. .FormBorderStyle Normaal gezien is de randstijl Sizable in plaats van Fixed3D. Andere mogelijkheden zijn: Fixed3D, FixedDialog, FixedSingle, FixedToolWindow, None, Sizable, SizableToolWindow H14VB2 Bij het laden van het formulier moeten de knoppen nog opgemaakt worden. ButtonEinde Afbeelding hand.png links Tekst stop rechts Lettertype Verdana 16pt vet De knop moet aan de bovenkant van het formulier gehangen worden ButtonAantal Tekst aantal links Lettertype Verdana 16pt vet De knop moet aan de onderkant van het formulier gehangen worden
private void FormH14VB2_Load(object sender, EventArgs e) { //formulier aanpassen this.ControlBox = false; this.FormBorderStyle = FormBorderStyle.Fixed3D; //layout regelen knoppen buttonEinde.Image = Properties.Resources.hand; buttonEinde.ImageAlign = ContentAlignment.TopLeft; buttonEinde.Text = "stop"; buttonEinde.TextAlign = ContentAlignment.BottomRight; buttonEinde.Font = new Font("verdana", 16, FontStyle.Bold); buttonEinde.Dock = DockStyle.Top;` buttonAantal.Text = "aantal"; buttonAantal.TextAlign = ContentAlignment.BottomLeft; buttonAantal.Font = new Font("verdana", 16, FontStyle.Bold); buttonAantal.Dock = DockStyle.Bottom; }

.ImageAlign Met de eigenschap . ImageAlign leg je vast waar de tekening op de knop moet komen:
buttonEinde.ImageAlign = ContentAlignment.TopLeft;

.TextAlign Met de eigenschap .TextAlign leg je vast waar de tekst op de knop moet komen:
buttonEinde.TextAlign = ContentAlignment.BottomRight;

H14VB2 Telkens als de gebruiker op de knop ButtonAantal klikt, verhoogt er een teller die ge toond wordt in de titelbalk van het formulier.
private void buttonAantal_Click(object sender, EventArgs e) { //teller verhogen in titelbalk int aantal = 0; _aantal += 1; this.Text = "Aantal keer geklikt " + _aantal; }

Lukt dit? int aantal = 0 is een lokale variabele. Lokale variabelen worden gedeclareerd binnen een operatie en zijn daar alleen gekend. Deze variabele wordt bij elke druk op de knop opnieuw gedeclareerd en genitialiseerd. Hierdoor wordt haar waarde telkens opnieuw op 0 ingesteld! Modulevariabelen We hebben nu nood aan variabelen die hun waarde behouden zodat we kunnen verder tellen en kunnen bijhouden hoe vaak we al op de knop geklikt hebben. OPLOSSING: Modulevariabelen Modulevariabelen zijn IN HEEL HET FORMULIER GEKEND en kunnen daar overal gebruikt worden. Declaratie: Bovenaan formulier onder public partial class FormH14VB2 : Form Statement Private Onderlijningsteken gevolgd door naam
namespace H14VB2 { public partial class FormH14VB2 : Form { //declaratie module private int _aantal;

Pas de code van ButtonAantal aan:


private void buttonAantal_Click(object sender, EventArgs e) { //teller verhogen in titelbalk _aantal += 1; this.Text = "Aantal keer geklikt " + _aantal; }

45

H14VB2 VOLLEDIGE OPLOSSING


namespace H14VB2 { public partial class FormH14VB2 : Form { //declaratie module private int _aantal; public FormH14VB2() { InitializeComponent();

private void buttonEinde_Click(object sender, EventArgs e) { //toepassing sluiten Application.Exit(); } private void FormH14VB2_Load(object sender, EventArgs e) { //formulier aanpassen this.ControlBox = false; this.FormBorderStyle = FormBorderStyle.Fixed3D; //layout regelen buttonEinde.Image = Properties.Resources.hand; buttonEinde.ImageAlign = ContentAlignment.TopLeft; buttonEinde.Text = "stop"; buttonEinde.TextAlign = ContentAlignment.BottomRight; buttonEinde.Font = new Font("verdana", 16, FontStyle.Bold); buttonEinde.Dock = DockStyle.Top; buttonAantal.Text = "aantal"; buttonAantal.TextAlign = ContentAlignment.BottomLeft; buttonAantal.Font = new Font("verdana", 16, FontStyle.Bold); buttonAantal.Dock = DockStyle.Bottom; } private void buttonAantal_Click(object sender, EventArgs e) { //teller verhogen in titelbalk _aantal += 1; this.Text = "Aantal keer geklikt " + _aantal; } } }

46

15

Werken met strings

Inleiding Het datatype string is een veel gebruikt datatype binnen programmas. In C# zijn er veel methodes waarmee strings bewerkt kun nen worden. In dit hoofdstuk lichten we doe toe. H15VB1 De gebruiker voert tekst in, de invoer kan op verschillende manieren verwerkt worden
WERKEN MET STRINGS A. B. C. D. E. F. G. H. I. X. Lengte brekenen van "appelsap" Een deel van "appelsap" opvragen Zoeken naar de plaats van een teken in "appelsap" Vooraan en achteraan blancos weghalen Tekens verwijderen uit "appelsap" Tekens toevoegen aan "appelsap" Tekens vervangen in "appelsap" De invoer omkeren Zin splitsen in woorden Stoppen

Uw keuze:

De functie NietLegeTekstInlezen() zorgt er voor dat er een vraag gesteld wordt waarop de gebruiker moet antwoorden. Lege antwoorden worden afgekeurd. De functie MenuKeuze() toont het menu en vraagt een antwoord aan de gebruiker. De functie PositiefGetalInlezen() zorgt er voor dat de gebruiker een vraag te zien krijgt waarop die met een getal 0 moet antwoorden.

H15VB1 NietLegeTekstInlezen() Lege antwoorden afkeuren 1ste manier


private static string NietLegeTekstInlezen(string vraag) { //declaratie string tekst = null; //inlezen do { Console.WriteLine(); Console.Write(vraag); Console.ForegroundColor = ConsoleColor.Red; tekst = Console.ReadLine(); Console.ForegroundColor = ConsoleColor.Black; } while (tekst == "" || tekst == null); //terugkeerwaarde return tekst; }

NADEEL: Wanneer men uitsluitend spaties ingeeft, wordt dit aanvaard als een correct antwoord. Lege antwoorden afkeuren 2de manier
private static string NietLegeTekstInlezen(string vraag) { //declaratie string tekst = null; //inlezen do { Console.WriteLine(); Console.Write(vraag); Console.ForegroundColor = ConsoleColor.Red; tekst = Console.ReadLine(); Console.ForegroundColor = ConsoleColor.Black; } while (string.IsNullOrWhiteSpace(tekst)); //terugkeerwaarde return tekst; }

String.IsNullOrWhiteSpace() indiceert of een string leeg is, gelijk aan null of enkel uit spaties bestaat. String.IsNullOrEmpty() indiceert of een string leeg is of gelijk aan null.

47

H15VB1 MenuKeuze()
private static string MenuKeuze(string teVerwerken) { //declaratie string antwoord = null; //inlezen Console.Clear(); Console.WriteLine("\nWERKEN MET STRINGS\n"); Console.WriteLine("A. Lengte berekenen van \"" + teVerwerken + "\""); Console.WriteLine("B. Een deel van \"" + teVerwerken + "\" opvragen"); Console.WriteLine("C. Zoeken naar de plaats van een teken in \"" + teVerwerken + "\""); Console.WriteLine("D. Vooraan en achteraan blanco's weghalen"); Console.WriteLine("E. Tekens verwijderen uit \"" + teVerwerken + "\""); Console.WriteLine("F. Tekens toevoegen aan \"" + teVerwerken + "\""); Console.WriteLine("G. Tekens vervangen in \"" + teVerwerken + "\""); Console.WriteLine("H. De invoer omkeren"); Console.WriteLine("I. Zin splitsen in woorden"); Console.WriteLine("X. Stoppen"); antwoord = NietLegeTekstInlezen("Uw keuze: ").ToUpper(); Console.WriteLine(); return antwoord; }

H15VB1 PositiefGetalInlezen() Dubbele invoercontrole Geeft geheel getal 0 terug


private static int PositiefGetalInlezen(string vraag) { //declaratie string getalTekst = null; int getal = 0; //inlezen do { do { Console.Write(vraag); Console.ForegroundColor = ConsoleColor.Red; getalTekst = Console.ReadLine(); Console.ForegroundColor = ConsoleColor.Black; } while (!int.TryParse(getalTekst, out getal); } while(getal < 0); //terugkeerwaarde return getal; }

H15VB1 Main() In het hoofdprogramma vind je een switch structuur (in volgende code is deze nog niet aangevuld)
static void Main(string[] args) { //declaratie string woord = null; string keuze = null; string aangepastWoord = null; string teZoeken = null; string inTeVoegen = null; string[] woordArray; int lengte = 0; int eerstePositie = 0; int laatstePositie = 0; int teller = 0; bool isGevonden = false; //inlezen basiswoord woord = NietLegeTekstInlezen("Uw invoer aub: "); //priming read //menu tonen en antwoord inlezen keuze = MenuKeuze(woord); //verwerken //test op voorwaarde while (keuze != "X") { //verder werken met correcte waarde switch (keuze) { case "A": //lengte break; case "B": //deel van het woord break; case "C": //zoeken break; case "D": //spaties voor en achter verwijderen break; case "E": //tekens verwijderen break; case "F": //tekens invoegen break;

48

case "G": //tekens vervangen break; case "H": //omkeren break; case "I": //splitsen van zinnen in woorden break; default: break; } //pauzeren Console.ReadLine(); //opnieuw keuze vragen keuze = MenuKeuze(woord); } Console.WriteLine("Druk op een toets"); Console.ReadLine(); }

A. Eigenschap .Length Eigenschap waarin de lengte van een string bewaard wordt. Alle karakters word en geteld. Bijvoorbeeld: string woord = "jas"; int lengte = 0; lengte = woord.Length; in de variabele lengte zit nu 3
case "A": //lengte Console.WriteLine("De lengte van \"" + woord + "\" is " + woord.Length); break;

B. Methode Substring() Methode om een aantal karakters uit een string te halen Substring(startpositie, lengte) LET OP: De methode Substring() ziet het karakter op plaats 0 als het eerste karakter! TIP: Als je alleen de startpositie opgeeft, wordt alles vanaf die positie to t op het einde van de string opgehaald. Bijvoorbeeld: string woord = "kind"; string resultaat; resultaat = woord.Substring(1,2); in de variabele resultaat zit nu "in".
case "B": //deel vh woord eerstePositie = PositiefGetalInlezen("Waar wil je starten? "); lengte = PositiefGetalInlezen("Hoeveel tekens wil je? "); if (eerstePositie + lengte - 1 <= woord.Length && lengte != 0 && eerstePositie != 0) { aangepastWoord = woord.Substring(eerstePositie - 1, lengte); Console.WriteLine("Het resultaat is: " + aangepastWoord); } else { Console.WriteLine("Dit lukt niet"); } break;

C. Methode Contains() Methode om na te gaan of een zoekwaarde voorkomt in de string Contains(zoekwaarde) Methode geeft als resultaat een Boolean terug (True of False) Bijvoorbeeld: string woord "jas"; bool isGevonden; isGevonden = woord.Contains("g"); In de variabele isGevonden zit nu "False" C. Methode IndexOf() Methode om de plaats van een lettercombinatie binnen een string om te zoeken (hoofdlettergevoelig!) IndexOf(zoekstring) IndexOf(zoekstring, startpositie) IndexOf(zoekstring, startpositie, aantalkarakters) Geef je geen startpositie en aantal karakters op, dan wordt de hele string doorzocht. Geef je geen aantal karakters op, maar wel een startpositie, dan wordt vanaf die positie tot op het einde gezocht Bijvoorbeeld: string woord = "paraplu"; int positie; positie = woord.IndexOf("arp"); In de variabele positie zit nu "-1". Dit betekent: niet gevonden! positie = woord.IndexOf("a"); In de variabele positie zit nu "1". Dit betekent: op indexplaats 1 werd die letter voor het eerst gevonden.

49

C. Methode LastIndexOf() Methode analoog aan IndexOf(), maar nu gezocht naar het laatste voorkomen van een zoekstring (h oofdlettergevoelig!)
case "C": //zoeken teZoeken = NietLegeTekstInlezen("Wat wil je zoeken? "); isGevonden = woord.Contains(teZoeken); if (isGevonden) { eerstePositie = woord.IndexOf(teZoeken); laatstePositie = woord.LastIndexOf(teZoeken); Console.WriteLine(teZoeken + " komt de eerste keer voor op index " + eerstePositie + " en de laatste keer op index " + laatstePositie); } else { Console.WriteLine("Sorry, niet gevonden"); } break;

D. Methode Trim() Methode om spaties vooraan en achteraan in de string te verwijderen. Alternatieve mogelijkheden: TrimEnd(): gaat enkel de spaties op het einde van de string weglaten TrimStart(): gaat enkel de spaties in het begin van de string weglaten
case "D": //voorloopspaties, spaties achteraan verwijderen aangepastWoord = woord.Trim(); Console.WriteLine("De invoer |" + woord + "| werd omgevormd tot |" + aangepastWoord + "|"); break;

E. Methode Remove() Methode om karakters uit een string te verwijderen Remove(startpositie, aantal karakters) Startpositie is de positie van het eerste te verwijderen teken uit de string Aantal karakters is het aantal te verwijderen tekens. Bijvoorbeeld: string woord = "kinderen"; string resultaat; resultaat = woord.Remove(4,4); In de variabele resultaat zit nu "kind"
case "E": //tekens verwijderen eerstePositie = PositiefGetalInlezen("Waar wil je starten met verwijderen? "); lengte = PositiefGetalInlezen("Hoeveel tekens wil je verwijderen? "); if (eerstePositie + lengte - 1 <= woord.Length && eerstePositie != 0 && lengte != 0) { aangepastWoord = woord.Remove(eerstePositie - 1, lengte); Console.WriteLine("Het resultaat is: " + aangepastWoord); } else { Console.WriteLine("Dit lukt niet"); } break;

F. Methode Insert() Methode om karakters toe te voegen aan een string Insert(startpositie, in te voegen karakters) Startpositie is de positie waar op de in te voegen karakters worden bijgevoe gd. In te voegen karakters is wat er bijgevoegd moet worden. Bijvoorbeeld: string woord = "kind"; string resultaat; resultaat = woord.Insert(4, "eren"); In de variabele resultaat zit nu "kinderen"
case "F": //tekens invoegen eerstePositie = PositiefGetalInlezen("Waar wil je starten met invoegen? "); inTeVoegen = NietLegeTekstInlezen("Wat wil je invoegen? "); if (eerstePositie <= woord.Length) { aangepastWoord = woord.Insert(eerstePositie - 1, inTeVoegen); Console.WriteLine("Het resultaat is: " + aangepastWoord); } else { Console.WriteLine("Dit lukt niet"); } break;

50

G. Methode Replace() Methode om karakters in een string te vervangen Replace(oude string, nieuwe string) Oude string is het tekstgedeelte van de string die we wensen aan te passen. Nieuwe string is de nieuwe waarde die we aan de oude string willen geven. Bijvoorbeeld: string woord = "jas"; woord = woord.Replace("a", "o"); In de variabele woord zit nu "jos"

string woord = "adam en eva" woord = woord.Replace(" ", ""); In de variabele woord zit nu "adameneva"

case "G": //tekens vervangen teZoeken = NietLegeTekstInlezen("Welk teken wil je overal vervangen? "); inTeVoegen = NietLegeTekstInlezen("Wat wil je in de plaats van dat teken invoegen? "); aangepastWoord = woord.Replace(teZoeken, inTeVoegen); Console.WriteLine("Het resultaat is: " + aangepastWoord); break;

H. Omkeren van een tekst Zelf te programmeren aan de hand van de andere methodes die aan bod kwamen.
case "H": //omkeren aangepastWoord = null; for (teller = woord.Length - 1; teller >= 0; teller--) { aangepastWoord += woord.Substring(teller, 1); } Console.WriteLine("Het resultaat is: " + aangepastWoord); break;

I. Methode Split() Methode om een string te splitsen in verschillende delen. Resultaat is een array . Split(scheidingsteken(s)) Scheidingsteken is van het type char! Bijvoorbeeld (n scheidingsteken): string woord = "jan piet joris"; string [] woordArray; woordArray = woord.Split(' '); Resultaat: woordArray[0] = "jan" woordArray[1] = "piet" woordArray[2] = "joris" Bijvoorbeeld (meerdere scheidingstekens): string woord = "jan piet joris"; string [] woordArray; woordArray = woord.Split(new Char[] {' ', ','}); blanco en komma Resultaat: woordArray[0] = "jan" woordArray[1] = "piet" woordArray[2] = "joris"
case "I": // splitsen van zinnen in woorden woordArray = woord.Split(new Char[] { ' ', ',', '.', ':', '\t' }); teller = 0; Console.WriteLine(woord); Console.WriteLine(new String(':',woord.Length) + "\n"); foreach (string woordje in woordArray) { Console.Write(new String(' ', 15) + new String('>',3) + teller + ":"); if (woordje.Trim() != "") { Console.WriteLine(woordje + new String('<', 3)); } else { Console.WriteLine(new String('=', 3)); } teller++; } break;

BESLUIT We bespraken een nieuwe eigenschap en nieuwe methodes bij strings. Deze vormen een aanvulling op .ToLower() en .ToUpper() die al eerder in de cursus aan bod kwamen.

51

Van teken naar ASCII Als je de ASCII-waarde van een letter wil kennen, moet je dat character casten naar een integer. Bijvoorbeeld:
int waarde; waarde = (int)'a'; Console.WriteLine(waarde);

Resultaat op scherm: 97

Als je het teken wil kennen dat bij een ASCII-waarde hoort, moet je de ASCII-waarde casten naar een char. Bijvoorbeeld:
int getal getal = 100; Console.WriteLine((char)getal);

Resultaat op scherm: d

Het consolevenster is hoger dan normaal. Om een consolevenster hoger te maken moet je de eigenschap .WindowHeight aanpassen.
Console.WindowHeight = 35;

H15VB2
Van A naar Z De De De De De De De De De De De De De De De De De De De De De De De De De De ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde ASCII-waarde van van van van van van van van van van van van van van van van van van van van van van van van van van A B C D E F G H I J K L M N O P Q R s T U V W X Y Z is is is is is is is is is is is is is is is is is is is is is is is is is is 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

Druk op een toets static void Main(string[] args) { //declaraties int teller; //schermkleuren Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; Console.Clear(); Console.WindowHeight = 35; //titel Console.WriteLine("Van A naar Z\n"); //verwerken for (teller = (int)'A'; teller <= (int)'Z'; teller++) { Console.WriteLine("\t De ASCII-waarde van " + (char)teller + " is " + teller); } //wachten op enter Console.WriteLine("\nDruk op een toets"); Console.ReadLine(); }

Alternatieve schrijfwijze:
//verwerken for (teller = Convert.ToInt32('A'); teller <= Convert.ToInt32('Z'); teller++) { Console.WriteLine("\t De ASCII-waarde van " + Convert.ToChar(teller) + " is " + teller); }

Voor de veelgebruikte datatypes int en char bestaan er ook C onvert-methodes. Je mag deze ook gebruiken.

H15VB2 Bespreking De teller begint vanaf de ASCII-waarde A en eindigt bij de ASCII-waarde van Z. Elke keer wordt de teller omgevormd tot het daarbij horende karakter en wordt daarbij de ASCII -waarde vermeld.

52

16

Willekeurige getallen Timer

H16VB1 Doel: telkens willekeurige foto laten zien, fotos 1 t/m 20 zijn beschikbaar. Dus: willekeurig geheel getal nodig. In ontwerpweergave is alles in orde: pictureBoxJapan, buttunToonWillekeurigeFoto Resources zijn opgevuld, naamgeving: _1 t/m _20
private void FormH16VB1_Load(object sender, EventArgs e) { //afbeelding blijft in verhouding pictureBoxJapan.SizeMode = PictureBoxSizeMode.Zoom; //titelbalk this.Text = "Fotogalerij"; } private void buttonToonWillekeurigeFoto_Click(object sender, EventArgs e) { //declaratie Random willekeurigGetal = new Random(); int fotoNummer; //willekeurife foto bepalen fotoNummer = willekeurigGetal.Next(1, 21); //foto tonen pictureBoxJapan.Image = (Image)Properties.Resources.ResourceManager.GetObject("_" + fotoNummer); this.Text = "Fotogalerij " + fotoNummer; }

As New Random Als je een aantal willekeurige getallen wil genereren, moet je dat doen aan de hand van een nieuwe instantie van d e klasse Random
Random willekeurigGetal = new Random();

Methode Next() Methode die een willekeurig geheel getal X genereert Next(ondergrens, bovengrens) Ondergrens is inbegrepen. Bovengrens is NIET inbegrepen. H16VB2 Doel: Een digitale klok met animatie nabootsen. Dus: Nood aan een nieuwe control Timer Voeg een Timer toe uit de gewonde Windows Form toolbox en benoem als timerKlok. Component Tray bevat objecten die tijdens run-time niet zichtbaar zijn.

Timer Eigenschappen: Interval: Bepaalt na welke tijdsinterval de gebeurtenis Tick wordt uitgevoerd.

Wordt uitgedrukt in miliseconden. Interval van 1000 miliseconden = 1 seconde

Enabled: True:

Timer wordt ingeschakeld

False: Timer wordt uitgeschakeld


Methodes: Start(): Stop(): Timer wordt ingeschakeld Timer wordt uitgeschakeld

We gebruiken bij voorkeur de methodes in plaats van de eigenschappen!

53

H16VB2 Load Event


private void FormH16VB2_Load(object sender, EventArgs e) { //achtergrondkleur bepalen this.BackColor = Color.FromArgb(0, 50, 100); //timer instellen timerKlok.Interval = 1000; timerKlok.Start(); //figuur vergroten pictureBoxMaan.SizeMode = PictureBoxSizeMode.Zoom; //labelDatumTijd opmaken labelDatumTijd.Dock = DockStyle.Bottom; labelDatumTijd.BorderStyle = BorderStyle.Fixed3D; labelDatumTijd.ForeColor = Color.White; }

Test uit! Timer is gestart, maar we zien geen effect Er is nog geen Tick event! H16VB2 Tick Event Code die uitgevoerd wordt al de Timer afloopt. Kies de juiste procedure:

private void timerKlok_Tick(object sender, EventArgs e) { //updaten titelbal en label this.Text = DateTime.Today.ToShortDateString() + " - " + DateTime.Now.ToLongTimeString(); labelDatumTijd.Text = "Laatste update: " + this.Text; }

Test uit! Nog geen afbeeldingen; Begin is niet OK! H16VB2 Oplossing afbeeldingen Nood aan een modulevariabele om bij te houden welke prent we juist getoond hebben!
namespace H16VB2 { public partial class FormH16VB2 : Form { //declaratie module variabelen private int _maanstand = 0; public FormH16VB2() ... private void FormH16VB2_Load(object sender, EventArgs e) ... private void timerKlok_Tick(object sender, EventArgs e) { //declaratie constante const string BEGIN = "MOON0"; //updaten titelbal en label ... //figuur na elkaar tonen _maanstand++; pictureBoxMaan.Image = (Image)Properties.Resources.ResourceManager.GetObject(BEGIN + _maanstand); if (_maanstand == 8) { _maanstand = 0; } } } }

Test uit! Je moet nog steeds n seconde wachten vooraleer de juiste informatie getoond wordt!

H16VB2 Oplossing meteen starten We gaan bij het laden van het formulier onmiddelijk het event Tick uitvoeren! InitializeComponentExtra()
public FormH16VB2() { InitializeComponent(); InitializeComponentExtra(); } private void InitializeComponentExtra() { this.Load += new EventHandler(timerKlok_Tick); }

54

Zelfstudie 5

Interessante controls en werkwijzen

H16ZelfVB1 Dit programma vraagt om een wachtwoord in te vullen. Indien de gebruiker een juist wachtwoord (KHK) opgeeft, kan hij berekene n hoe het nu zit met zijn/haar BMI. In dit voorbeeld wordt er gebruik gemaakt van de volgende nieuwe controls: panel numericUpDown maskedTextBox Ook passen we de volgende nieuwe werkwijze toe: Emuratie H16ZelfVB2 Met dit programma kan je een datum en een GSM nummer gemakkelijk invullen. Wanneer je iets fout ingeeft, krijg je een duidelijke boodschap. In dit voorbeeld komen andere eigenschappen van maskedTextBox aan bod. H16ZelfVB3 Dit programma opent vanuit C# de website van KHK of van de nieuwsdienst En en opent de windowstoepassing in Notepad. Ook het gebruik van een menubalk wordt hier verduidelijkt. In dit voorbeeld wordt er gebruik gemaakt van de volgende nieuwe controls: linkLabel menuStrip en toolStripMenuItem panel NIEUWE CONTROLS : 1. PANEL Een panel is een container van verschillende controls. Je gebruikt een panel wanneer je een collectie van controls wenst te groeperen om ze gemakkelijker samen te tonen, te verbergen of op te maken. H16ZelfVB1 Dit voorbeeld bevat een panelInlog. Dit panel bat een label, een maskedTextBox en een button. Door de instructies panelInlog.Hide() in de gebeurtenis buttonValideer_Click kan je 3 controls in n keer verbergen H16ZelfVB3 Dit voorbeeld bevat een panelWWW met twee linklabels. Het lettertype van het panel wordt aangepast door: panelWWW.Font = New Font("Verdana", 12); Het resultaat is dat het lettertype van de linklabels op het panel ook is aangepast.

2. MASKEDTEXTBOX Een maskedTextBox is een tekstvak met speciale invoerkenmerken. Eigenschap PasswordChar H16ZelfVB1 Via de eigenschap PasswordChar zorg je ervoor dat de ingevoerde tekst niet leesbaar is. Elk ingetikte karakter wordt vervangen voor het karakter bepaald door de eigenshap PasswordChar. Hoe realiseer je dit? maskedTextBoxPaswoord.PasswordChar = Convert.ToChar("*"); Tip: Je moet "*" converteren naar datatype Char. Het datatype Char is bedoeld om n alfanumerie karakter in op te slaan. Je kan natuurlijk ook meteen coderen met enkele quotes rond het paswoordteken. maskedTextBoxPaswoord.PasswordChar = '*'; Eigenschap Mask H16ZelfVB2 Via de eigenschap Mask zorg je ervoor dat er een bepaalde invoermasker toegepast wordt op het tekstvak. De gebruiker kan dan niet meer alle karakters invullen, hij/zij moet zich dan aan een bepaald masker houden. Wanneer je een standaardmasker wil gebruiken, klik je op '' bij de eigenschap Mask: Wanneer je een ander masker wenst dan de standaardmaskers, kan je dit realiseren door code te gebruiken: maskedTextBoxDatum.Mask = "00/00/000";
maskedTextBoxDatum.Mask = "(0000)000000";

Code 0 9 / . , $

Betekenis Getal vereist Getal of spatie, optioneel Scheidingsteken voor datum. Scheidingsteken voor decimalen Scheidingsteken voor duizendtallen Valuta-aanduiding

maskTextBox heeft een gebeurtenis om te reageren op foute invoer, namelijk MaskInputRejected.

55

H16ZelfVB2
public FormH16ZelfVB2() { InitializeComponent(); InitializeComponentExtra(); } private void InitializeComponentExtra() { maskedTextBoxDatum.MaskInputRejected += new maskInputRejectedEventHandler(maskedTextBox_MaskInputRejected); maskedTextBoxGSMNummer.MaskInputRejected += new MaskInputRejectedEventHandler(maskedTextBox_MaskInputRejected); } private void maskedTextBox_MaskInputRejected(object sender, MaskInputRejectedEventArgs e) { //declaratie en instantiren MaskedTextBox CastenGemaskerdTekstvak; CastenGemaskerdTekstvak = (MaskedTextBox)sender; //bericht tonen MessageBox.Show("Enkel getallen invoeren aub!", CastenGemaskerdTekstvak.Name); }

3. NUMERICUPDOWN De numericUpDown control wordt gebruikt indien de invoer enkel een getal mag zijn. Deze control is te vergelijken met een textBox, waar een pijltje naar boven en een pijltje naar onder aan zijn toegevoegd. Klik je op n van deze pijltjes, dan wijzigt de waarde die getoond wordt. Ook deze control heeft specifieke eigenschappen: Minimum bepaalt wat de kleinste waarde is. Standaardwaarde is 0. Maximum bepaalt wat de hoogste waarde is. Standaardwaarde is 100. Value bepaalt wat de huidige waarde is van de control. Standaard is dit 0. Increment bepaalt met welke waarde de eigenschap value van de control moet verhoogd/verlaagd worden als je op een pijltje drukt. Standaard is dit met 1. DecimalPlaces bepaalt hoeveel decimalen je kan gebruiken. Standaard is dit 0. LET OP: Het datatype van bovenstaande eigenschappen is steeds Decimal! H16ZelfVB1
//numeric updowns regelen numericUpDownLengte.Minimum = 130; numericUpDownLengte.Maximum = 230; numericUpDownLengte.Value = 175; numericUpDownGewicht.Increment = Convert.ToDecimal(0.5); numericUpDownGewicht.Minimum = 25; numericUpDownGewicht.Maximum = 250; numericUpDownGewicht.DecimalPlaces = 2; numericUpDownGewicht.Value = 65;

4. LINKLABEL De linkLabel is een spaciale Label met extra eigenschappen. Je kan een linkLabel vergelijken met een hy perlink in HTML. Wanneer de gebruiker klikt op een linkLabel kan men een website of een andere windowstoepassing openen. Ook deze control heeft specifieke eigenschappen: LinkColor: kleur voor normale link VisitedLinkColor: kleur voor bezochte link ActiveLinkColor: kleur van actieve link LinkArea: lengte/positie van link instellen H16ZelfVB3
private void FormH16ZelfVB3_Load(object sender, EventArgs e) { // linklabel opmaken linkLabelNieuws.Text = "Klik hier voor meer nieuws"; linkLabelNieuws.LinkArea = new LinkArea(5, 4); linkLabelNieuws.VisitedLinkColor = Color.Green; linkLabelNieuws.ActiveLinkColor = Color.Red; linkLabelKHK.Text = "KHK site"; linkLabelNotepad.Text = "Notepad openen"; } private void InitializeComponentExtra() { linkLabelKHK.LinkClicked += new LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked); linkLabelNieuws.LinkClicked += new LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked); linkLabelNotepad.LinkClicked += new LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked); naamToolStripMenuItem.Click += new EventHandler(voornaamToolStripMenuItem_Click); } private void linkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { // declaratie LinkLabel CastenLinkLabel; string wwwAdres = null; CastenLinkLabel = (LinkLabel)sender; if (CastenLinkLabel.Name.ToLower().Contains("nieuws")) { wwwAdres = "http://www.deredactie.be/cm/vrtnieuws"; } else { if (CastenLinkLabel.Name.ToLower().Contains("khk")) { wwwAdres = "http://www.khk.be/khk04"; } else

56

{ wwwAdres = "notepad"; } } // juiste url of window toepassing openen System.Diagnostics.Process.Start(wwwAdres); // hyperlink instellen als bezocht CastenLinkLabel.LinkVisited = true; }

5. MENUSTRIP EN TOOLSTRIPMENUITEM Om een menubalk op je formulier te krijgen, moet je een menuStrip control selecteren uit de toolbox. Je typt de gewenste structuut in deze menustrip. Om een streep te drukken gebruik je ''. H16ZelfVB3 Elk onderdeel zoals Invoer, Resultaat, Afsluiten, Voornaam en Naam is een toolStripMenuItem -control. De naamgeving van de toolStripMenuItem passen we niet aan.

private void voornaamToolStripMenuItem_Click(object sender, EventArgs e) { // declaratie ToolStripMenuItem CastenToolStripMenuItem; CastenToolStripMenuItem = (ToolStripMenuItem)sender; // bepalen wat je gaat inlezen switch (CastenToolStripMenuItem.Text.ToLower()) { case "naam": _naam = Inlezen("Geef je naam op: "); break; case "voornaam": _voornaam = Inlezen("Geef je voornaam op: "); break; } // alleen als de module variabelen allemaal ingevuld zijn wordt het menuitem beschikbaar if (!string.IsNullOrWhiteSpace(_naam) && !string.IsNullOrWhiteSpace(_voornaam)) { resultaatToolStripMenuItem.Enabled = true; } } private void resultaatToolStripMenuItem_Click(object sender, EventArgs e) { // boodschap tonen MessageBox.Show("Dag " + _voornaam + new string(' ', 1) + _naam + Environment.NewLine + "nog een mooie dag! "); }

NIEUWE WERKWIJZEN: 1. WERKEN MET ENUMERATIES Wanneer je in een toepassing een reeks van gerelateerde constanten moet gebruiken, werk je beter met een emuratie. De waarde van de constanten moet wel bestaan uit positieve of negatieve GEHELE getallen. Het gebruik van een emuratie verbetert de leesbaarheid van je code. Declaratie van een enumeratie gebeurt op private niveau aan de hand van een sleutelwoord enum. H16ZelfVB1
private enum _BMI { ondervoed = 0, normaalGewicht = 20, lichtOvergewicht = 25, overgewicht = 30, extreemOvergewicht = 40 }; private void buttonBeoordeel_Click(object sender, EventArgs e) { //declaraties int prentnr; double gewicht, lengte; double BMI; const string BEGIN = "bmi"; //informatie inlezen lengte = Convert.ToDouble(numericUpDownLengte.Value); gewicht = Convert.ToDouble(numericUpDownGewicht.Value); //BMI berekenen BMI = (gewicht / Math.Pow(lengte, 2)) * 10000; //beoordelen van BMI + resultaat tonen in titelbalk if (BMI < Convert.ToDouble(_BMI.normaalGewicht)) { this.Text = _BMI.ondervoed.ToString(); prentnr = 1; } else {

57

if (BMI < Convert.ToDouble(_BMI.lichtOvergewicht)) { this.Text = _BMI.normaalGewicht.ToString(); prentnr = 2; } else { if (BMI < Convert.ToDouble(_BMI.overgewicht)) { this.Text = _BMI.lichtOvergewicht.ToString(); prentnr = 3; } else { if (BMI < Convert.ToDouble(_BMI.extreemOvergewicht)) { this.Text = _BMI.overgewicht.ToString(); prentnr = 4; } else { this.Text = _BMI.extreemOvergewicht.ToString(); prentnr = 5; } } } } //resultaat tonen in picturebox en label pictureBoxBMI.Image = (Image)Properties.Resources.ResourceManager.GetObject(BEGIN + prentnr); labelBeoordeel.Text = Math.Round(BMI, 1).ToString(); }

AFSPRAAK: Enumeraties worden zoals modulevariabelen met _ en met kleine letters geschreven, tenzij het gaat om afkortingen z oals BMI. Andere voorbeelden:
private enum _dagen { zondag, maandag, dinsdag, woensdag, donderdag, vrijdag, zaterdag };

In deze enumeratie is zondag = 0, maandag = 1, dinsdag = 2, Wanneer je nu de integerwaarde wenst te gebruiken van een enumeratie, kan je als volgt te werk gaan: int dag = (int)_dagen.zondag; dag krijgt nu de waarde 0 2. PROCES STARTEN Via System.Diagnostics.Process.Start() start je via taakbeheer een nieuw proces. De standaardactie bij het opgegeven bestand of de opgegeven string wordt uitgevoerd. In voorbeeld 3 wordt dit gebruikt om de browser te openen en naar een bepaalde URL te gaan die in wwwAdres vervat zit. H16ZelfVB3
private void linkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { // declaratie LinkLabel CastenLinkLabel; string wwwAdres = null; CastenLinkLabel = (LinkLabel)sender; if (CastenLinkLabel.Name.ToLower().Contains("nieuws")) { wwwAdres = "http://www.deredactie.be/cm/vrtnieuws"; } else { if (CastenLinkLabel.Name.ToLower().Contains("khk")) { wwwAdres = "http://www.khk.be/khk04"; } else { wwwAdres = "notepad"; } } // juiste url of window toepassing openen System.Diagnostics.Process.Start(wwwAdres); // hyperlink instellen als bezocht CastenLinkLabel.LinkVisited = true; }

H16ZelfVB4
//declaratie string antwoord; //inlezen Console.WriteLine("Menu \n"); Console.WriteLine("A: notepad starten"); Console.WriteLine("B: rekenmachine starten"); Console.WriteLine("C: naar google gaan"); Console.WriteLine("D: afbeelding uit bin-map openen"); Console.Write("\nUw keuze? "); antwoord = Console.ReadLine().ToUpper(); //verwerken switch (antwoord) { case "A": System.Diagnostics.Process.Start("notepad.exe"); break; case "B": System.Diagnostics.Process.Start("calc.exe"); break; case "C": System.Diagnostics.Process.Start("www.google.be"); break; case "D": System.Diagnostics.Process.Start("appel.jpg"); break; } //wachten op enter Console.ReadLine();

58

3. INPUTBOX GEBRUIKEN H16ZelfVB3 In H16ZelfVB3 staat code om een invoervenster of inputBox te genereren. Op dit moment is het NIET de bedoeling dat je deze code zelf schrijft. Je moet de code enkel kunnen gebruiken. Deze code krijg je dus ter beschikking:
private DialogResult InputBox(string title, string promptText, ref string value) { Form form = new Form(); Label label = new Label(); TextBox textBox = new TextBox(); Button buttonOk = new Button(); Button buttonCancel = new Button(); form.Text = title; label.Text = promptText; textBox.Text = value; buttonOk.Text = "OK"; buttonCancel.Text = "Cancel"; buttonOk.DialogResult = DialogResult.OK; buttonCancel.DialogResult = DialogResult.Cancel; label.SetBounds(9, 20, 372, 13); textBox.SetBounds(12, 36, 372, 20); buttonOk.SetBounds(228, 72, 75, 23); buttonCancel.SetBounds(309, 72, 75, 23); label.AutoSize = true; textBox.Anchor = textBox.Anchor | AnchorStyles.Right; buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; form.ClientSize = new Size(396, 107); form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel }); form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height); form.FormBorderStyle = FormBorderStyle.FixedDialog; form.StartPosition = FormStartPosition.CenterScreen; form.MinimizeBox = false; form.MaximizeBox = false; form.AcceptButton = buttonOk; form.CancelButton = buttonCancel; DialogResult dialogResult = form.ShowDialog(); value = textBox.Text; return dialogResult; }

Deze operatie met terugkeerwaarde maakt het mogelijk een tweede formulier te tonen waarin de gebruiker een actie moet ondernemen vooaraleer die terug naar het hoofdformulier kan keren. In H16ZelfVB3 worden de volgende invoervensters mee gegenereerd:

De code die nodig is om deze invoervenster te laten verschijnen:


private string Inlezen(string vraag) { // declaratie string tekst = null; DialogResult antwoord; do { antwoord = InputBox(vraag, "Invullen", ref tekst); } while (string.IsNullOrWhiteSpace(tekst) || antwoord == System.Windows.Forms. DialogResult.Cancel); return tekst; }

Zolang het antwoord leeg is/uit blancos bestaat of cancel is, blijft het invoervenster dus terug op het scherm komen

59

17

Sequentile bestanden - Keypress

Inleiding Tot nu toe verwerkten we altijd invoer die via het toetsenbord opgevraagd werd. De verwerkte gegevens werden altijd naar het scherm gestuurd. In dit hoofdstuk gaan we gegevens verwerken uit bestanden en verwerkte gegevens wegschrijven naar bestanden. Wat is een bestand? Een bestand is een verzameling van gegevens Wat is een record? Een bestand is een verzameling van records. Elke record bundelt de gegevens van n item in het bestand. Wat is een veld? Een record is een verzameling van velden. Een veld beschrijft een eigenschap van een record. Bijvoorbeeld: studentenrecorrd bestaat uit 3 velden: naam / groep / p unten C# Ongestructureerd bestand Er is geen recordtype of sleutelgegeven bij het aanmaken van het bestand. Sequentieel bestand INPUT: De gegevens worden n na n weggeschreven naar het bestand OUTPUT: De gegevens van het bestand worden n na n nagelezen Namespace System.IO In C# is bestandsbeheer voornamelijk gebaseerd op namespace System.IO De meest gebruikte classes zijn: FileStream: voor het openen of creren van bestanden

= tunnel, een verbinding tussen solution en bestand

StreamReader: om tekstgegevens uit bestanden te lezen = pomp om gegevens UIT de tunnel naar de applicatie te pompen StreamWriter: om tekstgegevens naar bestanden te schrijven = pomp om gegevens DOOR de tunnel IN het bestand te pompen

De namespace.IO moet gemporteerd worden Using System.IO OF we moeten bij het gebruiken van klassen uit die namespace de volledige verwijzing naar de namespace opnemen H17VB1 Het doel van dit voorbeeld is de inhoud van een tekstbestand integraal, maar wel in hoofdletters, in de console af te beelden. Het tekstbestand leerpad.txt moet in dezelfde map als de exe staan.

using using using using using

System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB1 { class Program { static void Main(string[] args) { //declaratie StreamReader streamLees = new StreamReader("leerpad.txt"); string inhoud=""; ...

H17VB1 Bespreking Om een bestand te kunnenn lezen, moet je System.IO aanspreken Using System.IO Declareer een object van de klasse StreamReader en instantieert het onmiddelijk new StreamReader() We gebruiken een standaard FileStream, je moet dus enkel de bestandsnaam vermelden binnen de argumenthaken bij initialisatie.
static void Main(string[] args) { //declaratie StreamReader streamLees = new StreamReader("leerpad.txt"); string inhoud=""; //bestand lezen inhoud = streamLees.ReadToEnd(); //bronnen vrijgeven streamLees.Close(); streamLees.Dispose(); //inhoud tonen op console Console.WriteLine(inhoud.ToUpper()); //Wachten op enter Console.ReadLine(); }

Het object van de klasse StreamReader kent de methode ReadToEnd om het hele bestand ineens in te lezen. Geef het bestand onmiddelijk vrij als je het niet langer nodig hebt, anders kunnen andere applicaties het bestand niet gebruiken. Gebruik de methode Close en de methode Dispose.

60

H17VB2 Het doel van H17VB2 is de inhoud van een tekstbestand in de console af te beelden waarbij elke lijn in een andere kleur verschijnt. Het tekstbestand moet in dezelfde map als de exe staan!

We hebben hier opnieuw de namespace System.IO nodig voor StreamReader, maar we moeten lijn per lijn inlezen!
using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB2 { class Program { static void Main(string[] args) { //declaratie int teller = 0; string lijn; //bestand lijn per lijn lezen en in juiste kleur tonen op console using (StreamReader streamLees = new StreamReader("leerpad.txt")) { while (!streamLees.EndOfStream) { teller++; lijn = streamLees.ReadLine(); if (teller % 2 == 0) { Console.ForegroundColor = ConsoleColor.Blue; } else { Console.ForegroundColor = ConsoleColor.Red; } Console.WriteLine(lijn.ToUpper()); } } //Wachten op enter Console.ReadLine();

H17VB2 Bespreking Met de methode ReadLine kan je n lijn gegevens (n record) inlezen, dit is tot aan de eerstvolgende return. Op het einde van het bestand vind je de EndOfStream aanduiding. Je kan niet verder lezen dan het bestand groot is. VRIJGEVEN VAN BRONNEN IS VERPLICHT! H17VB1: streamLees.Close(); streamLees.Dispose(); H17VB2: Bronnen worden automatisch vrijgegeven door gebruik te maken va n het using statement. De StreamReader streamLees is alleen gekend binnen het using-blok en wordt daarna opgeruimd. H17VB3 Het doel van dit voorbeeld is de inhoud van een tekstbestand in de console af te beelden waarbij EEN DEEL VAN ELKE LIJN een andere opmaak moet krijgen. Elke lijn in leerpad.txt bestaat uit 2 delen, gescheiden door een komma

System.IO toevoegen en declareren variabelen voor splitsen lijn:


using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB3 { class Program { static void Main(string[] args) { //declaratie DateTime datum; string lijn; string[] delenArray; // string-Array om resultaat Split() op te vangen //bestand lijn per lijn lezen en in juiste kleur tonen op console using (StreamReader streamLees = new StreamReader("leerpad.txt")) { while (streamLees.Peek() != -1) { //inlezen lijn lijn = streamLees.ReadLine();

61

//lijn splitsen op basis van scheidingsteken komma delenArray = lijn.Split(','); //datum uit string-Array halen en omzetten in DateTime datatype datum = Convert.ToDateTime(delenArray[1]); //lijn met opmaak drukken Console.WriteLine(delenArray[0] + " -> " + datum.ToLongDateString()); } } //Wachten op enter Console.ReadLine();

H17VB3 Bespreking In plaats van te werken met de eigenschap EndOfStream kan je ook de methode Peek() gebruiken. Deze geeft -1 terug als er geen gegevens meer in het bestand zijn. Gegevens splitsen doe je bijvoorbeeld via Substring() of via Split(). H17VB4 Het doel van dit voorbeeld is de inhoud van een tekstbestand OPGESPLITST EN GESORTEERD in de console af te beelden. Het tekst bestand moet in dezelfde map als de exe staan!

using using using using using

System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB4 { class Program { static void Main(string[] args) { //declaraties List<string> namenList = new List<String>(); List<int> scoreList = new List<int>(); string lijn; int index; //bestand inlezen using (StreamReader streamLees = new StreamReader("scores.txt")) { while (!streamLees.EndOfStream) { //inlezen lijn lijn = streamLees.ReadLine(); //opsplitsen en toevoegen aan lijsten namenList.Add(lijn.Substring(0, lijn.IndexOf(","))); scoreList.Add(Convert.ToInt32(lijn.Substring(lijn.IndexOf(",") + 1))); } } //sorteren op basis van score: van hoog naar laag if (namenList.Count > 0) { string[] namenArray = namenList.ToArray(); int[] scoreArray = scoreList.ToArray(); Array.Sort(scoreArray, namenArray); Array.Reverse(scoreArray); Array.Reverse(namenArray); //afdrukken op console Console.WriteLine("Scores van hoog naar laag:"); Console.WriteLine(); for (index = 0; index <= namenArray.GetUpperBound(0); index++) { Console.WriteLine(namenArray[index] + " behaalde " + scoreArray[index] + " op 20"); } } // wachten op enter Console.ReadLine(); } } }

H17VB4 Bespreking Voeg alleen items toe aan de lijsten als je gegevens in het bestand gevonden hebt. Sorteer de arrays pas als er echt iets in de lijsten staan. Vergeet de bronnen niet vrij te geven via using statement close() en dispose().

62

H17VB5 Het doel van dit voorbeeld is de invoer van de gebruiker te BEWAREN in een tekstbestand en meteen te TONEN IN KLADBLOK. Het tekstbestand komt in dezelfde map als de exe te staan!

Om naar een bestand te kunnen schrijven, heb je een object van de klasse StreamWriter nodig:
using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB5 { class Program { static void Main(string[] args) { //declaraties StreamWriter stramSchrijf = new StreamWriter("gasten.txt"); string gast; ...

H17VB5 Bespreking Als je enkel een bestandsnaam gebruikt, werk je met een standaard FileStream. Dit houdt in dat het bestand ALTIJD OPNIEUW AANGEMAAKT WORDT, ook als het al zou bestaan. Gegevens die er eventueel waren, worden dus altijd overgeschreven!
//priming read Console.Write("Wie wil je uitnodigen? (\"stop\" om te stoppen): "); gast = Console.ReadLine(); while (gast.ToLower() != "stop") //test op kritieke waarde { //verder werken met correcte waarde stramSchrijf.WriteLine(gast); //opnieuw kritieke waarde inlezen Console.Write("Wie wil je uitnodigen? (//stop// om te stoppen): "); gast = Console.ReadLine(); }

Gebruik priming read, want enkel correcte gegevens mogen weggeschreven worden! Een object van de klasse StreamWriter kent de methode Write() en de methode WriteLine().
//bronnen vrijgeven streamSchrijf.Close(); streamSchrijf.Dispose(); //bestand dat gemaakt is tonen in kladblok System.Diagnostics.Process.Start("gasten.txt"); //wachten op enter Console.ReadLine();

Geef de bronnen zo snel mogelijk vrij. Dit moet je doen voor je probeert het bestand met kladblok te openen. System.Diagnostics.Process.Start wordt gebruikt om een tekstbestand te openen in de standaardeditor voor txt-bestanden. H17VB6 Het doel van dit voorbeeld is de invoer van de gebruiker te BEWAREN OF TOE TE VOEGEN aan een door de gebruiker opgegeven tekstbestand en meteen te tonen in kladblok. Het tekstbestand komt in dezelfde map als de exe te staan.

Er is een variabele voorzien voor de bestandsnaam opgegeven door de gebruiker. Merk op dat de StreamWriter niet genitialiseerd wordt.
using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB6

63

class Program { static void Main(string[] args) { //declaratie StreamWriter streamSchrijf; string gast, bestand, toevoegen; //keuze van de gebruiker Console.Write("Welk bestand wil u maken? Typ alleen de naam, niet de extensie: " ); bestand = Console.ReadLine(); bestand += ".txt"; Console.Write("Gegeven achteraan toevoegen? (J/N): "); toevoegen = Console.ReadLine(); //initialiseren streamwriter if (toevoegen.ToUpper() == "J") { streamSchrijf = new StreamWriter(bestand, true); } else { streamSchrijf = new StreamWriter(bestand); }

H17VB6 Bespreking De txt-file krijgt de naam bestand Toevoegen gaat door de waarde true mee te geven in de parameter append van de constructor De defaultwaarde voor append is false niet toevoegen maar overschrijven
//priming read Console.Write("Wie wil je uitnodigen? (\"stop\" om te stoppen): "); gast = Console.ReadLine(); while (gast.ToLower() != "stop") //test op kritieke waarde { //verder werken met correcte waarde streamSchrijf.WriteLine(gast); //opnieuw kritieke waarde inlezen Console.Write("Wie wil je uitnodigen? (//stop// om te stoppen): "); gast = Console.ReadLine(); } //bronnen vrijgeven streamSchrijf.Close(); streamSchrijf.Dispose(); //bestand dat gemaakt is tonen in kladblok System.Diagnostics.Process.Start(bestand); //wachten op enter Console.ReadLine();

De rest van de code is analoog aan H17VB5 H17VB7 Het doel van dit voorbeeld is op basis van een scorebestand EEN ANDER GESORTEERD BESTAND te maken met enkel de geslaagde studenten. Het gemaakte tekstbestand komt in dezelfde map als de exe te staan.

using using using using using

System; System.Collections.Generic; System.Linq; System.Text; System.IO;

namespace H17VB7 { class Program { static void Main(string[] args) { //declaraties List<string> namenGeslaagdenList = new List<String>(); List<int> scoreGeslaagdenList = new List<int>(); string lijn, naam; int index, score; //bestand inlezen using (StreamReader streamLees = new StreamReader("scores.txt")) { while (!streamLees.EndOfStream) { // inlezen lijn lijn = streamLees.ReadLine(); //opsplitsen en geslaagden toevoegen aan lijsten naam = lijn.Substring(0, lijn.IndexOf(",")); score = Convert.ToInt32(lijn.Substring(lijn.IndexOf(",") + 1)); if (score >= 10) { namenGeslaagdenList.Add(naam); scoreGeslaagdenList.Add(score); }

64

H17VB7 Bespreking Lees alle lijnen in, maar vergroot de lijsten pas als je een geslaagde studen (score 10) gevonden hebt. Het bestand wordt na het beindigen van het using statement vrijgegeven.
// wegschrijven naar bestand using (StreamWriter streamSchrijf = new StreamWriter("proclamatie.txt")) { //titel wegschrijven streamSchrijf.WriteLine("Lijst van geslaagden:"); if (namenGeslaagdenList.Count > 0) { //sorteren op basis van score van hoog naar laag string[] namenArray = namenGeslaagdenList.ToArray(); int[] scoreArray = scoreGeslaagdenList.ToArray(); Array.Sort(scoreArray, namenArray); Array.Reverse(scoreArray); Array.Reverse(namenArray); //wegschrijven naar bestand for (index = 0; index <= namenArray.GetUpperBound(0); index++) { streamSchrijf.WriteLine(namenArray[index] + " behaalde " + scoreArray[index] + " op 20."); } } else { streamSchrijf.WriteLine("Er zijn geen geslaagden."); } }

Maak vervolgens een objectvariabele van de klasse StreamWriter aan. Er is net zoals bij StreamReader gebruik gemaakt van een using statement om de StreamWriter te declareren en te initialiseren. Dit betekent dat op het einde van de using blok alle bronnen automatisch worden vrijgegeven. Sorteer alleen als je ook effectief gegevens in de lijsten hebt. Schrijf de inhoud van de arrays we naar he t bestand. Als de arrays leeg zijn, wordt de tekst Er zijn geen geslaagden weggeschreven.
System.Diagnostics.Process.Start("proclamatie.txt");

Process.Start opent de txt in kladblok. Het is niet nodig nog op enter te wachten, de toepassing mag meteen geloten worden. H17VB8 Dit programma is een Windowsapplicatie die met een bestand werkt (lezen/uitbreiden). H17VB8 DEEL 1: BESTAND LEZEN EN TONEN IN TEKSTVAK Aan het formulierontwerp wordt niets gewijzigd!

Bij het laden van het formulier breng je alle controls in orde; Bij de menukeuze Bekijken lees je de gegevens uit een bestand. Werk op dezelfde manier als in Console:
using System.IO; namespace H17VB8 { public partial class FormStart : Form { public FormStart() { InitializeComponent(); } private void FormStart_Load(object sender, EventArgs e) { this.Text = DateTime.Now.ToLongDateString(); textBoxOverzicht.Multiline = true; textBoxOverzicht.Dock = DockStyle.Fill; textBoxOverzicht.ScrollBars = ScrollBars.Both; }

Declareer en initialiseer StreamReader; geef de bronnen zo snel mogelijk vrij:


private void bekijkenToolStripMenuItem_Click(object sender, EventArgs e) { using (StreamReader streamLees = new StreamReader("prijzen.txt")) { textBoxOverzicht.Text = streamLees.ReadToEnd(); } }

65

H17VB8 DEEL 2: BESTAND UITBREIDEN EN TONEN IN TEKSTVAK Deze applicatie bevat twee formulieren: FormStart.cs en FormToevoegen.cs FormToevoegen wordt opgeroepen bij klikken op MenuItem Toevoegen in FromStart. Zelf een form toevoegen aan een project doe je via: Add New Item Windows Form FormStart:
private void uitbreidenToolStripMenuItem_Click(object sender, EventArgs e) { //declareren en initialiseren FormToevoegen FormToevoegen form = new FormToevoegen(); //FormToevoegen tonen form.ShowDialog(); //opnieuw tonen overzicht na sluiten FormToevoegen bekijkenToolStripMenuItem_Click(uitbreidenToolStripMenuItem,e);

H17VB8 Bespreking Een tweede formulier oproepen doe je door een instantie van dit formulier aan te maken. FormToevoegen form = new FormToevoegen(); Deze instantie toon je via de methode Show() of via ShowDialog(). ShowDialog() Het formulier dat geopend wordt met de methode ShowDialog() werkt als een standaard dialoogvenster. Het startformulier is dus niet toegankelijk voor de gebruiker zolang het dialoogvenster openstaat. Pas wanneer het dialoogvenster is afgesloten wordt de code op het startformulier verder uitgevoerd. FormToevoegen:
using System.IO; namespace H17VB8 { public partial class FormToevoegen : Form { public FormToevoegen() { InitializeComponent(); } private void FormToevoegen_Load(object sender, EventArgs e) { this.ControlBox = false; this.Text = "Toevoegen"; } private void buttonToevoegen_Click(object sender, EventArgs e) { double getal; using (StreamWriter streamSchrijf = new StreamWriter("prijzen.txt", true)) { //alleen wegschrijven als beide tekstvakken niet leeg zijn en prijs een reel getal is if (textBoxProduct.Text != "" && textBoxPrijs.Text != "" && double.TryParse(textBoxPrijs.Text, out getal)) { streamSchrijf.WriteLine(textBoxProduct.Text + "*" + getal); this.Close(); } else { MessageBox.Show("Toevoegen mislukt, vul beide tekstvakken in! \nPrijs moet een getal zijn!"); } } }

H17VB8 Bespreking Bij klikken op de button Toevoegen schrijf je de gegevens naar een bestand. Werk op dezelfde manier als in Console: Importeer de namespace System.IO Declareer en initialiseer StreamWriter Als je gegevens wegschrijft, moet je die controleren. Probeer fouten te vermijden door goede invoercontroles. Geef de bronnen zo snel mogelijk vrij. Na wegschrijven naar het bestand wordt het formulier FormToevoegen gesloten om terug te keren naar FormStart. Dit gebeurt via de methode: this.Close(); Na sluiten van FormToevoegen wordt de code na de oproep via ShowDialog() uitgevoerd:
private void uitbreidenToolStripMenuItem_Click(object sender, EventArgs e) { //declareren en initialiseren FormToevoegen FormToevoegen form = new FormToevoegen(); //FormToevoegen tonen form.ShowDialog(); //opnieuw tonen overzicht na sluiten FormToevoegen bekijkenToolStripMenuItem_Click(uitbreidenToolStripMenuItem,e); }

66

H17VB9 Deze voorbeeld is een uitbreiding op H17VB8. In FormToevoegen wordt in de klik gebeurtenis gecontroleerd of beide tekstvakken inhoud bevatten en of de prijs wel een double is. Het controleren van de inhoud van het prijstekstvak gebeurt in H17VB9 via het eve nt KeyPress van de tekstvakken. FormToevoegen:
private void textBoxPrijs_KeyPress(object sender, KeyPressEventArgs e) { if (!(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar) || e.KeyChar == ',')) { e.Handled = true; } }

KeyPress Event KeyPress doet zich voor wanneer je een karakter intypt. e.KeyChar bevat de toets die je hebt ingedrukt. We controleren of deze toets overeenkomt met de opgelegde beperkingen. Voldoet de toets niet, dan wordt e.Handled = true. Hierdoor wordt de toetsaanslag niet meer verder gestuurd naar het scherm en dus niet meer getoond in het tekstvak. We gebruiken de klasse Char, omdat daar methodes ter beschikking zijn om na te gaan og een karakter van een bepaalde soort is. IsDigit() test iets anders uit dan IsNumber(): Bij IsNumber mag 2 en 3 ook ingetoetst worden, bij IsDigit niet. e.Handled = false moet je niet schrijven, want dat is de defaultwaarde. e.Handled = false betekent dat de toetsaanslag nog niet afgewerkt is en dus nog door moet gaan naar het scherm. D.m.v. KeyPress bij het prijstekstvak, kan je de controlere bij wegschrijven naar het bestand inperken:
private void buttonToevoegen_Click(object sender, EventArgs e) { using (StreamWriter streamSchrijf = new StreamWriter("prijzen.txt", true)) { //alleen wegschrijven als beide tekstvakken niet leeg zijn //controle prijs een reel getal gebeurt nu via keypress if (textBoxProduct.Text != "" && textBoxPrijs.Text != "" ) { streamSchrijf.WriteLine(textBoxProduct.Text + "*" + textBoxPrijs.Text); this.Close(); } else { MessageBox.Show("Toevoegen mislukt, vul beide tekstvakken in! \nPrijs moet een getal zijn!"); } } } private void textBoxPrijs_KeyPress(object sender, KeyPressEventArgs e) { if (!(char.IsLetterOrDigit(e.KeyChar) || char.IsWhiteSpace(e.KeyChar) || e.KeyChar == (char) Keys.Back)) { e.Handled = true; } }

H17VB9 Bespreking
char.IsWhiteSpace(e.KeyChar) (char) Keys.Back)

spatie backspace

Testen op backspace kan door de ASCII-waarde can de backspace die je kan opvragen via Keys.Back te casten naar een char en te vergelijken met e.KeyChar.

67

You might also like