Wat is programmeren
.NET Framework
Als je programmeert, maak je altijd gebruik van bundel vooraf geschreven code waarop je kan voortbouwen. Het zou niet handig zijn als je bij elk programma opnieuw knoppen, dialoogvensters, scrollbars enz... vanaf nul moet programmeren! Een dergelijke bundel noemt men een framework.
Frameworks bestaan in veel gebieden:
- game programming: Unity3D, Unreal, ...
- web & mobile apps: Ionic, Phonegap, React, Angular, ...
- 3D programming: ThreeJS, Babylon, ...
- …
In deze cursus gebruiken we het .NET Framework: het is weliswaar voornamelijk gericht op Windows apps, maar ook op mobiele (Android bv) of cloud toepassingen. Het werkt bovendien naadloos samen met C#.
De term famework wordt vaak verward met library. Er is nochtans een duidelijk verschil:
- Een framework is een fundamentele structuur die als basis dient voor het schrijven van programma's, b.v. .NET, Angular (Javascript), Spring (Java)... Je plugt je code in een framework.
- Een library is een pakket herbruikbare code die je in je projecten kan gebruiken, b.v. ScottPlot.NET voor grafieken. Het is eerder een hulp; je plugt een library in je code.
Verwar een library dan weer niet met een package, wat in .NET een manier is om libraries, scripts, tools enz... toe te voegen aan je .NET projecten — vergelijkbaar met extensies in VS Code, plugins in browsers en node modules in NodeJS. De gebruikte tool is NuGet Package Manager; we zullen dit later gebruiken voor de StyleCop.Analyzers code quality tool.
Fasen van een programma
Een programma is een opeenvolging van instructies die in een bepaalde volgorde worden uitgevoerd. Het hele proces van code tot uitvoering bestaat uit drie grote stappen. Grafisch samengevat:
Coderen
Dit is het schrijven van een programma, b.v. C# in de Visual Studio ontwikkelomgeving.
Builden
Als je klaar bent, ga je naar de volgende stap, het builden (shortcut: Ctrl-B)
De code wordt in verschillende stappen omgezet naar een .exe bestand met platform-onafhankelijke tussencode, CIL of Common Intermediate Language genoemd, bestaande uit low-level instructies of bytecodes. Voor de geïnteresseerden: je kan de bytecodes zien door de .exe te openen in tools als ILSpy. Enkele aspecten van het build proces:
- linking: combineren van alle bronnen, codefiles, libraries, referenties enz... in één bestand
- compiling: vertaling van hig-level C# code naar low-level bytecodes
In de output kan je zien of er buildfouten zijn:
Als de build gelukt is, komen er twee mappen bij in je project:
- bin: bevat de binaire (uitvoerbare) bestanden
- obj: bevat tijdelijke en intermediarie bestanden
Sommige buildproblemen kan je oplossen door de bin en obj mappen handmatig te verwijderen, en opnieuw te builden.
Uitvoeren
Je kan het programma nu starten vanuit Visual Studio (shortcut: Ctrl-F5):
Je kan het programma ook starten door het rechtstreeks te starten in de bin map:
De .NET Common Language Runtime (CLR) zal tijdens de uitvoering (JIT: just in time) de bytecode vertalen in platform-specifieke machine-instructies.
Soorten fouten
In elke fase van het programma kunnen fouten optreden:
- syntax error: je code bevat een fout tegen de vormregels van de programmeertaal, bv. puntkomma of haakje vergeten
- build error: je code is correct geschreven, maar tijdens het builden loopt iets fout, bv. een bibliotheek wordt niet gevonden
- runtime error: je code compileert netjes, maar tijdens het uitvoeren loopt je programma vast, bv. een onverwachte deling door nul, geheugenfout, bestand wordt niet gevonden enz...
- logical error: je programma loopt niet vast, maar doet niet wat je verwacht, bv. de output is verkeerd of een knop werkt niet
Integrated Development Environment (IDE)
De ontwikkelomgeving of Integrated Development Environment is de omgeving waarin je programma's ontwikkelt. Typische features van IDE's:
- werken met solutions & projecten
- code schrijven: code editor, code hints, automatische layout, object browser...
- interfaces bouwen (vensters, knoppen, menu's...) met de designer
- programma's builden en runnen, eventueel simulators (bv. mobiele devices)
- tools om te debuggen (foutopsporing),
- testen: unit tests, performantie metingen, analyse geheugengebruik...
- samenwerking: versiebeheer, code review, live sharing...
- distributie: cloud integratie, publicatie op het web...
- ...
De meest gebruikte omgeving voor C# Visual Studio (versie 2022 op moment van schrijven).
Installatie Visual Studio
Downloaden
Download en installeer Visual Studio gratis vanop https://visualstudio.microsoft.com/free-developer-offers/ (Visual Studio Community)
Keuze workload
In Visual Studio kan je programmeren in verschillende talen (en zelfs meerdere tegelijk in één project): Javascript, Python, C++, Visual Basic, R, F#, C#... en voor verschillende platforms (Windows, Azure, Android, Web…). Daarom biedt Visual Studio een heel aantal verschillende standaardomgevingen, workload genoemd, met tools, omgeving enz... aangepast aan jouw specifieke ontwikkelingsbehoeften. Wij gebruiken de .NET desktop environment; let er dus op dat je de juiste omgeving kiest tijdens installatie.
Selecteren individuele componenten
Je kan tijdens installatie (of achteraf) individuele componenten kiezen, b.v. support voor oudere versies van .NET. Je kan dit deel voorlopig overslaan; individuele componenten kan je achteraf nog altijd selecteren via de Visual Studio installer.
Taalkeuze
Het is sterk aangeraden de taal van Visual Studio op Engels in te stellen. Dit maakt het b.v. makkelijker foutmeldingen op te zoeken, en de interface sluit dan aan bij de screenshots in deze cursus. Standaard wordt de taal van Windows gekozen; bij veel studenten zal dat Frans of Nederlands zijn. Verander dit naar Engels via Tools, Options, Environment, International Settings:
Staat Engels er niet tussen? Voeg het dan toe via de Visual Studio Installer.
Personaliseren
Thema veranderen
Pas het kleurschema aan via Tools, Theme:
Panels toevoegen
Voeg panels toe via View:
Panels pinnen
Pin/unpin panels zodat ze altijd zichtbaar/ingeklapt weergegeven worden:
Panels docken
Kiezen waar je een panel plaatst heet docken. Opties zijn links, boven, rechts, onder en centraal. Versleep eenvoudigweg het panel aan de bovenbalk naar een nieuwe plaats:
Solutions en projecten
Solution vs. project
- een project groepeert alle bestanden die bij één programma horen: codebestanden, afbeeldingen, configuratiebestanden...
- een solution groepeert een aantal projecten die om één of andere reden logisch bij elkaar horen
Hoe code georganiseerd wordt in solutions en projecten hangt af van vak tot vak. Voor Introductie in Programmeren (ORP42a, graduaat) en OO Application Development (OBI25a, bachelors) wordt gekozen voor één solution per les, één project per oefening. Hieronder een screenshot van een typische les geopend in Visual Studio.
Je herkent:
- de solution SlnBasis; dit is de les waamee we bezig zijn
- de projecten ConsoleAsciiArt, ConsoleGedicht, ConsoleHalloWereld...; dit zijn de oefeningen behorende bij die les
- de bronnen Properties, References, App.config, Program.cs onder ConsoleHalloWereld: dit zijn de bestanden/mappen behorende bij die oefening
- het codevenster links: hierin schrijf je je code
Solution (=les) openen
In Visual Studio open je nooit een folder, maar een solution. Dit doe je door te dubbelklikken op het .sln solutionbestand van die les in verkenner:
Project (=oefening) toevoegen
Voor elke oefening voegen we een nieuw project toe aan de solution van die les. De eenvoudigste manier is met de rechtermuisknop op de solution, Add, New Project...:
In het volgende venster kan je kiezen uit heel veel projecttypes. In het volgende dialoogvenster je filtert best alvast op taal (C#) en platform (Windows):
Project types
In eerstejaarsvakken komen hoofdzakelijk deze twee types aan bod:
- Console application: programma uitgevoerd in een simpel commandprompt-achtig venster
- WPF application: een typisch Windows programma in een venster met menu’s, knoppen, dialoogvensters, scrollbars…
Op het einde van OO Application Development komt ook nog de class library aan bod, maar dat is voor dit hoofdstuk.
Console toepassingen hebben beperktere mogelijkheden dan WPF; daar staat tegenover dat je kan focussen op de essentie van leren programmeren. WPF toepassingen aan de andere kant laten toe snel een interface te bouwen met knoppen, menu's, sliders, date pickers enz... wat het dan weer makkelijker maakt complexere toepassingen te bouwen, al vraagt het meer kennis van Visual Studio. Sommigen studenten schrijven liever console toepassingen, anderen geven de voorkeur aan WPF, maar bij de meesten is er geen duidelijke voorkeur.
Wij zijn ervan overtuigd dat beide projecttypes elkaar aanvullen als manier om te leren programmeren.
Console Application
Een console applicatie draait dus in de console, i.e. een soort commandprompt-achtig venster. De mogelijkheden zijn beperkter dan bij WPF toepassingen, vooral grafische en UI componenten ontbreken. Enkele voorbeelden van wat wel/niet kan:
- tekst in- en output
- voor- en achtergrondkleur
- muziek en andere geluiden
- bestanden lezen en schrijven
- werken met databanken
- grafische vormen als ellipsen, rechthoeken...
- form controls
- video
- UI componenten als menu's, scrollbars...
- dialoogvensters (bestanden openen e.d.)
Aanmaken
Om een console toepassing te maken, open je eerst de solution van de les. Dan voeg je zoals steeds een project toe met Add, New Project...:
In het volgende venster kies je voor Console App:
Je vindt mogelijks nog andere versies zoals Console App (.NET Core) of Console App (.NET Framework). Dit zijn (sterk) verouderde types, die mag je niet gebruiken! Let er dus op dat het type exact is als op de screenshot.
Kies de naam van het project exact hetzelfde als de naam van de oefening:
In het laatste venster kies je voor de laatste versie, en duid aan dat je geen top-level statements wil:
Voorbeeld: ConsoleHalloWereld
Tenslotte kan je de code van het programma intypen:
Run het programma via F5 of deze knop:
Het programma in actie:
WPF Application
WPF staat voor Windows Presentation Foundation, een technologie van Microsoft om Windows toepassingen te bouwen. Ze hebben een grafische interface met knoppen, menu's, sliders, tekstvakken, afbeeldingen... en zijn daardoor visueel aantrekkelijker dan console applicaties. De mogelijkheden zijn dus uitgebreider dan Console toepassingen, maar de leercurve is ook steiler.
Aanmaken
Om een WPF toepassing te maken, open je weer eerst de solution van de les. Dan voeg je zoals steeds een project toe met Add, New Project...:
In het volgende venster kies je voor WPF Application:
Je vindt mogelijks nog andere versies zoals Windows Forms Application of WPF App (.NET Framework). Dit zijn (sterk) verouderde types, die mag je niet gebruiken! Let er dus op dat het type exact is als op de screenshot.
Kies de naam van het project exact hetzelfde als de naam van de oefening:
In het laatste venster kies je voor de laatste versie:
Designer
WPF toepassingen hebben twee aparte delen:
- designer: drag-drop interface (versleep controls uit de toolbox links) → XAML code in MainWindow.xaml
- code-behind, de “code achter het design”: geschreven in C# code → C# code in MainWindow.xaml.cs
In de designer kan je controls toevoegen en properties instellen; de gegenereerde XAML (spreek uit: “zammel”) middenonder kan je ook rechtstreeks met de hand aanpassen of aanvullen.
XAML manueel aanpassen
De XAML code wordt automatisch gegenereerd via de designer, maar het lijkt qua structuur sterk op HTML. Hou je dus zeker niet in met de hand aanpassingen te doen (zie b.v. deze opmaakproperties in de C# cursus):
Controls toevoegen
Een WPF component als Button, TextBox enz... toevoegen heet een WPF control. In het hoofdstuk WPF Controls komen we uitgebreid op terug op alle controls en hun gebruik. Voeg ze toe door verslepen uit de Toolbox:
Eigenschappen instellen
De volgende stap is het instellen van alle eigenschappen:
- naam van de control
- opmaak: tekst, kleur, lettertype, grootte...
- layout: positie, grootte, marges...
- events (wat gebeurt er als je op de knop klikt?)
- ...
naam
Controls die je later nodig hebt, geef je best onmiddellijk een naam:
Controls als titels of vaste afbeeldingen die je niet nodig hebt in je programmeercode later, hoef je geen naam te geven.
We gebruiken de Hongaarse notatie: een drieletter prefix plus een omschrijving in PascalCase.
Voorbeelden: btnOk, inpNaam, txtError...
opmaak
Opmaakeigenschappen kan je via het properties panel instellen, of rechtstreeks in de XAML:
layout
Een correcte flexibele layout maken vraagt best wel wat kennis en werk; dit komt in een apart hoofdstuk 04. WPF layout aan bod. Maar voorlopig kunnen we perfect uit de voeten met slepen, en handmatig aanpassen van Padding
en Margin
. De makkelijkste plaats is rechtstreeks in de XAML. Gebruik zoveel mogelijk afgeronde waarden voor een mooie layout:
Events toevoegen
We willen uiteraard ook kunnen reageren op interacties met onze controls. Denk aan:
- klikken op een knop
- veranderen van een sliderwaarde
- selecteren van een item in een lijst
- tekst intikken in een tekstvak
- ...
Er zijn meerdere soorten events mogelijk op controls, b.v. een Button
kent zowel Click
, MouseEnter
als MouseLeave events. Het “meest logische” event is het standaardevent; bij de Button
is dat Click
.
Voeg een standaardevent toe door dubbelklikken op de control, of kies een willekeurig ander event via de⚡knop van het properties panel:
Het toevoegen van een event heeft twee effecten:
- in de XAML code (bestand MainWindow.xaml) wordt een event handler methode gekoppeld aan een event
- in de code-behind (bestand MainWindow.xaml.cs) wordt een lege event handler methode aangemaakt
naam event handler aanpassen
De stijlregels (zie verder) vereisen dat alle namen van methodes met een hoofdletter beginnen. Pas daarom de naam aan zodat het begint met een hoofdletter:
Pas namen van variabelen, methodes e.d. nooit manueel aan maar altijd aan via Rename — zo ben je zeker dat de naam overal in je code (C#, XAML) correct aangepast wordt.
Code-behind
De code-behind, dus de “code achter het design”, is het eigenlijke programma. Je vindt het terug in MainWindow.xaml.cs:
Voorbeeld: WpfHalloWereld
Je zou nu in staat moeten zijn volgend WPF programma in elkaar te steken:
Media en andere bestanden toevoegen
Om bestanden als afbeeldingen of geluidsfragmenten toe te voegen aan je project, volg je deze stappen:
- maak een map aan in je project voor de media bestanden via Add, New Folder...
- drag drop de afbeeldingen in deze map uit verkenner
- selecteer bij de properties voor elke afbeelding bij Build Action Content en bij Copy to Output Directory Copy always:
Deze laatste stap mag je niet vergeten! Anders zullen je bestanden niet gevonden worden bij de uitvoering van je programma.
Solutions en projecten aanpassen
Bestaand project toevoegen of verplaatsen uit andere solution
Stappen:
- kopieer de projectmap naar de doelsolutionmap (als die er niet al in zit)
- voeg het project toe via rechtermuisknop, Add, Existing project... en selecteer het .csproj bestand van het project
Project verwijderen
Als je een project wil verwijderen, moet je twee stappen ondernemen:
- verwijder het project uit de solution
- verwijder het project van de harde schijf
Naam solution wijzigen
Volg deze stappen om de naam van een solution te wijzigen, b.v. van SlnOld naar SlnNew:
- sluit de solution
- hernoem de solution folder naar SlnNew
- hernoem het .sln bestand naar SlnNew.sln
- (voor de zekerheid) open de solution folder eens in VS Code (dus niet Visual Studio) en vervang met search/replace overal SlnOld door SlnNew
- heropen de solution, en rebuild het
Naam project wijzigen
De naam van een project wijzigen vraagt best wel wat stappen. Een voorbeeld van WpfOld naar WpfNew:
- sluit de solution
- hernoem de project folder naar WpfNew
- hernoem het .csproj bestand naar SlnNew.csproj
- (voor de zekerheid) open de project folder eens in VS Code (dus niet Visual Studio) en vervang met search/replace overal WpfOld door WpfNew
- open de solution; het oude project WpfOld zal niet meer gevonden worden, verwijder die dus uit de solution
- voeg het nieuwe project WpfNew toe aan de solution
- hernoem in een willekeurig codebestand uit het project de namespace van WpfOld naar WpfNew
- rebuild het project
StyleCop.Analyzers
Als programmeeur kan je eigenlijk niet zonder code analyse tools, denk maar aan b.v. html-validate voor HTML of StyleLint voor CSS. Features:
- codingstijl: controle op consistente toepassing van hoofdletters, layout, commentaar, accolades...
- optimalisatie: suggesties voor kortere, efficiëntere en beter leesbare code
- foutopsporing: veel fouten komen voort uit slordigheden, die deze tools helpen vermijden
- configuratie: via een configuratiebestand kun je de regels en de manier waarop ze afgedwongen worden personaliseren
Installatie
Voor C# gebruiken we de StyleCop.Analyzers NuGet package. Voeg het toe aan je project via de NuGet package manager:
Zoek op “StyleCop.Analyzers” en vink alle projecten aan:
Als je een nieuw project toevoegt, moet je opnieuw naar dit scherm om ook bij dit project StyleCop aan te vinken!
Configuratie
StyleCop.Analyzers heeft heel veel regels — teveel eigenlijk, zodat je massa's foutmeldingen krijgt. Gelukkig kan je de regels configureren met een .editorconfig in de solution map:
Dit bestand bevat alle configureerbare regels:
Het is niet de bedoeling dat je zelf de regels gaat opstellen of veranderen. Voor elk vak zul je het configuratiebestand aangeleverd krijgen, zodat de regels voor alle studenten identiek zijn. Controleer gewoon of bestand aanwezig is, en zoniet, download het van Toledo en steek het in de solution.
Problemen oplossen
Je moet uiteraard niet alleen StyleCop installeren, maar ook effectief alle fouten en waarschuwingen oplossen:
Debugging
Het stap voor stap doorlopen van je code, en ondertussen de waarden van properties en variabele in het oog houden, heet debugging.
Breekpunt(en) plaatsen
Plaats overal waar je de uitvoering van het programma wil pauzeren een breekpunt in de grijze balk links:
Programma doorlopen
Doorloop dan stap voor stap je programma:
- continue: ga door tot het volgende breekpunt
- step over: voer de volgende regel uit
- step into: stap in een methode
- step out: stap uit een methode
Variabelen inspecteren
Via de rechtermuisknop kan je een zgn. watch toevoegen aan een variabele:
Je kan dan de waarde van variabelen observeren tijdens het debuggen:
Shortcuts
Typische Visual Studio shortcuts die je zou moeten kennen:
Shortcut | Betekenis |
---|---|
Ctrl-K+D |
Document format |
Ctrl-K+C, Ctrl-K+U |
Comment, Uncomment geselecteerd blok |
F5 |
programma starten |
Ctrl+F5 |
programma starten zonder debugging |
F7 |
open code behind |
Ctrl-Alt-=, Ctrl-Alt-- |
zoom design view in / uit |
Nog enkele algemene shortcuts van elke tekst editor: