Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 123 minIntermédiaire

Windows Forms en C# : c'est quoi, et créer ton premier projet

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • dire ce qu'est un client lourd et quand le choisir plutôt qu'une application web ;
  • choisir entre .NET 10 et .NET Framework 4.8, et entre WinForms, WPF et MAUI ;
  • créer une solution WinForms dans Visual Studio ou avec la commande dotnet ;
  • expliquer le rôle de Program.cs, du formulaire et de son fichier Designer.cs ;
  • lancer l'application et la déboguer avec des points d'arrêt.

4 exercices corrigés3 schémas

Windows Forms, ou WinForms, est la bibliothèque de .NET qui permet de construire en C# des applications de bureau pour Windows : des fenêtres que l'on dessine à la souris dans Visual Studio, puis dont on programme les réactions. Ce chapitre situe WinForms parmi les autres façons de faire une application, explique quelle version de .NET viser en 2026, présente le projet fil rouge et te fait créer la solution qui servira dans tout le cours.

Client lourd, client léger : où s'exécute ton code ?

Une application WinForms s'installe sur le poste de l'utilisateur et s'y exécute : on parle de client lourd (ou application de bureau, desktop). Une application web, au contraire, s'exécute dans un navigateur qui charge ses pages depuis un serveur : c'est un client léger, il n'y a rien à installer.

Client lourd (WinForms, WPF)Client léger (application web)Application mobile
Où tourne l'interfaceSur le poste, dans un .exeDans le navigateurSur le téléphone
InstallationSur chaque poste, mises à jour à déployerAucune, la mise à jour est sur le serveurPar un magasin d'applications
Accès aux ressources du posteComplet : fichiers, imprimantes, lecteur de cartes, ports sérieLimité par le navigateurLimité par le système du téléphone
Réactivité, travail hors ligneExcellente, possible hors ligneDépend du réseauBonne, hors ligne possible
Où vont les donnéesBase distante (directement ou via une API), parfois fichier localServeurAPI distante

Les clients lourds restent très présents en entreprise : logiciels de caisse, gestion de production, logiciels métier des cabinets médicaux, outils internes du service informatique. Ce sont des applications utilisées toute la journée par les mêmes personnes, sur des postes Windows maîtrisés, souvent reliées à du matériel.

Une application de bureau peut parler à sa base de données de deux façons. Soit elle s'y connecte directement (le cas le plus fréquent dans les projets de BTS, et celui des chapitres 9 et 10), soit elle passe par une API hébergée sur un serveur, qui seule accède à la base (chapitre 11). La seconde architecture est plus sûre, tu verras pourquoi au chapitre 12.

Client lourd directApplication webClient lourd et APIPoste WindowsGSB Ordonnances (.exe)SQL, avec la chaînede connexionServeur MySQLbase gsb_ordonnancesLe poste détient le motde passe de la baseNavigateuraffiche des pagesHTTPSServeur webexécute le codeSQLServeur MySQLmême réseau que le serveurRien à installer surle postePoste WindowsGSB Ordonnances (.exe)HTTPS, JSONjeton personnelServeur d'APIAPI RESTSQLServeur MySQLinvisible depuis le posteSeule l'API connaîtla base
Trois façons de relier une interface à la base de données

Au BTS SIO, le référentiel décrit l'environnement technologique dans lequel tes réalisations d'E6 sont construites : elles doivent couvrir au moins trois des quatre situations « poste fixe (client lourd), navigateur, terminal mobile, serveur », et comporter des appels à des services applicatifs distants (détail des exigences). Un client lourd C# en est l'exemple le plus classique.

WinForms, WPF, MAUI ou Avalonia ?

Microsoft propose plusieurs bibliothèques d'interface pour .NET. Toutes s'écrivent en C# ; elles diffèrent par la façon de décrire les fenêtres et par les systèmes visés.

BibliothèqueSystèmesDescription de l'interfaceQuand la choisir
Windows Forms (2002)WindowsConcepteur visuel, code C# généréApplications de gestion, outils internes, apprentissage : c'est la plus simple
WPF (2006)WindowsXAML, liaison de données très richeInterfaces graphiques soignées, gros logiciels Windows
.NET MAUI (2022)Windows, macOS, Android, iOSXAMLUne même application pour le bureau et le mobile
Avalonia (projet libre)Windows, macOS, Linux, mobile, navigateurXAML proche de WPFUne application de bureau multiplateforme

WinForms n'est pas une technologie abandonnée : elle fait partie de .NET 10, Microsoft continue de la faire évoluer (mode sombre, fenêtres asynchrones, nouveau presse-papiers en .NET 10), et des milliers d'entreprises l'utilisent. Elle reste la meilleure porte d'entrée pour comprendre la programmation événementielle : ce que tu apprends ici (événements, contrôles, liaison de données, couches) se retrouve presque tel quel en WPF ou en MAUI.

.NET 10 ou .NET Framework 4.8 ?

C'est la première source de confusion. Il existe deux plateformes .NET, qui n'ont pas la même histoire.

  • .NET Framework (2002 à 2019) est l'ancienne plateforme, livrée avec Windows. Sa dernière version est la 4.8.1 : elle ne recevra plus de nouvelles fonctionnalités, seulement des correctifs de sécurité, aussi longtemps que la version de Windows qui l'embarque est maintenue.
  • .NET (appelé .NET Core jusqu'à la version 3.1, puis simplement .NET 5, 6, 7…) est la plateforme actuelle, libre et multiplateforme. Une nouvelle version sort chaque mois de novembre. WinForms y est disponible depuis 2019.

Les versions paires sont à support long (LTS, trois ans), les impaires à support standard (STS, deux ans). Au 2 novembre 2026, la situation est la suivante :

VersionTypeSortieFin du support
.NET 8LTSnovembre 202310 novembre 2026
.NET 9STSnovembre 202410 novembre 2026
.NET 10LTSnovembre 202514 novembre 2028
.NET 11STSattendue en novembre 2026deux ans après sa sortie

Pour un nouveau projet, vise .NET 10. C'est la version LTS en cours, celle que propose Visual Studio 2026, et elle sera maintenue pendant toute ta formation. Un projet en .NET 8 doit être migré tout de suite : en général, il suffit de changer net8.0-windows en net10.0-windows dans le fichier projet et de mettre à jour les paquets NuGet.

Tu rencontreras pourtant .NET Framework en stage ou en entreprise. Beaucoup d'applications métier écrites entre 2005 et 2020 tournent encore en .NET Framework 4.7 ou 4.8, parfois en VB.NET. Elles fonctionnent, sont maintenues, mais leur migration vers .NET coûte du temps : les bibliothèques tierces anciennes, les rapports Crystal Reports ou les composants COM ne suivent pas toujours. Savoir reconnaître ces projets fait partie du métier.

IndiceProjet .NET FrameworkProjet .NET 10
Modèle choisi dans Visual Studio« Application Windows Forms (.NET Framework) »« Application Windows Forms »
Fichier projet .csprojlong, liste chaque fichier .cs, <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>court, <TargetFramework>net10.0-windows</TargetFramework>
ConfigurationApp.config, ConfigurationManagerappsettings.json ou autre, au choix
Point d'entréeApplication.EnableVisualStyles()ApplicationConfiguration.Initialize()
Paquetspackages.config<PackageReference> dans le .csproj

Ce que .NET 10 et C# 14 changent dans ton code

Le langage est expliqué dans le cours Programmation orientée objet (les bases de C#). Voici seulement les nouveautés récentes que tu vas croiser dans le code de ce cours, et qui n'existaient pas en .NET Framework.

  • Les types référence nullables (C# 8, activés par défaut dans les nouveaux projets). string? signifie « peut être null », string signifie « jamais null ». Le compilateur t'avertit quand tu risques une NullReferenceException. Le prénom d'un patient est facultatif : string? Prenom.
  • Les using implicites : System, System.Linq, System.Windows.Forms et quelques autres sont importés d'office, d'où des fichiers plus courts.
  • Les espaces de noms de fichier : namespace Gsb.Ui; en haut du fichier remplace les accolades d'un bloc namespace.
  • Les enregistrements (record, C# 9) : une classe de données en une ligne, comparée par valeur. Idéal pour une ligne de résultat ou un objet reçu d'une API.
  • Les constructeurs principaux (C# 12) : public class PatientService(IPatientRepository depot) déclare le constructeur et son paramètre dans l'en-tête de la classe.
  • Les expressions de collection (C# 12) : List<Patient> liste = []; ou int[] notes = [12, 15];.
  • Les chaînes brutes (C# 11) : un texte entre """ peut s'étaler sur plusieurs lignes sans échappement, parfait pour une requête SQL.
  • Le mot-clé field (C# 14) : dans une propriété, il désigne le champ caché que le compilateur crée. Tu peux ajouter un contrôle à une propriété automatique sans déclarer de champ privé.
csharp
public class Patient
{
    public string Nom
    {
        get;
        set => field = string.IsNullOrWhiteSpace(value)
            ? throw new ArgumentException("Le nom est obligatoire.")
            : value.Trim();
    } = "";

    public string? Prenom { get; set; }
}

Le get; reste automatique ; le set vérifie la valeur avant de la ranger dans field. Le = "" initialise le champ : le compilateur sait ainsi que Nom n'est jamais null. Enfin, async et await (C# 5) existent depuis longtemps, mais toute la bibliothèque moderne en dépend : le chapitre 7 leur est consacré.

Le projet fil rouge : GSB Ordonnances

Le cas s'inspire du contexte fictif GSB (Galaxy Swiss Bourdin), bien connu des étudiants de BTS SIO, transposé chez un éditeur de logiciels médicaux : GSB fournit à ses cabinets médicaux clients une application de bureau, GSB Ordonnances. La secrétaire médicale y gère les patients ; le médecin y rédige les ordonnances, chacune composée de plusieurs lignes (un médicament, une posologie, une durée).

Les besoins, tels qu'un client les exprimerait :

  1. se connecter avec un identifiant et un mot de passe personnels ;
  2. consulter la liste des patients, la filtrer par nom, ajouter, modifier ou supprimer un patient ;
  3. créer une ordonnance pour un patient : choisir le médecin, ajouter des médicaments avec posologie et durée ;
  4. consulter les ordonnances récentes avec le nom du patient et du médecin ;
  5. rechercher un médicament dans le référentiel des médicaments de l'éditeur, exposé par une API web ;
  6. exporter la liste des patients pour un courrier.

Les données sont rangées dans une base MySQL, gsb_ordonnances. Le chapitre 9 donne son script complet.

medecinnumMedecinnomprenomnumeroRppsspecialiteordonnancenumOrdonnancedateEmission#numMedecin#numPatientpatientnumPatientnomprenomdateNaissancenumeroSecumedicamentcodeMedicamentnomdosagecontenir#numOrdonnance#codeMedicamentposologiedureeJoursutilisateurnumUtilisateurloginhashMotDePasseroletable à part : les comptes
La base gsb_ordonnances : six tables

Sous forme de schéma relationnel, comme dans les sujets (la clé primaire, soulignée dans un sujet, est ici en gras ; les clés étrangères sont précédées d'un #) :

medecin (numMedecin, nom, prenom, numeroRpps, specialite)

patient (numPatient, nom, prenom, dateNaissance, numeroSecu)

medicament (codeMedicament, nom, dosage)

ordonnance (numOrdonnance, dateEmission, #numMedecin, #numPatient)

contenir (#numOrdonnance, #codeMedicament, posologie, dureeJours)

utilisateur (numUtilisateur, login, hashMotDePasse, role)

Installer Visual Studio 2026

Visual Studio 2026 (version 18) est l'environnement de développement de Microsoft pour .NET 10. L'édition Community est gratuite pour les étudiants, les particuliers et les petites équipes.

  1. Télécharge le programme d'installation sur le site de Visual Studio et lance-le.
  2. Dans l'onglet Charges de travail, coche Développement .NET Desktop. Elle installe le SDK .NET, les modèles WinForms et WPF et le concepteur de formulaires.
  3. Si tu veux aussi faire du web ASP.NET ou des tests de navigateur plus tard, ajoute Développement web et ASP.NET ; ce n'est pas utile pour ce cours.
  4. Clique sur Installer. Compte plusieurs gigaoctets et un bon moment.

Vérifie ensuite le SDK dans un terminal (PowerShell ou l'invite de commandes) :

bash
dotnet --list-sdks

Tu dois voir une ligne qui commence par 10.0.. Si la commande est inconnue, le SDK n'est pas installé ou le terminal a été ouvert avant l'installation : ferme-le et rouvre-le.

Créer la solution pas à pas

Dans Visual Studio, une solution regroupe plusieurs projets. Une application bien construite en contient plusieurs : l'interface, la couche métier, l'accès aux données et les tests (le chapitre 8 explique pourquoi). Pour l'instant, crée la solution et son premier projet, l'interface.

  1. Fichier > Nouveau > Projet (ou, à l'accueil, Créer un projet).
  2. Dans la recherche, tape Windows Forms, choisis Application Windows Forms en C# (pas la version .NET Framework, pas Visual Basic), puis Suivant.
  3. Nom du projet : Gsb.Ui. Nom de la solution : GsbOrdonnances. Décoche « Placer la solution et le projet dans le même répertoire ». Suivant.
  4. Framework : .NET 10.0 (prise en charge à long terme). Créer.

Visual Studio ouvre le concepteur (designer) avec une fenêtre vide, Form1. Tu peux déjà lancer l'application avec F5 : une fenêtre grise apparaît. Ferme-la.

La même solution se crée en ligne de commande, ce qui est utile sur un poste sans Visual Studio ou pour un script :

bash
dotnet new sln -n GsbOrdonnances
dotnet new winforms -n Gsb.Ui -o Gsb.Ui
dotnet new classlib -n Gsb.Metier -o Gsb.Metier
dotnet new classlib -n Gsb.Donnees -o Gsb.Donnees
dotnet new mstest -n Gsb.Tests -o Gsb.Tests
dotnet sln add Gsb.Ui Gsb.Metier Gsb.Donnees Gsb.Tests

Depuis le SDK .NET 10, le fichier de solution créé est un GsbOrdonnances.slnx, un format XML plus court que l'ancien .sln. Visual Studio 2026 ouvre les deux.

Ce que contient le projet

Dans l'Explorateur de solutions, le projet Gsb.Ui contient quatre fichiers utiles.

text
GsbOrdonnances/
├── GsbOrdonnances.slnx
└── Gsb.Ui/
    ├── Gsb.Ui.csproj        le fichier projet : plateforme, options, paquets
    ├── Program.cs           le point d'entrée : ce qui s'exécute au lancement
    ├── Form1.cs             ton code : les réactions aux événements
    └── Form1.Designer.cs    le code écrit par le concepteur : les contrôles

Un fichier Form1.resx (images, textes traduits) apparaît sous Form1.cs dès que tu ajoutes une ressource au formulaire, une icône par exemple.

Le fichier projet. Il tient en quelques lignes :

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net10.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

</Project>
LigneSens
OutputType WinExeUn exécutable Windows sans fenêtre de console
TargetFramework net10.0-windows.NET 10, avec les bibliothèques propres à Windows
Nullable enableActive les avertissements sur les null
UseWindowsForms trueAjoute WinForms au projet
ImplicitUsings enableImporte d'office les espaces de noms courants

Les paquets NuGet ajoutés plus tard (MySqlConnector, BCrypt.Net-Next…) apparaîtront dans ce fichier sous forme de lignes <PackageReference>.

Program.cs. C'est la méthode Main, la première exécutée :

csharp
namespace Gsb.Ui;

static class Program
{
    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();
        Application.Run(new Form1());
    }
}
  • [STAThread] place le programme dans le mode de fonctionnement qu'exigent les composants Windows (presse-papiers, boîtes de dialogue de fichiers). Ne le retire jamais.
  • ApplicationConfiguration.Initialize() applique les réglages de l'application : styles visuels, police par défaut, gestion des écrans haute résolution.
  • Application.Run(new Form1()) crée la fenêtre principale, l'affiche et lance la boucle de messages : le programme attend désormais les actions de l'utilisateur (chapitre 3). Quand cette fenêtre se ferme, Run se termine et l'application aussi.

Form1.cs et Form1.Designer.cs. Un formulaire est une classe qui hérite de Form. Elle est écrite dans deux fichiers grâce au mot-clé partial : le concepteur écrit dans Form1.Designer.cs, toi dans Form1.cs. À la compilation, les deux morceaux ne forment qu'une seule classe.

Form1.Designer.csécrit par le concepteur de Visual Studiopartial class Form1InitializeComponent()crée et règle les contrôlesTextBox txtNom;Button btnEnregistrer;Form1.csécrit par toipartial class Form1 : Formpublic Form1()appelle InitializeComponent()btnEnregistrer_Click(…)réagit au cliccompilationclass Form1 : Formune seule classe dans Gsb.Ui.dll
Un formulaire, deux fichiers, une seule classe

Quand tu poses un bouton dans le concepteur, Visual Studio ajoute dans Form1.Designer.cs un champ private Button button1; et, dans la méthode InitializeComponent(), les lignes qui le créent et règlent sa position, son texte, sa taille. Le constructeur de Form1.cs appelle InitializeComponent() : c'est à ce moment que les contrôles existent.

csharp
namespace Gsb.Ui;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();   // crée les contrôles dessinés dans le concepteur
    }
}

Renommer le formulaire. Form1 ne dit rien. Dans l'Explorateur de solutions, fais un clic droit sur Form1.cs, Renommer, tape FrmPatients.cs et accepte quand Visual Studio propose de renommer aussi la classe et ses références. Renommer à la main dans le code seulement casse le lien avec Program.cs et le fichier .resx.

Compiler, lancer et déboguer

Compiler transforme ton code C# en un fichier Gsb.Ui.dll (le code intermédiaire, ou IL) accompagné d'un lanceur Gsb.Ui.exe, dans le dossier bin\Debug\net10.0-windows\. Au lancement, le runtime .NET compile ce code intermédiaire en instructions du processeur, au fur et à mesure.

RaccourciAction
Ctrl + Maj + BGénérer la solution (compiler sans lancer)
F5Lancer avec le débogueur
Ctrl + F5Lancer sans le débogueur (plus rapide)
F9Poser ou retirer un point d'arrêt sur la ligne
F10Pas à pas principal : exécuter la ligne sans entrer dans les méthodes appelées
F11Pas à pas détaillé : entrer dans la méthode appelée
Maj + F5Arrêter le débogage
Ctrl + .Actions rapides : ajouter un using, corriger, générer une méthode

Le débogueur est ton meilleur allié. Pose un point d'arrêt (pastille rouge) sur une ligne, lance avec F5 et déclenche l'action : l'exécution s'arrête avant cette ligne. Survole une variable pour voir sa valeur, ou ouvre les fenêtres Variables locales et Espion. Avance ligne à ligne avec F10. Quand une exception n'est pas interceptée, Visual Studio s'arrête sur la ligne fautive et affiche le type de l'exception et son message : lis-les avant de modifier quoi que ce soit. Le cours Maintenance applicative détaille la lecture d'une pile d'appels.

Exercices

Exercice 1 sur 4 Client lourd ou pas ? Réussi À revoir

Pour chaque application, dis où s'exécute l'interface (poste, navigateur, mobile) et si c'est un client lourd.

  1. Le logiciel de caisse d'une boulangerie, installé sur le terminal du comptoir, relié au tiroir-caisse.
  2. GLPI, consulté par les techniciens dans Firefox.
  3. Microsoft Teams installé sur un PC.
  4. Une application React qui appelle une API Node.js.
  5. GSB Ordonnances.
Voir la réponseMasquer la réponse de l'exercice 1
  1. Client lourd : un exécutable installé sur le poste, qui pilote du matériel local.
  2. Client léger : l'interface est une page web, le code PHP s'exécute sur le serveur.
  3. Client lourd installé, même si son interface est construite avec des technologies web : il s'installe et s'exécute sur le poste. La frontière n'est pas toujours nette.
  4. Client léger : le code React s'exécute dans le navigateur, l'API sur le serveur. Ce sont deux des quatre situations de l'annexe de l'E6 (navigateur et serveur).
  5. Client lourd : un exécutable WinForms installé sur les postes du cabinet.

Tu avais trouvé ?

Exercice 2 sur 4 Lire un fichier projet Réussi À revoir

Un camarade t'envoie ce fichier projet.

xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>disable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
</Project>
  1. Quelle version de .NET vise-t-il, et pourquoi faut-il la changer en novembre 2026 ?
  2. Que perd-il avec Nullable à disable ?
  3. Sans ImplicitUsings, qu'est-ce qui change dans ses fichiers .cs ?
Voir la réponseMasquer la réponse de l'exercice 2
  1. .NET 8, dont le support se termine le 10 novembre 2026 : après cette date, plus aucun correctif de sécurité. Il faut écrire net10.0-windows et mettre à jour les paquets.
  2. Les avertissements du compilateur sur les null : il ne signalera plus une variable qui peut valoir null avant d'être utilisée. Les NullReferenceException ne seront découvertes qu'à l'exécution.
  3. Chaque fichier doit importer lui-même System, System.Linq, System.Windows.Forms, etc. avec des lignes using. Le code fonctionne pareil ; il est juste plus long.

Tu avais trouvé ?

Exercice 3 sur 4 Où va ce code ? Réussi À revoir

Pour chaque élément, indique le fichier : Program.cs, FrmPatients.cs ou FrmPatients.Designer.cs.

  1. La couleur de fond d'un bouton choisie dans la fenêtre Propriétés.
  2. Le code exécuté quand on clique sur « Enregistrer ».
  3. Le choix de la fenêtre affichée au lancement.
  4. La déclaration du champ txtNom.
  5. L'appel à InitializeComponent().
Voir la réponseMasquer la réponse de l'exercice 3
  1. FrmPatients.Designer.cs, dans InitializeComponent() : tout réglage fait dans le concepteur y est écrit.
  2. FrmPatients.cs, dans le gestionnaire btnEnregistrer_Click.
  3. Program.cs, dans Application.Run(new FrmPatients()).
  4. FrmPatients.Designer.cs : le concepteur déclare un champ par contrôle posé.
  5. FrmPatients.cs, dans le constructeur.

Tu avais trouvé ?

Exercice 4 sur 4 Le bon modèle Réussi À revoir

En stage, on te demande de corriger un bug dans un logiciel interne. Le fichier projet contient <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> et la solution a un fichier packages.config. Ton tuteur te propose aussi de démarrer un nouvel outil de suivi des prêts de matériel.

  1. Sur quelle plateforme est le logiciel existant ?
  2. Dois-tu le migrer avant de corriger le bug ?
  3. Quel modèle choisis-tu pour le nouvel outil ?
Voir la réponseMasquer la réponse de l'exercice 4
  1. .NET Framework 4.7.2 : l'ancienne plateforme (format de projet ancien, packages.config).
  2. Non. Une correction de bug doit rester petite et sans risque de régression : on corrige dans la plateforme existante. La migration est un projet à part, à proposer et à planifier avec ton tuteur.
  3. « Application Windows Forms » (sans la mention .NET Framework), avec .NET 10.

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Les contrôles WinForms : TextBox, ComboBox, DataGridViewRevoir le sommaire du cours