Une remarque pertinente ?
Une critique impertinente ?
Un lynchage en règle ?
Une invitation sous les tropiques ?

Ecrivez-moi !
Conçu et enseigné tel qu'en lui même, avec pertes, fracas et humour de qualité supérieure            
 par Christophe Darmangeat dans le M2 PISE du Master MECI (Université Paris 7)            

 
 
 
  
 
 
 
Partie 10
Toujours des contrôles
 
Continuons à fouiller la boîte à outils. Nous sommes encore loin d'avoir fait le tour de tous les couteaux à huit lames, des équerres courbes, des tire-bouchons à ressort et autres limes à épaissir proposées par VB. Voilà donc un chapitre bric-à-brac, dans lequel on va découvrir quelques ustensiles dont l'utilisation posera rarement de gros problèmes, et qui pourront très agréablement enrichir notre interface.

1. La classe TabControl
Il s'agit d'un contrôle qui va nous permettre de doter notre formulaire d'onglets, ce qui est bien connu pour améliorer tout autant l'ergonomie que le pot-au-feu.
Lorsqu'on le pose sur la Form, le TabControl prend l'aspect d'un rectangle qui délimite la partie de cette Form qui fonctionnera avec le système des onglets. Il est donc possible de laisser une zone (contenant des contrôles) qui sera visible quel que soit l'onglet sélectionné :
Pour ajouter des onglets en mode design, on peut passer soit par la propriété Tabpages, soit par Ajouter un onglet. Plusieurs propriétés, sur lesquelles je ne m'étendrai pas, règlent l'apparence de ces onglets. Au total, chaque onglet est représenté par un objet Tabpage et le nombre d'onglets est donné par la propriété TabCount. Le texte affiché sur chaque onglet est donné par sa propriété Text, avec la possibilité éventuelle de lui associer une image via un contrôle ImageList.
L'événement majeur pour un contrôle TabControl est SelectedIndexChanged qui indique bien évidemment que l'utilisateur a changé d'onglet. L'onglet actif est donné par la propriété SelectedIndex.
Bref, vraiment rien de méchant, et c'est encore un beau joujou supplémentaire.
2. Les classes HScrollBar, VScrollBar et TrackBar
Ces trois classes permettent à l'utilisateur de déterminer une valeur en maniant un curseur, qu'il s'agisse d'une barre de défilement horizontale (HScrollBar), verticale (VScrollBar), ou de cette barre de réglage un peu particulière (Trackbar) :
De ces contrôles très faciles à manipuler, il y a bien peu à dire  :
  • deux propriétés, Minimum et Maximum, déterminent la valeur associée à chaque extrémité.
  • deux autres, SmallChange et LargeChange, règlent la valeur de l'incrément lorsqu'on déplace le curseur (selon qu'on clique sur la flèche qui se trouve au bout de la barre ou dans la barre elle-même)
  • une propriété, Value, correspond à la valeur associée à la position actuelle du curseur.
A noter qu'il est possible d'afficher verticalement un contrôle Trackbar, en changeant sa propriété Orientation. Celui-ci possède de surcroît une propriété TickStyle, qui permet de modifier la trombine des graduations, et TickFrequency, qui règle leur intervalle.
L'événement privilégié associé à ces trois contrôles est le ValueChanged.
Et une fois qu'on a dit cela, on a fait le tour de la question.
3. La classe ProgressBar
Il s'agit de cette jolie chose censée faire patienter l'utilisateur - voire lui indiquer grosso modo où on en est - pendant une opération un peu trop longuette :
Là, c'est encore plus simple que précédemment, puisque l'utilisateur ne peut absolument pas agir sur ce contrôle. On retrouve donc les propriétés Minimum, Maximum et Value, mais guère plus, et pas d'événement particulier.
Circulez, y a rien, ou pas grand chose, à voir.
4. Les classes ToolTip et HelpProvider
Ces deux classes sont là pour donner une aide plus ou moins détaillée à l'utilisateur. Le ToolTip, c'est ce petit rectangle beige qui apparaît lorsqu'on stationne la souris pendant un certain temps au-dessus d'un contrôle :
En fait, il ne faut créer qu'un seul contrôle ToolTip par Form ; cet unique contrôle pourra servir ensuite pour l'ensemble des contrôles de cette Form. Les propriétés principales du contrôle tournent autour de la question du Delay : le temps au bout duquel le rectangle apparaît, le temps durant lequel il reste affiché, etc. Je ne détaille pas , parce que franchement, ça ne pose aucune difficulté. La seule astuce à connaître est le code qui permet d'associer un message à un contrôle donné. Il faudra pour cela écrire...
NomDuToolTip.SetToolTip(NomDuContrôle, Message)
Cette ligne devra naturellement être exécutée de préférence avant qu'il se passe quoi que ce soit d'autre, donc dans la procédure associée à l'événement Form.Load.
Quant au Helpprovider, que je ne cite ici que par acquit de conscience, il sert à "brancher" l'appui de la touche F1 d'un contrôle directement sur un fichier d'aide (*.chm ou *.htm), à la bonne page.
5. Les classes DomainUpDown et NumericUpDown
Ces deux contrôles ont un comportement très voisin de celui d'une liste qui aurait un look un peu particulier. Le premier, DomainUpDown, oblige l'utilisateur à choisir parmi une collection de Strings, et le second, NumericUpDown, parmi une série de nombres (simplement définis par un minimum et un maximum) :
Les propriétés et les méthodes de ces deux contrôles sont très voisines de celles des listes, pour ne pas dire qu'elles leur ressemblent comme deux couteaux (comme on dit en Alsace).
6. Les classes DateTimePicker et MonthCalendar
Il s'agit de deux contrôles spécialisés dans la saisie d'une date. Le premier des deux, DateTimePicker, est le plus polyvalent. Il se présente comme une liste déroulante déployant un calendrier :
 
Ce contrôle peut largement être paramétré :
  • fixation d'une date minimum et/ou maximum par les propriétés MinDate et MaxDate
  • empêchement de l'affichage du calendrier par ShowUpDown
  • changement de la valeur par défaut de la date, par DateTime
  • modification du format d'affichage de la date, par Format
  • modification de l'apparence du calendrier, par les six propriétés Calendar...
La date saisie est quant à elle stockée dans la propriété Value. Et le principal événement lié à ce contrôle est ValueChanged, provoqué par un changement de la valeur de la date.
Quant à MonthCalendar, c'est un DateTimePicker sans la zone de saisie, autrement dit un simple calendrier. L'avantage est que l'utilisateur pourra y sélectionner plusieurs dates (ce qui modifiera la valeur des propriétés SelectionStart, SelectionEnd et SelectionRange).
Bon, allez, on passe.
7. La classe Timer
Avec ce petit contrôle, on découvre un outil un peu déroutant au début, mais qui se révèle indispensable dans certaines situations :
En effet, jusque là, tous les événements que nous avons gérés étaient, d'une manière directe ou indirecte, provoqués par une action de l'utilisateur : un clic, une frappe au clavier, etc. Même lorsque l'événement était causé par l'exécution d'une ligne de code, celle-ci se trouvait dans une procédure elle-même déclenchée par une action de l'utilisateur (ou alors elle se trouvait dans une procédure elle-même appelée par une action de l'utilisateur, mais quelle que soit la longueur de la chaîne des causalités, au bout du bout du bout, il y avait un geste de l'utilisateur).
Or, dans certains cas, on peut souhaiter que certains événements se déclenchent (que certaines lignes de code soient exécutées) indépendamment de toute action de l'utilisateur.
Par exemple, imaginons que nous programmions un QCM en temps limité. Nous souhaitons que l'application se termine automatiquement au bout d'un délai donné, par exemple 30 minutes. Il va donc falloir, chaque minute, ou toutes les dix secondes, ou toutes les secondes, vérifier le temps écoulé depuis le début et en cas de besoin, prendre les mesures qui s'imposent en coupant le sifflet de l'utilisateur. Eh bien, c'est très exactement à cela que sert le Timer.
Il s'agit d'un contrôle capable de générer un événement à intervalle régulier, événement qui sera donc totalement indépendant de ce que fait, ou ne fait pas, l'utilisateur.
Ce contrôle est par définition invisible. A l'instar du ToolTipText ou de l"ImageList, Il ne se "pose" pas sur la Form, mais à côté.
La propriété Interval est celle qui règle l'intervalle de temps entre chaque événement généré par le Timer. Elle est exprimée en millisecondes. Et cet événement est tout simplement le Tick.
Bon, assez bavardé, amusons-nous un peu :
 
Exercice
Exécutable
Sources
Final Countdown

8. Les classes de boîtes de dialogue communes
Vous aurez sans doute remarqué que sous Windows, quel que soit le logiciel utilisé, ou presque, certaines commandes possèdent des airs de famille. Par exemple, lorsque vous faites Fichier - Ouvrir, Fichier - Enregistrer, Fichier - Imprimer, et quelques autres encore, non seulement les fonctionnalités proposées sont les mêmes, mais encore la présentation de la boîte de dialogue est rigoureusement identique d'une application à l'autre, au poil de nez près.
Cela ne peut signifier que deux choses. Soit les développeurs des différents logiciels prennent un soin maniaque à recopier leurs interfaces pour obtenir des copies conformes. Soit tous ces braves gens n'écrivent en fait rien du tout, et vont puiser du code, toujours le même, déjà programmé au sein de Windows. Eh bien devinez quoi ? C'est la deuxième proposition qui est la bonne.
De sorte que vous me voyez venir avec mes gros sabots : lorsque nous devrons insérer une de ces "boîtes de dialogues communes" dans notre application, nul besoin de la programmer nous-mêmes : Windows, via Visual Studio, nous offre la possibilité d'utiliser directement son code, au travers d'une série de classes. Les voici  :
  • OpenFileDialog : correspond à la boîte de dialogue Fichier - Ouvrir
  • SaveFileDialog : correspond aux boîtes de dialogue Fichier - Enregistrer et Fichier - Enregistrer Sous
  • FolderBrowserDialog : correspond à un explorateur de répertoires (qui repère automatiquement la structure des répertoires de la machine sur laquelle tourne l'application)
  • FontDialog : correspond à la boîte de dialogue Police
  • ColorDialog : correspond à une boîte de dialogue donnant accès aux couleurs personnalisées
  • PrintDialog : correspond à la boîte de dialogue Fichier - Imprimer
  • PrintPreviewDialog : correspond à la boîte de dialogue Fichier - Aperçu avant impression
  • PrintPreviewControl : zone permettant d'afficher un Aperçu avant impression
  • PrintDocument : correspond à la boîte de dialogue Fichier - Imprimer
  • PageSetupDialog : correspond à la boîte de dialogue Fichier - Mise en page
Tous ces contrôles, hormis PrintPreviewControl, ne se positionnent pas sur la Form, mais en-dehors. Pour les déclencher, il suffit d'utiliser dans le code la méthode ShowDialog. Naturellement, il est possible de paramétrer ces boîtes de dialogue via leurs propriétés, et d'en récupérer les résultats, toujours via leurs propriétés. Je ne m'étend donc pas sur les détails techniques de leur utilisation, qui ne présentent pas grand intérêt pour la compréhension du langage, et qui ne posent aucune difficulté majeure pour leur mise en oeuvre... quand on a une bonne documentation.
Mais cela signifie encore une fois, je me permets d'insister, que toutes les tâches banales et courantes d'une application comme ouvrir, enregistrer, imprimer, et tutti quanti, se programment en un tournemain, vu que d'autres ont déjà fait le travail à votre place.