Aller au contenu
Réussir mon BTS SIO

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

Par exemple

Chapitre 214 minIntermédiaire

Les contrôles WinForms : TextBox, ComboBox, DataGridView

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

À la fin de ce chapitre, tu sauras

  • nommer et régler les contrôles avec une convention claire ;
  • remplir une ComboBox à partir d'une liste d'objets et lire la valeur choisie ;
  • choisir le bon contrôle pour chaque donnée à saisir ;
  • construire une fenêtre qui reste lisible quand on l'agrandit.

4 exercices corrigés

Un contrôle est un élément visuel posé sur un formulaire : une étiquette, une zone de texte, un bouton, une liste déroulante, un tableau. Chaque contrôle est un objet C# dont les propriétés règlent l'apparence et le comportement, et dont les événements signalent les actions de l'utilisateur. Ce chapitre présente les contrôles qu'on retrouve dans toutes les applications de gestion, avec les propriétés qui comptent et les pièges de chacun.

Poser un contrôle et régler ses propriétés

La Boîte à outils (Ctrl + Alt + X) liste les contrôles. Fais-en glisser un sur le formulaire, puis règle-le dans la fenêtre Propriétés (F4). Les propriétés communes à presque tous les contrôles :

PropriétéRôleExemple
(Name)Le nom du champ dans le codetxtNom
TextLe texte affichéEnregistrer
EnabledUtilisable ou griséfalse pendant un chargement
VisibleAffiché ou cachéfalse pour un bouton réservé à l'administrateur
TabIndexL'ordre de passage avec la touche Tab0, 1, 2… de haut en bas
Anchor, DockLe comportement quand la fenêtre change de taillevoir plus bas
Font, ForeColor, BackColorPolice et couleursà éviter sauf besoin réel

Tout ce qui se règle dans la fenêtre Propriétés se règle aussi par le code, et inversement : btnEnregistrer.Enabled = false; a le même effet que de mettre Enabled à False dans la fenêtre, mais à l'exécution.

Nommer les contrôles

Le concepteur nomme les contrôles textBox1, textBox2, button1. Trois semaines plus tard, plus personne ne sait lequel contient le nom du patient. Renomme chaque contrôle dès que tu le poses, avant d'écrire le moindre gestionnaire : renommer après coup laisse des gestionnaires au nom périmé (button1_Click).

La convention la plus répandue préfixe le nom par trois lettres qui disent le type de contrôle :

ContrôlePréfixeExemple
LabellbllblStatut
TextBoxtxttxtNom
ButtonbtnbtnEnregistrer
ComboBoxcbocboMedecin
ListBoxlstlstMedicaments
CheckBoxchkchkSurOrdonnance
RadioButtonrdordoHomme
DateTimePickerdtpdtpNaissance
NumericUpDownnudnudDuree
DataGridViewdgvdgvPatients
GroupBox, Panelgrp, pnlgrpIdentite
FormulaireFrmFrmPatients

Une autre convention, recommandée par certaines équipes, met le type à la fin (nomTextBox, enregistrerButton). Peu importe laquelle, pourvu qu'elle soit la même dans tout le projet : la commission d'E6 lira ton code.

Afficher et saisir du texte : Label et TextBox

Le Label affiche un texte que l'utilisateur ne modifie pas : un libellé de champ, un message de statut. Mets AutoSize à true pour qu'il prenne la taille de son texte.

La TextBox est la zone de saisie. Sa propriété Text contient toujours du texte, même quand l'utilisateur tape un nombre : il faudra le convertir (chapitre 5).

PropriétéUsage
MaxLengthLongueur maximale, à aligner sur la colonne SQL (VARCHAR(50) → 50)
PlaceholderTextTexte grisé affiché quand la zone est vide : « Rechercher un nom »
Multiline, ScrollBarsPlusieurs lignes : une observation, une adresse
ReadOnlyAffiché, sélectionnable, mais non modifiable
UseSystemPasswordCharMasque la saisie par des points : mot de passe
CharacterCasingForce les majuscules ou les minuscules
csharp
txtNom.MaxLength = 50;
txtSecu.MaxLength = 13;
txtMotDePasse.UseSystemPasswordChar = true;
string nom = txtNom.Text.Trim();   // Trim retire les espaces au début et à la fin

Déclencher une action : Button

Le Button déclenche une action par son événement Click. Deux réglages du formulaire rendent la saisie bien plus agréable :

  • AcceptButton du formulaire désigne le bouton activé par la touche Entrée (Enregistrer, Se connecter) ;
  • CancelButton désigne le bouton activé par Échap (Annuler, Fermer).

Une esperluette dans le texte crée un raccourci clavier : &Enregistrer affiche « Enregistrer » avec le E souligné, et Alt + E clique sur le bouton.

Choisir dans une liste : ComboBox et ListBox

La ComboBox est une liste déroulante. Avec DropDownStyle = DropDownList, l'utilisateur ne peut que choisir une valeur proposée : c'est ce qu'il faut pour choisir le médecin d'une ordonnance. Avec le style DropDown par défaut, il peut aussi taper n'importe quoi, ce qui est rarement souhaité.

Le plus souvent, on remplit la liste avec des objets et non des chaînes. Trois propriétés font le lien :

  • DataSource : la liste d'objets ;
  • DisplayMember : le nom de la propriété affichée ;
  • ValueMember : le nom de la propriété renvoyée par SelectedValue, en général l'identifiant.
csharp
List<Medecin> medecins = await _medecinService.ListerAsync();

cboMedecin.DropDownStyle = ComboBoxStyle.DropDownList;
cboMedecin.DisplayMember = nameof(Medecin.NomComplet);   // « Dr Paul Martin »
cboMedecin.ValueMember = nameof(Medecin.NumMedecin);     // 1
cboMedecin.DataSource = medecins;

Pour lire le choix, SelectedValue renvoie l'identifiant et SelectedItem l'objet entier :

csharp
if (cboMedecin.SelectedValue is int numMedecin)
{
    ordonnance.NumMedecin = numMedecin;
}

Medecin? medecin = cboMedecin.SelectedItem as Medecin;

nameof(Medecin.NomComplet) produit la chaîne "NomComplet", mais vérifiée par le compilateur : si tu renommes la propriété, le code ne compile plus au lieu d'afficher une liste vide.

La ListBox affiche plusieurs éléments à la fois et peut autoriser la sélection multiple (SelectionMode = MultiExtended), lue par SelectedItems. Elle convient pour une liste courte : les médicaments d'une ordonnance, par exemple.

Cases à cocher et boutons radio

La CheckBox répond à une question oui ou non : sa propriété Checked est un bool. Les RadioButton proposent un choix exclusif : dans un même conteneur, cocher l'un décoche les autres. Pour avoir deux groupes indépendants sur un formulaire, place chaque groupe dans son propre GroupBox ou Panel.

csharp
bool surOrdonnance = chkSurOrdonnance.Checked;
string sexe = rdoFemme.Checked ? "F" : "M";

Saisir une date ou un nombre sans conversion

Plutôt que de faire taper une date dans une TextBox puis de la convertir, utilise un DateTimePicker. Sa propriété Value est un DateTime toujours valide. Règle Format = Short pour afficher 12/05/1990, et MaxDate = DateTime.Today pour interdire une naissance future.

Une date facultative (la date de naissance peut être inconnue) se gère avec ShowCheckBox = true : une case apparaît dans le contrôle, et Checked dit si une date a été choisie.

csharp
dtpNaissance.Format = DateTimePickerFormat.Short;
dtpNaissance.MaxDate = DateTime.Today;
dtpNaissance.ShowCheckBox = true;

DateTime? naissance = dtpNaissance.Checked ? dtpNaissance.Value.Date : null;

Le NumericUpDown fait de même pour les nombres : Minimum, Maximum, DecimalPlaces et Increment bornent la saisie, et Value est un decimal toujours compris entre les bornes. La durée d'un traitement, de 1 à 90 jours, s'y prête parfaitement.

csharp
nudDuree.Minimum = 1;
nudDuree.Maximum = Ordonnance.DureeMaxJours;   // 90
int duree = (int)nudDuree.Value;

Afficher un tableau : DataGridView

Le DataGridView affiche des données en lignes et en colonnes. C'est le contrôle central d'une application de gestion : la liste des patients, des ordonnances, des médicaments. Sa liaison aux données fait l'objet du chapitre 6 ; voici les réglages à faire dès qu'on le pose.

PropriétéValeur conseilléePourquoi
ReadOnlytrueOn modifie dans un formulaire dédié, pas dans la grille
AllowUserToAddRowsfalseSinon une ligne vide « nouvelle ligne » apparaît en bas
AllowUserToDeleteRowsfalseLa suppression passe par un bouton et une confirmation
SelectionModeFullRowSelectUn clic sélectionne la ligne entière
MultiSelectfalseUne seule ligne à la fois
AutoSizeColumnsModeFillLes colonnes occupent toute la largeur
RowHeadersVisiblefalseRetire la colonne grise de gauche
  • MenuStrip : la barre de menus (Fichier, Patients, Ordonnances, Aide). Chaque élément est un ToolStripMenuItem avec un événement Click et une propriété ShortcutKeys (Ctrl + N pour Nouveau).
  • ToolStrip : la barre de boutons sous le menu.
  • StatusStrip : la barre d'état en bas de la fenêtre, avec un ToolStripStatusLabel pour afficher « 3 patients » ou « Connecté : secretariat ».
  • TabControl : des onglets, pour séparer l'identité d'un patient de ses ordonnances sans ouvrir une autre fenêtre.

Disposer les contrôles : Anchor, Dock et les conteneurs

Par défaut, un contrôle reste collé à son point en haut à gauche : quand l'utilisateur agrandit la fenêtre, la grille ne grandit pas et les boutons restent au milieu. Deux propriétés règlent ce comportement.

  • Anchor accroche le contrôle à un ou plusieurs bords. Une grille ancrée Top, Bottom, Left, Right s'étire dans les deux sens ; un bouton ancré Bottom, Right reste dans le coin en bas à droite.
  • Dock colle le contrôle contre un bord et lui fait occuper toute la largeur ou la hauteur : Top pour une barre de recherche, Fill pour la grille qui prend le reste.

Pour des formulaires de saisie bien alignés, utilise un TableLayoutPanel : une grille invisible, avec une colonne pour les libellés et une pour les champs. Un FlowLayoutPanel aligne des boutons les uns à la suite des autres. Ces conteneurs gèrent aussi les différences de police et de résolution, là où des positions fixées au pixel se décalent.

Le mode sombre

Depuis .NET 10, le mode sombre de WinForms n'est plus expérimental. Une ligne dans Program.cs, avant de créer la première fenêtre, fait suivre à l'application le réglage clair ou sombre de Windows :

csharp
ApplicationConfiguration.Initialize();
Application.SetColorMode(SystemColorMode.System);   // ou Dark, ou Classic

Les couleurs fixées à la main (BackColor = Color.White) ne suivent pas : c'est une raison de plus pour laisser les couleurs par défaut.

Un formulaire accessible

Une application de gestion est utilisée au clavier toute la journée. Vérifie que la touche Tab parcourt les champs dans l'ordre de lecture (menu Affichage > Ordre de tabulation dans le concepteur), que les boutons principaux ont un raccourci Alt, et que AcceptButton et CancelButton sont réglés. Pour un lecteur d'écran, renseigne AccessibleName sur les contrôles sans libellé visible, comme un bouton qui n'affiche qu'une icône.

Exercices

Exercice 1 sur 4 Concevoir le formulaire patient Réussi À revoir

Le formulaire d'édition d'un patient doit permettre de saisir le nom (obligatoire, 50 caractères au plus), le prénom (facultatif), la date de naissance (facultative, jamais dans le futur) et le numéro de sécurité sociale (13 chiffres, facultatif), puis d'enregistrer ou d'annuler. Pour chaque élément, donne le type de contrôle, son nom et les propriétés à régler.

Voir la réponseMasquer la réponse de l'exercice 1
ÉlémentContrôleNomPropriétés
NomTextBoxtxtNomMaxLength 50, TabIndex 0
PrénomTextBoxtxtPrenomMaxLength 50, TabIndex 1
NaissanceDateTimePickerdtpNaissanceFormat Short, ShowCheckBox true, MaxDate = aujourd'hui (par le code, au chargement)
N° de sécurité socialeTextBoxtxtSecuMaxLength 13
EnregistrerButtonbtnEnregistrerText &Enregistrer, désigné comme AcceptButton du formulaire
AnnulerButtonbtnAnnulerDialogResult Cancel, désigné comme CancelButton

Plus un Label devant chaque champ (« Nom * », « Prénom »…), le tout dans un TableLayoutPanel à deux colonnes. MaxDate se règle dans le code, car « aujourd'hui » change chaque jour.

Tu avais trouvé ?

Exercice 2 sur 4 La liste des médecins Réussi À revoir

medecins est une List<Medecin>, la classe Medecin a les propriétés NumMedecin (int) et NomComplet (string). Écris le code qui remplit cboMedecin pour qu'on ne puisse que choisir un médecin, puis le code qui affiche dans lblChoix le numéro du médecin choisi.

Voir la réponseMasquer la réponse de l'exercice 2
csharp
cboMedecin.DropDownStyle = ComboBoxStyle.DropDownList;
cboMedecin.DisplayMember = nameof(Medecin.NomComplet);
cboMedecin.ValueMember = nameof(Medecin.NumMedecin);
cboMedecin.DataSource = medecins;

// plus tard, par exemple dans le Click d'un bouton
if (cboMedecin.SelectedValue is int numMedecin)
{
    lblChoix.Text = $"Médecin n° {numMedecin}";
}

Le test is int numMedecin protège du cas où aucun médecin n'est sélectionné (liste vide) : SelectedValue vaut alors null.

Tu avais trouvé ?

Exercice 3 sur 4 Le bon contrôle Réussi À revoir

Choisis le contrôle le plus adapté à chaque saisie, et dis pourquoi.

  1. La spécialité d'un médecin, parmi une liste fixe de 12 spécialités.
  2. Le nombre de boîtes à délivrer, de 1 à 6.
  3. Une observation médicale de plusieurs lignes.
  4. Le choix « médicament remboursé » oui ou non.
  5. La date d'une ordonnance.
Voir la réponseMasquer la réponse de l'exercice 3
  1. ComboBox en DropDownList : l'utilisateur ne peut pas inventer une spécialité.
  2. NumericUpDown avec Minimum 1 et Maximum 6 : aucune conversion, aucune valeur hors limites.
  3. TextBox avec Multiline à true et une barre de défilement verticale.
  4. CheckBox : un bool.
  5. DateTimePicker : la valeur est toujours une date valide.

Tu avais trouvé ?

Exercice 4 sur 4 La fenêtre qui ne s'agrandit pas bien Réussi À revoir

La fenêtre FrmPatients contient en haut une zone de recherche, au milieu une grille, en bas à gauche trois boutons (Nouveau, Modifier, Supprimer) et en bas à droite un bouton Actualiser. Quand on l'agrandit, la grille garde sa taille et les boutons restent au milieu. Donne la valeur d'Anchor de chaque contrôle.

Voir la réponseMasquer la réponse de l'exercice 4
  • Zone de recherche : Top, Left (ou Top, Left, Right si elle doit s'élargir).
  • Grille : Top, Bottom, Left, Right : elle s'étire dans les deux sens.
  • Nouveau, Modifier, Supprimer : Bottom, Left : ils suivent le bas de la fenêtre.
  • Actualiser : Bottom, Right : il reste dans le coin.

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 événements en C# WinForms : Click, TextChanged, LoadRevoir le sommaire du cours