diff --git a/Models/Product.cs b/Models/Product.cs
index 56bb692..1c91136 100644
--- a/Models/Product.cs
+++ b/Models/Product.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
@@ -8,8 +10,35 @@ namespace MVVM_DEMO.Models
{
public class Product
{
- public string ProductName { get; set; }
- public double Price { get; set; }
+ private string _productName;
+ private decimal _productPrice;
+
+ public string ProductName
+ {
+ get => _productName;
+ set
+ {
+ _productName = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public decimal ProductPrice
+ {
+ get => _productPrice;
+ set
+ {
+ _productPrice = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
}
}
diff --git a/STUDENT_HANDLEIDING.md b/STUDENT_HANDLEIDING.md
new file mode 100644
index 0000000..c341d43
--- /dev/null
+++ b/STUDENT_HANDLEIDING.md
@@ -0,0 +1,1617 @@
+# WPF MVVM Tutorial - Stap voor Stap Handleiding
+
+## Inhoudsopgave
+1. [Introductie](#introductie)
+2. [Vereisten](#vereisten)
+3. [Wat is MVVM?](#wat-is-mvvm)
+4. [Stap 1: Project Opzetten](#stap-1-project-opzetten)
+5. [Stap 2: Projectstructuur Aanmaken](#stap-2-projectstructuur-aanmaken)
+6. [Stap 3: Het Model Bouwen](#stap-3-het-model-bouwen)
+7. [Stap 4: RelayCommand Implementeren](#stap-4-relaycommand-implementeren)
+8. [Stap 5: Het ViewModel Bouwen](#stap-5-het-viewmodel-bouwen)
+9. [Stap 6: De View Bouwen](#stap-6-de-view-bouwen)
+10. [Stap 7: Testen en Uitvoeren](#stap-7-testen-en-uitvoeren)
+11. [Concepten Uitgelegd](#concepten-uitgelegd)
+12. [Veelgemaakte Fouten](#veelgemaakte-fouten)
+
+---
+
+## Introductie
+
+Deze handleiding leidt je stap voor stap door het bouwen van een WPF-applicatie met het MVVM (Model-View-ViewModel) ontwerppatroon. Je bouwt een eenvoudige productenbeheer applicatie waarbij je leert over:
+- Data Binding
+- Observable Collections
+- Property Change Notifications
+- ICommand Pattern
+- Separation of Concerns
+
+**Eindresultaat**: Een werkende applicatie waar je producten kunt bekijken, selecteren en toevoegen met automatische UI-updates.
+
+---
+
+## Vereisten
+
+### Software
+- Visual Studio 2022 (Community, Professional of Enterprise)
+- .NET 8.0 SDK
+
+### Kennis
+- Basis kennis van C#
+- Object-georiënteerd programmeren
+- Basiskennis van XAML (niet vereist maar handig)
+
+---
+
+## Wat is MVVM?
+
+MVVM staat voor **Model-View-ViewModel** en is een ontwerppatroon dat helpt bij het scheiden van:
+
+- **Model**: De data en business logica
+- **View**: De gebruikersinterface (XAML)
+- **ViewModel**: De tussenpersoon die data voorbereidt voor de View
+
+### Voordelen van MVVM:
+- **Scheiding van zorgen**: UI-code gescheiden van business logica
+- **Testbaarheid**: ViewModels kunnen eenvoudig worden getest zonder UI
+- **Herbruikbaarheid**: Models en ViewModels zijn herbruikbaar
+- **Data Binding**: Automatische synchronisatie tussen UI en data
+
+### Diagram:
+```
+View (XAML) <------ Data Binding ------> ViewModel
+ |
+ |
+ Model
+```
+
+---
+
+## Stap 1: Project Opzetten
+
+### 1.1 Nieuw Project Aanmaken
+
+1. Open Visual Studio 2022
+2. Klik op **"Create a new project"**
+3. Zoek naar **"WPF Application"** (niet WPF App (.NET Framework)!)
+4. Selecteer **"WPF Application"** en klik **Next**
+
+### 1.2 Project Configureren
+
+1. **Project name**: `MVVM_DEMO`
+2. **Location**: Kies een geschikte locatie
+3. **Solution name**: `MVVM_DEMO`
+4. Klik **Next**
+
+### 1.3 Framework Selecteren
+
+1. Selecteer **.NET 8.0** als framework
+2. Klik **Create**
+
+### 1.4 Wat Krijg Je?
+
+Visual Studio creëert automatisch:
+- `App.xaml` en `App.xaml.cs` - De applicatie startpunt
+- `MainWindow.xaml` en `MainWindow.xaml.cs` - Het hoofdvenster
+- `MVVM_DEMO.csproj` - Project configuratie
+
+---
+
+## Stap 2: Projectstructuur Aanmaken
+
+Een goede mappenstructuur is essentieel voor overzichtelijke MVVM-applicaties.
+
+### 2.1 Mappen Aanmaken
+
+In de **Solution Explorer**:
+
+1. **Rechtsklik** op het project `MVVM_DEMO`
+2. Selecteer **Add > New Folder**
+3. Maak de volgende mappen aan:
+ - `Models`
+ - `ViewModels`
+ - `Views`
+ - `Commands`
+ - `ValueConverters` (voorlopig leeg, voor toekomstige uitbreidingen)
+
+### 2.2 MainWindow.xaml Verplaatsen
+
+1. **Sleep** `MainWindow.xaml` naar de `Views` map
+2. Visual Studio vraagt of je namespace references wilt updaten - klik **Yes**
+
+### 2.3 Projectstructuur Controleren
+
+Je projectstructuur zou er nu zo uit moeten zien:
+```
+MVVM_DEMO/
+├── Commands/
+├── Models/
+├── ViewModels/
+├── Views/
+│ ├── MainWindow.xaml
+│ └── MainWindow.xaml.cs
+├── ValueConverters/
+├── App.xaml
+└── MVVM_DEMO.csproj
+```
+
+---
+
+## Stap 3: Het Model Bouwen
+
+Het **Model** bevat de data structuur. We gaan een `Product` class maken.
+
+### 3.1 Product Class Aanmaken
+
+1. **Rechtsklik** op de `Models` map
+2. Selecteer **Add > Class...**
+3. Naam: `Product.cs`
+4. Klik **Add**
+
+### 3.2 Product Class Implementeren
+
+Open `Product.cs` en vervang de inhoud met:
+
+```csharp
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MVVM_DEMO.Models
+{
+ public class Product
+ {
+ private string _productName;
+ private decimal _productPrice;
+
+ public string ProductName
+ {
+ get => _productName;
+ set
+ {
+ _productName = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public decimal ProductPrice
+ {
+ get => _productPrice;
+ set
+ {
+ _productPrice = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ }
+}
+```
+
+### 3.3 Code Uitleg
+
+#### Private Fields
+```csharp
+private string _productName;
+private decimal _productPrice;
+```
+- **Backing fields** voor de properties
+- Conventie: underscore prefix voor private fields
+
+#### Properties met OnPropertyChanged
+```csharp
+public string ProductName
+{
+ get => _productName;
+ set
+ {
+ _productName = value;
+ OnPropertyChanged();
+ }
+}
+```
+- **get**: Retourneert de waarde van het private field
+- **set**: Zet de nieuwe waarde EN roept `OnPropertyChanged()` aan
+- Dit zorgt ervoor dat de UI wordt genotificeerd bij wijzigingen
+
+#### INotifyPropertyChanged Event
+```csharp
+public event PropertyChangedEventHandler PropertyChanged;
+```
+- Event dat wordt afgevuurd wanneer een property verandert
+- De UI kan zich abonneren op dit event
+
+#### OnPropertyChanged Method
+```csharp
+protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+{
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+}
+```
+- **[CallerMemberName]**: Automatisch de naam van de aanroepende property
+- **PropertyChanged?.Invoke**: Veilig aanroepen (alleen als er listeners zijn)
+- **PropertyChangedEventArgs**: Bevat de naam van de gewijzigde property
+
+### 3.4 Waarom INotifyPropertyChanged?
+
+Zonder `INotifyPropertyChanged` weet de UI niet wanneer data verandert. Met dit pattern:
+1. Property wordt gewijzigd
+2. `OnPropertyChanged()` wordt aangeroepen
+3. Event wordt afgevuurd
+4. UI luistert naar het event
+5. UI update zichzelf automatisch
+
+---
+
+## Stap 4: RelayCommand Implementeren
+
+**Commands** zijn de MVVM-manier om button clicks en andere UI-acties af te handelen zonder code-behind.
+
+### 4.1 RelayCommand Class Aanmaken
+
+1. **Rechtsklik** op de `Commands` map
+2. Selecteer **Add > Class...**
+3. Naam: `RelayCommand.cs`
+4. Klik **Add**
+
+### 4.2 RelayCommand Implementeren
+
+Open `RelayCommand.cs` en vervang de inhoud met:
+
+```csharp
+using System;
+using System.Windows.Input;
+
+namespace MVVM_DEMO.Commands
+{
+ ///
+ /// A command whose sole purpose is to relay its functionality to other objects by invoking delegates.
+ /// The default return value for the CanExecute method is 'true'.
+ ///
+ public class RelayCommand : ICommand
+ {
+ private readonly Action