Vous êtes sur la page 1sur 63

C#

Premiers pas avec les WinForms

Table des matires

Introduction ................................................................................................................................ 4 Quest ce quune WinForm ? .............................................................................................. 4 Objectif .................................................................................................................................. 4 Minimum requis ................................................................................................................... 4 A propos de la portabilit .................................................................................................... 4 Chapitre 1 ................................................................................................................................... 5 Premiers pas ............................................................................................................................... 5 Application ............................................................................................................................ 5 Chapitre 2 ................................................................................................................................... 9 Une interface plus riche ............................................................................................................. 9 Application ............................................................................................................................ 9 Premire mthode : A la bourrin ! ................................................................................... 10 Seconde mthode : Rflchissez un peu ! ......................................................................... 11 Quest ce quune ancre ? ................................................................................................... 13 Fin de la partie Design ....................................................................................................... 13 Evnements ......................................................................................................................... 14 Retour sur les ancres .......................................................................................................... 15 Chapitre 3 ................................................................................................................................. 16 Interfaces multifentres ............................................................................................................ 16 Un cas simple ...................................................................................................................... 16 Interface documents multiples ....................................................................................... 20 Retour sur la premire application................................................................................... 22 Chapitre 4 ................................................................................................................................. 25 Les contrles personnaliss ..................................................................................................... 25 Application .......................................................................................................................... 25 La base de donnes ............................................................................................................. 26 User Control ........................................................................................................................ 28 Evnements personnaliss ................................................................................................. 30 La suite ............................................................................................................................ 32 Les attributs ........................................................................................................................ 36 Fin ........................................................................................................................................ 43 Pour aller plus loin ......................................................................................................... 46

Chapitre 5 ................................................................................................................................. 48 Multifentres, suite ............................................................................................................... 48 Application .......................................................................................................................... 48 Premier cas .......................................................................................................................... 51 Second cas ........................................................................................................................... 52 Chapitre 6 ................................................................................................................................. 57 A vous de jouer ......................................................................................................................... 57 Help me ! ............................................................................................................................. 57 Exemple : La TreeView ..................................................................................................... 57 Dernires informations ...................................................................................................... 58 A vous de jouer ................................................................................................................... 59
Exercice 1 : Solo Messenger........................................................................................................................ 59 Exercice 2 : Jouez ........................................................................................................................................ 59 Exercice 3 : Additionneur ............................................................................................................................ 60 Exercice 4 : Friends ..................................................................................................................................... 60 Exercice 5 : Notepad.................................................................................................................................... 60 Exercice 6 : MyWeb .................................................................................................................................... 61 Exercice 7 : QCM ........................................................................................................................................ 61 Exercice 8 : Fates le tri ............................................................................................................................... 62 Exercice 9 : PictureViewer .......................................................................................................................... 62 Exercice 10 : Notepad (suite) ...................................................................................................................... 62 Exercice 11 : Calculatrice ............................................................................................................................ 62 Exercice 12 : Explorateur ............................................................................................................................ 63

Introduction
Quest ce quune WinForm ?
Les Windows, Windows Forms, Forms ou encore SWF 1 sont la base de toute application Windows digne de ce nom. Elles sont le support graphique sur lequel vous, dveloppeur, allez placer vos contrles (boutons, menus, listes, etc.) permettant lutilisateur dinteragir facilement avec votre application.

Objectif
Vous verrez ici comment crer des interfaces graphiques (ou GUI 2). Ce tutorial est destin aux dbutants qui nont jamais ou trs peu utilis les WinForms. Cependant, les derniers chapitres peuvent intresser des dveloppeurs dun niveau moyen. La pdagogie utilise ici se base essentiellement sur la pratique et lutilisation des capacits des EDI 3 tels que Visual C# ou SharpDevelopp. Cela peut sembler paradoxal, mais il nest pas ncessaire de sy connatre en C# pour commencer ce tutorial. Il suffit davoir les connaissances de bases dans un langage de type (C/C++, Java, C# bien sr, etc.). Cependant, il est tout de mme prfrable den connatre quelques notions si vous dsirez poursuivre agrablement la lecture de ce tutorial. Trs peu de code sera fourni dans les premires parties et les notions abordes sont trs intuitives.

Minimum requis
Le .NET Framework 2.0 et Visual C# 2005 ou quivalent (Visual Studio 2005, SharpDevelopp 2.0, etc.). Nous utiliserons ici le .NET Framework 2.0 sous Windows XP ainsi que Visual C# 2005 dans sa version anglaise. Si vous utilisez encore les .NET Framework 1.1 et Visual Studio 2003 (ou quivalent), vous pourrez tout de mme suivre ce tutorial car les diffrences entre les deux versions ne seront quasiment pas exploites ici.

A propos de la portabilit
Mono gre depuis fin 2006 les SWF, vos interfaces graphiques seront donc compatibles Windows, Linux, OSX Plus dinformations

1 2

System.Windows.Forms Graphical User Interface 3 Editeur de Dveloppement Intgr

Chapitre 1 Premiers pas

Nous allons commencer pas crer une petite application qui devrait vous prendre cinq secondes si vous avez dj un peu touch aux WinForms ou sinon, tout au plus deux minutes. Essayez de la faire vous-mme avant de lire la solution. Si cest trop facile pour vous, passez donc au chapitre suivant.

Application
Ralisez une application graphique prsentant un unique bouton dont ltiquette est "Cliquez ici" et qui affichera une bote de dialogue contenant un message de votre cru.

Voyons un peu ce quil fallait faire Inutile de vous demander douvrir Visual C#, vous lavez srement dj fait Crez une Application Windows . Pour cela, allez dans File New Project, puis slectionnez Windows Application. Renommez l comme il vous plat puis validez !

Fates File New Project

Slectionnez Windows Application Vous arrivez alors sur une fiche Windows, appele communment sous .NET Form, ou formulaire en franais :

Dans votre EDI, vous avez votre disposition un panneau qui se nomme la Toolbox (ou bote outils) sous Visual C#. Celle-ci devrait se trouver sur la droite ou sur la gauche et est dployable souhait.

Remarque : Si la Toolbox nest pas affiche, allez dans le menu View et cliquez sur la ligne marque Toolbox. Vous remarquerez, si vous tes un peu observateur, que cette Toolbox contient une multitude ditems qui correspondent en fait des raccourcis vers des Control (ou contrles) tels que des Label, Button, ListBox, etc. Slectionnez le contrle qui vous intresse et cliquez sur le formulaire lendroit o vous souhaitez le placer. Votre contrle est en place :

Remarque : Vous pouvez galement placer un contrle sur votre Form en effectuant un Drag & Drop (ou glisser-dposer) depuis la Toolbox jusquau formulaire (en mode Designer). Si votre contrle est mal positionn, vous pouvez toujours le dplacer en le slectionnant directement sur votre Form puis en dplaant le curseur (lequel est prsent suivi par votre contrle) lendroit dsir Redimensionnez prsent la fentre et le bouton de manire obtenir la prsentation suivante

le bouton tant parfaitement centr. Pour centrer le bouton, slectionnez-le et cliquez successivement dans la barre doutils de mise en forme sur Center Horizontally et sur Center Verticaly.

Si cette barre de raccourcis nest pas affiche, vous pourrez la trouver dans le menu View Toolbars Votre bouton est donc plac mais il affiche pour le moment "Button1". Pour modifier son tiquette, slectionnez votre bouton puis allez dans le panneau des proprits (si celui-ci nest pas affich, vous le retrouverez galement dans le menu View). Dans ce dernier, existe une ligne marqu Text et contenant le texte "Button1". Modifiez "Button1" et tapez "Cliquez-ici".

Attention : Les contrles pouvant afficher du texte ont gnralement leurs deux proprits Text et Name la mme valeur que le texte affich par le contrle. Name et Text sont deux proprits distinctes : Text permet de modifier le texte qui sera affich alors que Name modifie le nom que porte votre contrle dans le code source. Reste maintenant associer lvnement clic de ce bouton, laffichage du message. Fates un double clic sur le bouton (depuis le mode Designer). Vous vous retrouvez alors en mode codeur, plac directement dans une fonction portant le nom (Name) de votre bouton, suivie de _Click(). Ajoutez alors le code ci-aprs au sein de cette mthode : MessageBox.Show("Merci davoir cliqu", "Message"); Nattendez plus, lapplication est termine ! Excutez le code (raccourci F5 dans Visual Studio) et admirez le rsultat !

Chapitre 2 Une interface plus riche

La premire application tait vraiment simplissime, passons quelque chose dun peu plus pouss.

Application

Ci-dessous, les caractristiques de cette application Pour toutes dimensions de la fentre, que lutilisateur peut redimensionner souhait (comportement par dfaut), il faut que : la barre de menu reste fixe en haut de la fentre de mme pour la barre de raccourcis (sauf quelle est fi xe au bas de la barre de menu) le SplitContainer occupe tout lespace restant la ListBox occupe tout lespace du Panel gauche du SplitContainer les deux TextBox occupent toute la largeur du Panel droit du SplitContainer ltiquette "Nom" reste fixe dans le coin suprieur gauche du Panel droit du SplitContainer ltiquette "Prnom" reste la mme distance des deux TextBox et de la bordure gauche du Panel droit du SplitContainer lespace sparant les deux boutons (entre eux) soit toujours le mme lespace sparant les deux boutons de la TextBox soit toujours le mme lespace sparant le bouton OK de la bordure droite du Panel droit du SplitContainer soit toujours le mme

Et voici la liste des actions : le menu fichier contient 3 lments : "RAZ" pour vider les TextBox et la ListBox un sparateur "Quitter" pour quitter lapplication le menu daide contient un seul lment : "A propos de" qui affiche quelques informations propos de cette application (vous mettrez ce que vous voudrez) dans une MessageBox (et pas autre chose) le bouton est un raccourci de "RAZ"

le bouton est un raccourci de "A propos de" le bouton "Vider" efface simplement le contenu des deux TextBox le bouton "OK" ajoute le contenu des TextBox associs "Nom" et "Prnom" en les sparant par un espace. Concrtement, si on a dans la TextBox de "Nom" : "Gates" et dans celui de "Prnom" : "Bill", alors en cliquant sur le bouton "OK", on ajoute "Bill Gates" dans la ListBox. Remarque : Si vous observez bien limpression cran de lapplication, vous consta terez que le F du menu Fichier est soulign non pas par hasard bien videmment. Il sagit l dun raccourci clavie r pour accder au menu Fichier qui est automatiquement attribu par Windows. Lorsque lutilisateur fait la combinaison Alt+F, il ouvrira ainsi le menu Fichier (sans touche la souris bien sr). Pour quune lettre de menu apparaisse souligne (et attribuer ainsi un raccourci clavier votre menu), vous devez la faire prcder du caractre esperluette (&). Cela sapplique tous les menus, sous menus et la lettre du raccourci peut tre nimporte quelle lettre du mot du menu, sous menu Aide : Le splitter est en fait un lment de SplitContainer (que vous pourrez trouver dans la ToolBox) Intressez vous la proprit Dock de vos contrles Intressez vous galement la proprit Anchor (pour voir ce quelle fait vraiment, vous devrez excutez lapplication, la manipuler un peu dans tous les sens) A vous de jouer ! Trop facile ? Dans ce cas passez directement au chapitre suivant. Pas si simple que ? Alors lisez ce qui suit ! Pour commencer, crez votre application Windows. Il faut prsent ajouter les contrles. Nous allons faire suivant deux mthodes : la mthode bourrin (pas intelligente du tout) la mthode intelligente

Premire mthode : A la bourrin !


Comme son nom vous la probablement laiss supposer, ne rflchissez pas quant la faon logique dont les contrles sont disposs, placez les tous, on verra aprs

Soit vous avez de la chance, soit vous nen avez pas et vous tes dans un sacr ptrin, ou du moins, vous vous compliquez srieusement la tche en procdant ainsi. Voyons plutt lautre mthode.

Seconde mthode : Rflchissez un peu !


Et vous serez oblig, un moment ou un autre, de rflchir la manire dont sorganise votre GUI. Si on devait poursuivre avec la premire mthode, on slectionnerait dans lordre appropri chaque contrle afin de lui donner les proprits souhaites, de le placer comme il faut, etc. Ici, nous allons en fait placer les contrles un un en les positionnant immdiatement correctement puis leur donner directement leurs proprits. Cela vitera notamment davoir revenir sur chacun dentre eux pour en modifier une petite donne On gagne donc du temps. Si on regarde bien linterface, on saperoit quun des contrles encapsule les autres, quil les contient Cest dailleurs son nom vu quil sagit du SplitContainer (qui contient ListBox, TextBox, Label et Button). Nous navons donc que trois contrles qui se trouvent au mme niveau : le menu, la barre de raccourcis et le SplitContainer. Lequel placer en premier ? Si on regarde ce que lon attend de lapplication, on doit avoir : la barre de menu reste fixe en haut de la fentre de mme pour la barre de raccourcis (sauf quelle est fixe au bas de la barre de menu) le SplitContainer occupe tout lespace restant Par consquent, on peut placer le SplitContainer en premier (sinon o mettrait-on la barre de menu et de raccourcis ?), ni la barre de raccourcis (puisquelle est fixe la barre de menu). Vous devez par consquent placer la barre de menu en premier.

Par chance, ou plutt par commodit et conventionalit, la barre de menu sest automatiquement place en haut de la fentre. Rien de plus faire son sujet Ajoutez de mme la barre de raccourcis. Placez prsent le SplitContainer. Celui-ci se place galement immdiatement comme il faut : il occupe tout de suite tout lespace restant du formulaire. Cest pour cela quil faut rflchir

Comme vous pouvez le constater, votre SplitContainer se divise en deux Panel. Chaque Panel reprsente en fait un nouveau support graphique complet qui ragit de la mme manire quune Form vide.

Il faut prsent placer la ListBox dans le Panel de gauche. Commencez donc par lajouter.

Mais un problme se pose alors. Nous voulons que la ListBox occupe tout le Panel de gauche et pas seulement une partie. Pour ce faire, rglez la proprit Dock du contrle ListBox sur Fill :

Voila, la ListBox occupe prsent tout le Panel de gauche.

Remarque : Testez galement les autres valeurs de la proprit Dock pour voir ce quelles font. Occupons nous prsent du Panel de droite.

Placez-y les premier Label et modifiez en le texte pour quil affiche "Nom". Si vous essayez de le placer dans le coin suprieur gauche du Panel, vous verrez apparatre des petits pointills bleus liant les bordures du Panel aux parties du Label qui en sont le plus proche

Nous voulons prsent que ce Label reste fix en haut gauche du Panel. Pour cela, il faut dfinir son ancre (proprit Anchor) sur Top, Left. Etant donn quil sagit l de la valeur par dfaut de cette proprit, vous naurez rien modifier.

Quest ce quune ancre ?


La dfinition est en fait trs proche de celle que lon pourrait donner une ancre de navire Anchor : obtient ou dfinit les bords du conteneur auquel un contrle est li et dtermine comment un contrle est redimensionn avec son parent. (Dfinition tire de MSDN 2007) Si vous ne percevez pas encore leur utilit, pas de panique, vous le verrez mieux un peu plus loin.

Fin de la partie Design


Terminons le dessin de notre application ! Placez prsent la premire TextBox de manire ce que celle-ci occupe toute la largeur du Panel2 et quelle se trouve juste sous le premier Label. Lorsque les dimensions et la position de la TextBox seront bonnes, vous verrez trois indicateurs de positions (bleus) safficher en essayant de redplacer le contrle.

Maintenant que la TextBox est convenablement place, empressez vous de la renommez (proprit Name et non pas Text) de manire cohrente (en sachant quoi la TextBox va servir). Nous la nommerons ici "textBoxOfName" (veuillez respecter la casse). Modifiez ensuite le contrle de manire ce que ses ancres soient fixes gauche, droite et en haut. Parfait, cest presque fini ! Les deux contrles suivants sont exactement les mmes que les deux prcdents Fates donc un copier/coller des deux contrles prcdents. Attention : Au moment de coller vos contrles, assurez vous que la zone active (cerne par des pointills) est bien celle o vous voulez coller vos contrles. Une fois colls, gardez les deux lments slectionns (ou reslectionnez-les sils ne le sont plus tout les deux) et dplacez les tout deux en mme temps au bon endroit

Vrifiez ensuite leurs proprits dancres et modifiez les proprits Name et Text comme prcdemment. Bien entendu, la proprit Text du Label vaut prsent "Prnom" et la proprit Name de la TextBox vaut "textBoxOfFirstName". Ajoutez maintenant les deux boutons. Modifiez en les proprits Text comme il convient et fixez leurs ancres sur Right et Top. Reste ajouter les boutons et les liens dans les barres de menu et de raccourcis, mais vous naurez pas de mal pour trouver comment faire.

Evnements
Sans mme rflchir, commencez par crer les deux fonctions des boutons OK et Vider Vous pouvez, si vous le souhaitez, modifier auparavant le nom (proprit Name) afin que les noms des mthodes soient plus explicites (exemple : pour le bouton OK, mettez buttonOK). Voyons un peu ces deux nouvelles mthodes. private void buttonOK_Click(object sender, EventArgs e) { } private void buttonVider_Click(object sender, EventArgs e) { } et rappelons nous ce quelles devaient faire : le bouton "Vider" efface simplement le contenu des deux TextBox le bouton "OK" ajoute le contenu des TextBox associs "Nom" et "Prnom" en les sparant par un espace. Concrtement, si on a dans la TextBox de "Nom" : "Gates" et dans celui de "Prnom" : "Bill", alors en cliquant sur le bouton "OK", on ajoute "Bill Gates" dans la ListBox. Effacer le contenu dune TextBox revient mettre une valeur "" dans sa proprit Text. Par consquent, la mthode associe au clic sur le bouton vider contient : textBoxOfFirstName.Text = ""; textBoxOfName.Text = "";

Pour ajouter un lment une ListBox, il suffit dutiliser la mthode membre Add() de la proprit Items. listBox1.Items.Add(textBoxOfFirstName.Text + " " + textBoxOfName.Text); Les derniers vnements crer sont tous trs simples. Vous devriez y arriver tout seul prsent. Aide : Pour quitter une application qui utilise des Forms, il faut utiliser la mthode Exit() de la classe statique Application.

Retour sur les ancres


Pour voir lutilit des ancres, il ny a pas grand -chose faire Slectionnez lune des TextBox et au lieu de laisser les ancres fixes sur Left, Right, Top, mettez simplement Left. Excutez le programme Tout va bien, aucune diffrence. Maintenant, redimensionnez lapplication en en modifiant la largeur (en tirant le ct droit de la fentre, vous verrez mieux ce qui se passe) ou la hauteur Constatez la diffrence ! Vous pouvez vous amuser comme cela en modifiant les ancres de cos contrles, en les redimensionnant pour avoir tel ou tel comportement. Aprs un tel exercice, vous devriez avoir parfaitement compris quoi servent les ancres.

Chapitre 3 Interfaces multifentres

Un seul formulaire pour toute une application, cest bien souvent insuffisant et moins de travailler normment sur le dynamisme de linterface, cest tout simplement impossible (dpend de lapplication bien entendu). Dans ce chapitre, nous allons voir comment appeler des formulaires depuis un autre formulaire et comment faire pour que formulaires enfants et parents puissent schanger des informations. Remarque : La complexit de linterface ne nous intresse pas dans ce chapitre.

Un cas simple

Cette application est trs basique Le formulaire principal ne fait rien : il ne sert qu afficher le for mulaire secondaire ("FORM FILLE") qui permet dentrer du texte. En cliquant sur le bouton OK, le texte est directement transmis dans le champ du formulaire principal Si on reclique ensuite dans le formulaire principal sur le bouton Changer, on rouvre le formulaire secondaire et on y retrouve le texte que lon y avait inscrit, etc., etc. Commencez par crer les deux formulaires et placer les contrles ncessaires. Renommez-les et paramtrez-les comme il vous convient.

Note : Pour ajouter un formulaire votre projet : clic droit dans lexplorateur de solution, Add Windows Form

Modifiez galement la proprit Name du formulaire enfant et mettez-y "FormFille" (tout accroch). Crez ensuite lvnement associ au clic sur le bouton Changer et rendez vous dans la mthode cre pour private void buttonChange_Click(object sender, EventArgs e) { } Cest ici que vous devez commander laffichage de votre formulaire enfant. Pour afficher le formulaire enfant, il faut dabord que celui-ci existe : il faut dabord le crer ! FormFille ff = new FormFille(); Ensuite, il suffit de lafficher : ff.Show(); Dans notre mthode, cela donne donc : private void buttonChange_Click(object sender, EventArgs e) { FormFille ff = new FormFille(); ff.Show(); } Voil, cest bon ! Vous pouvez tester Remarque : Il existe en fait deux mthodes pour afficher un formulaire : Show() et ShowDialog() qui ragissent diffremment Comparez ces deux mthodes. Vous remarquerez en les comparant et en rduisant votre application (notamment) que les deux icnes dans la barre des tches (une pour chaque formulaire) ne sont pas toutes les deux utiles. Nous utiliserons, pour des raisons pratiques et dans le but de minimiser le code, la mthode ShowDialog() qui renvoie un objet de type DialogResult. Si vous ne voulez pas quun formulaire (nimporte laquelle) ait une icne qui saffiche dans la barre des tches, rglez sa proprit ShowInTaskbar sur false. La proprit ShowIcon qui se trouve juste ct permet de choisir si licne de lapplication (en haut gauche) doit tre affiche ou non Pour en finir avec le formulaire parent (du moins pour linstant), rglez la proprit ReadOnly de la TextBox sur true (lutilisateur ne doit pas pour modifier le texte que celle -ci contient). Allons prsent faire un petit tour dans le formulaire enfant Nous voulons que celui-ci se ferme lorsque lutilisateur appuie sur OK. Pour cela, il y a plusieurs faons de procder, mais nous allons utiliser ici la mthode la plus simple et la plus intelligente qui soit Il suffit dutiliser en fait une proprit du formulaire : AcceptButton. Voyez par vous-mme : associez la proprit DialogResult du bouton OK la valeur OK associez la proprit AcceptButton du formulaire enfant le bouton OK testez !

Remarque : Cela ne marchera que si vous affichez le formulaire enfant avec la mthode ShowDialog(). Alors quel est ce miracle ? Eh bien pour le savoir, rien de mieux que deffectuer un petit dbogage en plaant judicieusement deux breakpoints.

Note : Un breakpoint se place (sous Visual Studio) en cliquant dans la marge sur la ligne o lon veut p oser le breakpoint. Un breakpoint entraine ncessairement la mise en pause du programme lorsque celui-ci (de breakpoint) est rencontr. En effectuant le dbogage (F5 pour continuer une fois arrt), vous vous apercevrez alors qu en appuyant sur le bouton OK, vous revenez dans la mthode associe au clic du bouton Changer. La suite nest quune histoire de porte En quittant la mthode, vous dtruisez tout ce que celle -ci a cr, vous dtruisez donc le formulaire enfant et celui-ci disparait. Remarque : En fait le formulaire ne disparait parce quil est dtruit dans ce cas (cela serait suffisant dans dautres cas) Il sagit en fait du comportement de la mthode ShowDialog(), qui, lorsquelle sent quun DialogResult est mis, ferme le formulaire Il ne nous resterait donc qu placer le code ncessaire entre ces deux breakpoints pour rcuprer puis afficher le texte du formulaire enfant. Sauf que lon ne veut effectuer cette action que si le bouton OK est cliqu (pas si la croix est clique). En sachant que la mthode ShowDialog() (ce nest pas le cas de Show()) renvoie un objet de type DialogResult et que le DialogResult associ au bouton OK est justement OK, il suffit dajouter la condition : if (ff.ShowDialog() == DialogResult.OK) { } A prsent, on peut placer le code traitant le texte entre les accolades de la condition. Mais dabord, il faut pouvoir accder ce texte (qui se trouve dans le formulaire enfant et auquel nous navons pas accs par dfaut). Pour cela, deux possibilits : la mauvaise : on rend la TextBox du formulaire enfant publique (c'est--dire accessible depuis lextrieur) en rglant sa proprit Modifiers sur Public. On a alors directement accs la TextBox depuis le formulaire parent et il ne reste plus qu taper : textBox1.Text = ff.textBoxEnfant.Text; la bonne : on va dans le code source du formulaire enfant et on ajoute la proprit (publique bien sr) suivante : public string InputText { get { return textBoxEnfant.Text; } set { textBoxEnfant.Text = value; } }

Il suffit alors de questionner cette proprit depuis le formulaire parent : textBox1.Text = ff.InputText; Contrlez ! Tout marche bien Reste prsent passer le texte de la premire TextBox au formulaire enfant lorsque celui-ci est cr et insrer ce texte dans la TextBox du formulaire enfant. En utilisant la bonne mthode (la dernire), cest immdiat. Il suffit de passer la chane de caractres de la premire TextBox (celle du formulaire parent) en utilisant la proprit cre prcdemment. Pour que cela fonctionne comme souhait, il faut faire attention de passer la chane avant dafficher le formulaire enfant. Finalement, le code complet du bouton Changer donne quelque chose du genre : private void buttonChange_Click(object sender, EventArgs e) { FormFille ff = new FormFille(); ff.InputText = textBox1.Text; if (ff.ShowDialog() == DialogResult.OK) { textBox1.Text = ff.InputText; } } Voil pour le cas simple Remarque : Nous traiterons un cas plus complexe (et ncessitant quelques connaissances supplmentaires en C# que vous aurez acquise dici l) dans le chapitre 5. Quelques proprits : Enabled : en rglant cette proprit sur false pour une TextBox, cela revient griser la case de la TextBox et interdire la saisie et la slection du texte qui sy trouve. Cette proprit existe pour tous les contrles. Visible (true ou false) : affiche ou massage le contrle (que ce soit un formulaire, un bouton, une bote de texte) AcceptButton : vous permet de choisir quel bouton du formulaire sera activ lorsque lutilisateur appuiera sur la touche Entrer. CancelButton : mme chose mais avec la touche Echap. ControlBox (true ou false) : affiche ou masque la barre de contrle du formulaire BackColor : permet de choisir la couleur de fond du contrle (Form, Button, etc.) FormBorderStyle : permet de changer le style de la fentre Icon : associe une icne au formulaire MinimizeBox (true ou false) : transparent MaximizeBox (true ou false) : transparent TopMost : force le formulaire rester toujours au premier plan (et ceux par rapport toutes les applications) Size : modifier ou obtenir la taille du contrle StartPosition : obtient ou dfinit la position initiale du formulaire au moment de lexcution Il ne sagit nullement dune liste exhaustive des proprits des proprits de la classe Form Pour obtenir cette liste, rendez-vous sur MSDN.

Interface documents multiples


Nous allons nous intresser prsent une autre faon de grer les multifentres, il sagit des MDI4. Si le nom ne vous dit rien, linterface vous rappellera certainement quelques logiciels : Citons immdiatement les proprits en rapport avec les MDI : ActiveMdiChild : obtient la fentre enfant MDI active. IsMdiChild : obtient une valeur indiquant si le formulaire est un formulaire enfant MDI. IsMdiContainer : obtient ou dfinit une valeur indiquant si le formulaire est un conteneur de formulaires enfants d'interface multidocument (MDI). MdiChildren : obtient un tableau de formulaires reprsentant les formulaires enfants MDI qui sont apparents ce formulaire. MdiParent : obtient ou dfinit le formulaire parent MDI en cours de ce formulaire. Et les mthodes : LayoutMdi : organise les formulaires enfants MDI au sein du formulaire parent MDI. ActivateMdiChild : active lenfant MDI dun formulaire. Rien de bien difficile en fin de compte pour crer ce type dinterface Il suffit simplement de crer un formulaire qui va contenir les autres et de mettre sur true sa proprit IdMdiContainer (le style du formulaire change alors immdiatement) et de crer dautres formulaires en spcifiant quel est leur formulaire parent avec la proprit MdiParent. Par exemple, commencez par raliser linterface ci-contre avec le menu Fichier qui ne contient que "Quitter" et un seul bouton sur la barre de raccourcis. Pour avoir laspect infrieur du formulaire ci-contre, mettez sur true sa proprit IsMdiContainer. Sur lunique bouton de la barre de raccourcis, mettez : Form form = new Form(); form.Text = "Form " + MdiChildren.Length; form.MdiParent = this; form.Show(); Lancez et testez votre application !
4

Multiple Document Interface

Rien de plus simple donc Vous pouvez bien sr ajouter des formulaires que vous avez-vous-mme fait avec le Designer (ou sans). Exemple : Crez le formulaire suivant

et ajoutez le votre MDI. Crez un deuxime formulaire (comme vous le voulez) et fates en sortes quen cliquant sur le bouton Nouveau, on ait une fois le formulaire 1 qui soit ajoute, puis une fois le formulaire 2, une fois le formulaire 1, etc.

Si vous voulez faire communiquer les formulaires enfants avec le formulaire parent, cest comme prcdemment, crez des proprits, etc. Les communications entre formulaires enfants seront abordes au chapitre 5. Remarque : Intressez vous la proprit LayoutMdi et voyez ce quelle permet de faire Si vous avez besoin dune interface relativement standard grant les MDI, Visual C# offre la possibilit de crer directement un formulaire MDI.

Vous obtenez une interface toute prte qui traite dj un certain nombre de fonctions (nouveau, enregistrer, ouvrir).

Retour sur la premire application

Nous allons modifier le code de la premire application de manire ce que la fentre fille ne soit plus dtruite chaque fois que lon clique sur le bouton OK. Pour cela, revoyons comment le formulaire enfant tait cre :

private void buttonChange_Click(object sender, EventArgs e) { FormFille ff = new FormFille(); ff.InputText = textBox1.Text; if (ff.ShowDialog() == DialogResult.OK) { textBox1.Text = ff.InputText; } } Ici, on cre une instance dobjet de la fentre fille avec le mot cl new. Cette instance est stocke dans la variable ff. Ensuite, on demande linstance de la fentre fille de safficher. On fait des tests et une fois sorti des tests, plus rien on sort de la mthode du clic et on perd toute trace de la fentre fille : linstance est dtruite et au prochain clic, tout sera reconstruit ce qui nest pas toujours souhaitable en fonction de ce que lon veut raliser comme application. Pour y remdier, cest simple, il suffit dajouter FormFille ff aux champs de la classe du formulaire parent (ou plus gnralement, du formulaire qui sera le lanceur de la nouvelle fentre) public partial class Form1 : Form { //Champs FormFille ff; //Constructeur public Form1() { InitializeComponent(); } //Mthode du bouton Changer private void buttonChange_Click(object sender, EventArgs e) { FormFille ff = new FormFille(); ff.InputText = textBox1.Text; if (ff.ShowDialog() == DialogResult.OK) { textBox1.Text = ff.InputText; } } } et de crer linstance de cette Form dans le constructeur de la classe mre. et de crer linstance de ce formulaire dans le constructeur de la classe mre. //Constructeur public Form1() { InitializeComponent(); ff = new FormFille(); } Notre objet, notre formulaire enfant existe prsent tout le temps enfin, jusqu ce que le formulaire parent soit dtruit lui aussi (dans cette application, cela narrivera quen la quittant). Voyons prsent quoi doit ressembler le code du bouton Changer :

//Mthode du bouton Changer private void buttonChange_Click(object sender, EventArgs e) { ff.InputText = textBox1.Text; if (ff.ShowDialog() == DialogResult.OK) { textBox1.Text = ff.InputText; } } On peut mme faire mieux ! En effet, vu que le formulaire enfant existera toujours, les contrles quelle contient aussi et en particulier la TextBox. Autrement dit, entre deux clics sur le bouton Changer, la TextBox et par consquent le texte quelle contient (ce qui nous intresse) ne seront pas modifis et il devient alors inutile de repasser au formulaire enfant le texte modifier : //Mthode du bouton Changer private void buttonChange_Click(object sender, EventArgs e) { if (ff.ShowDialog() == DialogResult.OK) { textBox1.Text = ff.InputText; } } Et on peut galement modifier la proprit du formulaire enfant, la modification de la TextBox quil contient devenant inutile (dans cette application) : public string InputText { get { return textBoxEnfant.Text; } } Contrlez ! Cela marche comme auparavant : lutilisateur ne voit pas la diffrence du moins dans cette application car si vous aviez du ouvrir un formulaire dont le temps de chargement est non ngligeable, mieux vaut ne le charger quune seule fois et choisir ensuite de lafficher ou pas.

Chapitre 4 Les contrles personnaliss

Tout cela est bien gentil mais cela commence devenir rudement complexe grer si lapplication comporte sur un mme formulaire des dizaines (voire des centaines) de contrles et qui plus est, ont, malgr vos efforts, tous des noms relativement proches. Il devient difficile de sy retrouver. Pire ! LEDI commence ramer srieusement lorsque vous lui fates afficher le formulaire en mode Designer. Imaginez par exemple que vous vouliez raliser un jeu de mots croiss. Comment crer son interface si ce nest quavec des centaines de TextBox ? La solution ce problme se nomme les contrles utilisateurs dont nous allons voir comment en tirer toute la puissance.

Application
Nous nallons pas faire de mots croiss car cela compliquerait srieusement le travail faire. Voila notre but :

Chacun des GroupBox (encadr en rouge) se trouve dans un contrle utilisateur diffrent (nous avons donc trois contrles utilisateurs crer).

Comportement : La GroupBox Mes amis est dsactive tant quun contact na pas t ajout la base de donnes. La GroupBox Photo reste dsactive tant quun ami nest pas slectionn dans la liste des amis du GroupBox Mes amis. Un contact est ajout la base de donnes lors que le bouton Accepter est cliqu. Le contact est invisible par dfaut pour lutilisateur. Lorsque lutilisateur appuie sur le bouton Rechercher, le ou les contacts dont les noms ou prnoms contiennent le texte marqu dans la TextBox de Nom/prnom sont ajouts la ComboBox. Si la TextBox de Nom/prnom est vide, tous les contacts sont ajouts dans la ListBox. Lorsquun contact est slectionn dans la ComboBox, les boutons Ajouter et Details deviennent cliquables. En cliquant sur Ajouter, le contact est ajout la liste des amis. Si un contact est slectionn dans la liste des amis, le bouton Details devient cliquable et la GroupBox Photo est active. Si le bouton Details est cliqu, la GroupBox Contact est remplie par les donnes du contact en question mais la GroupBox est dans un tat qui empche lutilisateur de modifier le contact. Pour entrer un nouveau contact, il faut absolument dslectionner (perte de focus) le contact en question. A lactivation de la GroupBox Photo, si lami a dj une photo, celle-ci est immdiatement affiche, sinon, rien nest affich. En cliquant sur Modifier, une bote de dialogue douverture de fichier apparat et lutilisateur peut slectionner un fichier de type JPEG ou JPG uniquement pour ajouter limage choisie en tant que photo de lami. Ca commence se compliquer un peu Essayez de faire seul cette application. Si vous y parvenez, bravo ! Sinon, pas grave, cest normal, cest dj assez difficile faire comme programme surtout si vous dbutez. Que vous ayez russi ou non, la suite devrait certainement vous intresser

La base de donnes
Il est prfrable de commencer par mettre en place la base de donnes avant de sattaquer linterface et plus particulirement aux contrles personnaliss. Ici, nous allons simplement crer une classe Contact capable de recevoir toutes les donnes que nous sommes en mesure de lui fournir (ne pas oublier la photo). Lensemble des contacts sera gr en interne par une classe gnrique : List. Remarque : Les gnriques ntant disponibles que sous C# 2.0 ou version ultrieure, vous ne pourrez en faire usage en C# 1.1 et vous ne pourrez donc pas utiliser la classe gnrique List en C# 1.1. Pas dinquitude, vous pouvez utiliser la classe ArrayList la place. Le code pour ArrayList sera galement fourni Voyons un peu le code de cette classe Contact : public class Contact { //Champs private string name; private string firstName; private string adresse; private string email; private string telfixe; private string telmob; private bool isFriend;

private byte[] photo; //Constructeur public Contact( string name, string firstName, string adresse, string email, string telephoneFixe, string telephoneMobile) { this.name = name; this.firstName = firstName; this.adresse = adresse; this.email = email; this.telfixe = telephoneFixe; this.telmob = telephoneMobile; this.isFriend = false; } //Proprits public string Name { get { return name; } } public string FirstName { get { return firstName; } } public string Adresse { get { return adresse; } } public string Email { get { return email; } } public string TelephoneFixe { get { return telfixe; } } public string TelephoneMobile { get { return telmob; } } public bool IsFriend { get { return isFriend; } set { isFriend = value; } } public byte[] Photo { get { return photo; } set { photo = value; } } }

Rien de difficile dans cette classe on ne fait que stocker les donnes et les rcuprer Remarque : Pensez crer un nouveau fichier ddi cette classe Contact et nommez le Contact.cs. Allez prsent sur le formulaire principal et modifiez en le nom du fichier, tapez : MainForm.cs et allez immdiatement dans le code source. Il faut crer cette fameuse liste de contacts. Pour cela, ajoutez le champ suivant dans la classe MainForm List<Contact> myContacts; et instanciez le dans le constructeur public MainForm() { InitializeComponent(); myContacts = new List<Contact>(); } Voila, on peut prsent soccuper de linterface graphique Pour ajouter un contact cette liste, il suffit dutiliser la mthode membre de la classe List : Add(). Note : Comme signal prcdemment, le code prcdent nest valable que sous C# 2.0 ou une version ultrieure. Sous C# 1.1, il suffit de remplacer List<Contact> par ArrayList. ArrayList contient de mme une mthode Add() pour y ajouter des lments.

User Control
Commencez par ajouter un User Control votre projet

Nommez le ContactArea.cs :

Vous avez alors votre disposition un nouveau support de dessin, similaire celui dun formulaire mais sans les bordures de fentres La zone encadre correspond votre contrle. Vous pouvez la redimensionner

Placez-y les lments de linterface de la GroupBox Contact Redimensionnez le contrle personnalis comme vous le voulez pour faciliter le placement des contrles Dfinissez la proprit Dock de la GroupBox sur Fill pour que le contrle personnalis et la GroupBox ne fassent quun.

Remarques : Lorsque vous rglez la proprit Dock dun contrle sur Fill, vous pouvez par la suite avoir du mal accder au contrle parent (ici, il sagit du support mm e du contrle personnalis). Pour cela, fates un clic droit dans le tas... une petite liste des contrles accessibles saffichent alors, slectionnez celui qui vous intresse (dans notre cas, sera Select ContactArea). Pensez aux ancres !!! Occupez vous de lvnement associ au clic sur le bouton Vider Remarque : Etant donn que nous allons galement vider tous les champs lorsque le contact sera ajout la liste, il est largement conseill de crer une mthode spcialement ddie cette tche. Il suffira alors dappeler cette mthode aux moments o lon en aura besoin. Cela permet de ne pas avoir rcrire plusieurs fois le mme code dans diffrentes mthodes. Voyons par contre ce quil est possible de faire pour le bouton Accepter Lorsque le bouton Accepter est cliqu, on veut quun contact soit ajout notre liste. Le problme, cest que le formulaire principal na pas et ne doit pas avoir accs au bouton Accepter puisque celui-ci appartient au contrle utilisateur (et pas au formulaire principal comme stait le cas dans les applications prcdentes). Pour que le formulaire principal ait connaissance du contenu du contrle personnalis, il y a plusieurs solutions mais on peut rsumer en disant quil faut simplement que le formulaire princip al ait accs ces donnes par des proprits (publiques) personnalises du contrle utilisateur. Dans tous les cas, nous voulons ajouter le contact aprs que le bouton Accepter ait t cliqu. Un clic correspondant un vnement. Il faudra de mme tre en mesure de signaler au formulaire principal que le bouton Accepter t cliqu mais celui-ci nayant pas accs au bouton en question, il va galement falloir crer nos propres vnements pour cet User Control. Commenons par le plus simple : occupons nous dabord des proprits. Il y a diffrentes faons de procder : Soit on cre une proprit pour chaque champ (cela nous en ferait six en tout) Soit on se dbrouille pour que toutes les informations soient passes en une seule fois, avec une seule proprit. Cela doit toutes fois rester simple et comprhensible pour quelquun qui na pas conu lui-mme le contrle utilisateur. Ici nous allons pouvoir appliquer la deuxime mthode car nous avons notre disposition une classe Contact qui a t spcialement cre pour cela.

Il suffit finalement de crer une uniquement proprit renvoyant une instance de Contact contenant tous les lments du contrle utilisateur. Simple : public Contact Contact { get { return new Contact( textBoxName.Text, textBoxFirstName.Text, textBoxAddress.Text, textBoxEmail.Text, textBoxTelHome.Text, textBoxTelMob.Text ); } } Pensez galement que le formulaire principal devra tre capable de demander un contact de safficher dans le contrle personnalis. Il suffit pour cela dajouter laccesseur set la proprit prcdente set { textBoxName.Text = value.Name; textBoxFirstName.Text = value.FirstName; textBoxAddress.Text = value.Adresse; textBoxEmail.Text = value.Email; textBoxTelHome.Text = value.TelephoneFixe; textBoxTelMob.Text = value.TelephoneMobile; } Cest tout ce quil y a faire pour les proprits. A prsent notre User Control est bien quip pour communiquer convenablement avec nimporte quel contrle parent. Reste avertir le contrle parent du moment o le bouton Accepter sera cliqu.

Evnements personnaliss
Pour cela il faut crer notre propre vnement. Voyons dabord comment on accde aux vnements dj existant button2.Click += new EventHandler(button2_Click); //Plus loin dans le code //La mthode button2_Click private void button2_Click(object sender, EventArgs e) { } Mais au fait, pourquoi ne pourrions nous pas mettre simplement la mthode button2_Click sans paramtre ?

//Pourquoi pas ? private void button2_Click() { } Alors, quest ce qui nous en empche ? En fait, lvnement Click est de type EventHandler et EventHandler prend en paramtre (target) une mthode ne renvoyant rien (type void) et prenant ellemme en paramtre, dans cet ordre, un object et un EventArgs. Nous pouvons donc crer nimporte quelle mthode, avec nimporte quel nom et la passer en paramtre au EventHandler, la condition que cette mthode prenne en paramtre un type object puis un type EventArgs. Nous avons donc besoin de crer un vnement qui soit publique, qui indique que le bouton Accepter a t cliqu et qui soit de type EventHandler car nous nallons en fin de compte faire que transfrer lvnement Click du bouton Accepter depuis lUser Control vers le contrle parent (ici, le formulaire principal) car nous navons pas dinformations ajouter lvnement Placez, de la mme manire que pour un champ, la ligne de code suivante : public event EventHandler AcceptButtonClick; Nous avons bien ici ajout notre classe ContactArea un vnement (event) de type EventHandler et qui est public et qui indique, pour linstant par son nom, quil sera dclench au moment o le bouton Accepter sera cliqu. Il ne nous reste plus qu le dclencher au bon moment. Allez dans la mthode associe au clic sur le bo uton Accepter et placez-y les lignes suivantes : if (AcceptButtonClick != null) AcceptButtonClick(sender, e); Rappelons que AcceptButtonClick est de type EventHandler et que EventHandler prend en paramtre une mthode lors de sa construction ! Lorsquon veut utiliser AcceptButtonClick, il faut donc dabord vrifier que celui-ci pointe effectivement vers une mthode. Si ce nest pas le cas, il vaut null. Sinon, on peut appeler AcceptButtonClick, ce qui revient en fait appeler la mthode vers laquelle pointe AcceptButtonClick via le EventHandler. Remarque : EventHandler pointe sur une mthode car il sagit en fait dun dlgu. Nous naborderons pas ici leur fonctionnement et nous nous limiterons leur utilisation via les vnements, ce qui est beaucoup plus intuitif et donc simple comprendre. Retenez simplement quun dlgu est un pointeur de mthode . Cest tout On peut prsent ajouter le nouveau User Control au formulaire principal Retournez sur le formulaire principal et regardez dans la Toolbox. Il devrait y avoir un nouveau contrle portant le nom ContactArea et reprsent par une icne dengrenage tout en haut Sil ny est pas, reconstruisez (Build Build Solution ou F6) le projet. Sil ny a pas derreurs, il devrait prsent tre visible

Ne vous reste donc plus qu lajouter votre formulaire comme nimporte quel autre contrle. Remarquez ds prsent que votre contrle personnalis se comporte dans le Designer comme nimporte quel autre contrle que vous avez lhabitude de manipuler Allons prsent nous occuper de cette liste de contacts. Commencez par crer la mthode associe lvnement AcceptButtonClick. Attention, ici pas de double clic sur le contrle, il va falloir aller faire un petit tour dans le code Cette mthode prend en paramtre, rappelez-vous, un type object et un type EventArgs private void addContact(object sender, EventArgs e) { } Ajoutez ensuite cette mthode lvnement AcceptButtonClick dans le constructeur du formulaire principal. public MainForm() { InitializeComponent(); myContacts = new List<Contact>(); contactArea1.AcceptButtonClick += new EventHandler(addContact); } Il ne reste plus qu ajouter les instructions la mthode addContact pour que celle-ci rcupre les informations contenues dans le contrle ContactArea et les ajoute la liste myContacts. Rien de bien difficile une fois de plus puisque nous avons cod le contrle ContactArea de manire ce que celui-ci puisse directement nous renvoyer un objet de type Contact contenant toutes ces informations. La mthode ressemble donc quelque chose du genre : private void addContact(object sender, EventArgs e) { myContacts.Add(contactArea1.Contact); //Sans oublier de nettoyer tous les champs du contrle contactArea1.Clear(); } Vous pouvez vrifiez, tout marche comme prvu, lvnement envoy depuis le contrle personnalis est bien intercept par le formulaire et les champs sont vids depuis ce dernier Passons la suite prsent

La suite
Ne perdez pas de temps, crez immdiatement les deux autres contrles personnaliss et occupez vous de leurs interfaces

Nommez les FriendsArea et PhotoArea. Traitons-les dans lordre logique du programme : commenons par le contrle FriendsArea. Rappelons-nous ce quil y a faire pour ce contrle : Lorsque lutilisateur appuie sur le bouton Rechercher, le ou les contacts dont les noms ou prnoms contiennent le texte marqu dans la TextBox de Nom/prnom sont ajouts la ComboBox. Si la TextBox de Nom/prnom est vide, tous les contacts sont ajouts dans la ListBox. Lorsquun contact est slectionn dans la ComboBox, les boutons Ajouter et Details deviennent cliquables. En cliquant sur Ajouter, le contact est ajout la liste des amis. Si un contact est slectionn dans la liste des amis, le bouton Details devient cliquable et la GroupBox Photo est active. Si le bouton Details est cliqu, la GroupBox Contact est remplie par les donnes du contact en question mais la GroupBox est dans un tat qui empche lutilisateur de modifier le contact. Pour entrer un nouveau contact, il faut absolument dslectionner (perte de focus) le contact en question. Commenons par la recherche Pour effectuer une recherche, deux possibilits : on la fait en interne, dans le User Control, ou dans le formulaire. Ces deux cas sont possibles et donnent un contrle utilisateur plus ou moins facile mettre en place et plus ou moins personnalisable depuis lextrieur du contrle. Nous allons la faire en interne pour simplifier Le problme, cest que le contrle na pas disposition la liste de contacts. Qu cela ne tienne, il suffit de la lui passer. Crez pour cela une proprit qui permet de dfinir la liste de contacts pour le contrle personnalis. Noubliez pas de crer le champ dans ce contrle au passage List<Contact> myList = new List<Contact>(); //Plus loin dans le code... public List<Contact> List { set { myList = value; } } Maintenant que nous avons la liste, nous navons plus qu lancer la recherche lorsque le bouton Rechercher est cliqu. Pas de double clic sur le bouton, on va faire autrement pour changer Slectionnez le bouton Rechercher puis allez dans linspecteur de proprits. Tout en haut de celui -ci, vous avez une icne en forme dclair Cliquez dessus pour basculer sur la liste des vnements du bouton Rechercher Soffre alors vous une grande liste des vnements du bouton Rechercher, tous accessibles en un clic ! Pour crer un vnement, nimporte lequel de cette liste, effectuez un double clic dans la case vide droite de lvnement que vous voulez crer. Une mthode est alors automatiquement cre dans le code. Cest donc aussi facile que le simple double clic sur le bouton pour crer un vnement Click, la diffrence quici vous avez beaucoup plus dvnements sous la main

Rendez vous dans la mthode associe au clic sur le bouton Rechercher. Il faut prsent effectuer la recherche dans cette mthode sans oublier que la liste na peut-tre pas t pass au contrle, peut-tre quelle vaut toujours null comboBoxResults.Items.Clear(); //Ajouter un lment neutre comboBoxResults.Items.Add(""); if (myList != null) { //Pour chaque contact de la liste... foreach (Contact c in myList) { /* ... si celui-ci a son nom ou prnom de tap dans la * TextBox de recherche... */ if(textBoxSearch.Text.ToLower().Contains(c.Name.ToLower())|| textBoxSearch.Text.ToLower().Contains(c.FirstName.ToLower())|| textBoxSearch.Text == "") { //... on l'ajoute la ComboBox comboBoxResults.Items.Add(c.Name + " " + c.FirstName); } } } Occupons nous maintenant de la ComboBox Lorsquun lment est slectionn, si cet lment nest pas llment neutre, on doit activer le bouton Ajouter et le bouton Details. Il faut pour cela dfinir lvnement SelectedIndexChanged (utilisez linspecteur de proprits comme montr prcdemment pour crer la mthode) et valider ou non la proprit Enabled des deux boutons cits. Remarque : Si vous effectuez un double clic sur la ComboBox, vous nallez non pas crer lvnement Click qui lui est associe mais crer lvnement SelectedIndexChanged qui est lvnement par dfaut de ce contrle (alors que pour un bouton, lvnement par dfaut est Click).
private void comboBoxResults_SelectedIndexChanged(object sender, EventArgs e) { bool activer = comboBoxResults.SelectedItem.ToString() == "" ? false : true; buttonAdd.Enabled = activer; buttonDetails.Enabled = activer; }

Rappel : Les codes suivants sont quivalents : <type> variable = condition ? valeur1 : valeur2; <type> variable; if (condition) variable = valeur1; else variable = valeur2; Pensez alors dsactiver par dfaut les deux boutons Ajouter et Details en passant par linspecteur de proprits et en rglant leurs proprits Enabled sur false (slectionnez les deux boutons pour aller plus vite). Occupons nous prsent du bouton Ajouter Lorsque lutilisateur clique sur ce bouton, il suffira dajouter le texte qui se trouve dans la ComboBox dans la liste et de modifier la proprit IsFriend du contact slectionn pour lui donner la valeur true. Noubliez pas quil faut galement vider la ComboBox (items et texte) et la TextBox ainsi que dsactiver les boutons Ajouter et Details

Remarques : Il est inutile de prvoir le cas dans le bouton Ajouter o la ComboBox sera slectionn sur llment neutre puisque cela narrivera jamais ! En effet, le bouton sera alors inactif et lvnement Click rendu inaccessible. Vu que lon ajoute que les noms et prnoms du contact dans la ComboBox, on na pas directement accs celui-ci et il va falloir effectuer une nouvelle recherche pour le retrouver et modifier sa proprit IsFriend. En fait, on pourrait se passer de cette recherche en sachant que les items de la ComboBox ne sont non pas de type string mais de type object ! On pourrait donc passer linstance de Contact toute entire lors de lajout de litem mais il y aurait des surcharges de mthodes faire (juste une en fait) pour que laffichage du contact soit bon. Nous verrons ce cas tout la fin de ce chapitre. Le mme problme sera rencontr par la suite pour rcuprer un contact de la ListBox : il faudra encore effectuer une recherche. En attendant la fin du chapitre, comme nous aurons besoin plusieurs fois dun code trs similaire dans diffrentes mthodes, nous allons coder une mthode prive gnrale permettant partir dun texte de la forme nom, espace, prnom de rcuprer le contact qui possde exactement les mmes noms et prnoms (le cas o plusieurs contacts auraient mmes noms et prnoms ne sera pas trait mais sera englob dans le code vu quon sarrtera au premier contact valide rencontr). Suffit pour les remarques, voici le code de la mthode gnrale de recherche prcise de contact : private Contact getContact(string description) { if (myList != null && description != null) foreach (Contact c in myList) if (c.Name + " " + c.FirstName == description) return c; return null; } Et voici le code excuter lorsque le bouton Ajouter est cliqu : listBoxFriends.Items.Add(comboBoxResults.SelectedItem.ToString()); Contact cct = getContact(comboBoxResults.SelectedItem.ToString()); cct.IsFriend = true; textBoxSearch.Text = ""; comboBoxResults.Items.Clear(); comboBoxResults.Text = ""; buttonAdd.Enabled = false; buttonDetails.Enabled = false; Occupons nous du bouton Details Ce bouton nest actif que si un contact est slectionn dans la ComboBox (, cest fait) ou dans la ListBox (pas fait). Petit dtour par la ListBox :
private void listBoxFriends_SelectedIndexChanged(object sender, EventArgs e) { buttonDetails.Enabled = listBoxFriends.SelectedItems.Count == 1 ? true : false; }

Profitez-en pour interdire la slection multiple dans la ListBox via la proprit SelectionMode ( rgler sur One bien entendu). Voyons maintenant ce bouton Details Lorsque celui-ci est cliqu, il doit dabord avertir le contrle parent quun contact doit tre affich et cest ensuite le formulaire principal qui a pour tche dafficher (comme il peut) le contact slectionn.

Nous avons donc besoin de deux choses, les mmes que pour le contrle prcdent : Une proprit retournant le contact slectionn Un vnement pour signaler que le bouton Details a t cliqu Comme prcdemment, dfinissez la proprit renvoyant le contact public Contact SelectedContact { get { string description = null; //Les amis d'abord if (listBoxFriends.SelectedItems == 1) description = listBoxFriends.SelectedItem.ToString(); //il y a forcment un lment de slectionn dans la ComboBox else description = comboBoxResults.SelectedItem.ToString(); //Dans tous les cas, on va appeler la mthode getContact... return getContact(description); //...qui renvoie directement un Contact } } puis lvnement personnalis List<Contact> myList = null; public event EventHandler DetailsButtonClick; reste dclencher lvnement au moment opportun private void buttonDetails_Click(object sender, EventArgs e) { if (DetailsButtonClick != null) DetailsButtonClick(sender, e); } et le contrle est alors prt tre ajout au formulaire principal. Mais nous allons encore le perfectionner

Les attributs
Mais que reste-t-il a perfectionner ? Eh bien comparons un peu notre contrle personnalis ceux fournis par dfaut, comme la TextBox par exemple Focalisons-nous surtout sur ce que notre contrle na pas, sur ce qui lui manque par rapport aux autres : Les proprits dfinies dans le code de notre contrle ne sont pas tries dans linspecteur de proprit de Visual Studio (mais elles sont prsentes mais dans la catgorie Misc), elles nont pas de valeurs par dfaut, de description De mme pour les vnements personnaliss. En faisant un double clic sur le contrle, une mthode associe lvnement Load serait cre alors que ce nest pas lvnement intressant de notre contrle. Il faudrait que cela soit lvnement DetailsButtonClick qui soit lvnement par dfaut. Il est impossible de donner des valeurs par dfaut au contrle, comme par exemple, remplir la ListBox des amis avec des contacts sans que lutilisateur clique sur le bouton Ajouter.

Tous ces dfauts peuvent tre bien sr corrigs en utilisant les attributs. Les attributs sont des sortes de balises que lon place entre crochets devant une proprit, un vnement, une classe, etc. Elles ne jouent aucun rle lors de lexcution du programme mais permettent de fournir des informations sur la classe ou la fonction lors de ldition ou de la compilation du programme. Nous aurons besoins de quelques attributs pour modifier notre contrle. Voici ceux que nous tudierons ici : BrowsableAttribute : spcifie si la proprit doit tre affiche ou non dans linspecteur de proprits. CategoryAttribute : attribue une catgorie la proprit ou lvnement (exemples de catgories : Design, Behavior, Data) DefaultEventAttribute : attribue lvnement par dfaut associe une classe DefaultValueAttribute : attribue une valeur par dfaut la proprit DescriptionAttribute : donne une description de la proprit ou de lvnement DesignerSerializationVisibilityAttribute : pour grer des collections dobjets Tous ces attributs se trouvent dans lespace de nom System.ComponentModel. Pensez donc vrifier que cet espace de nom est bien dclar dans votre code. Remarque : La suffixe Attribute est facultatif. Par exemple, vous pouvez utiliser lattribut de catgorie en tapant Category ou bien CategoryAttribute. Nous omettrons par la suite ce suffixe. Ajoutez le contrle FriendsArea au formulaire principal mais avant de faire quoi que ce soit dautre, retournez dans le code source de ce contrle personnalis. Occupons nous de lvnement DetailsButtonClick Nous voulons le placer dans la catgorie "Action" de linspecteur dvnements et lui donner la description suivante : "Occurs when the Details button is clicked.". Pour cela, rien de difficile, reprez la ligne o vous avez dclar lvnement en question et ajoutez lui les attributs suivants : [Category("Action")] [Description("Occurs when the Details button is clicked.")] Vous pouvez galement mettre tous les attributs dans un mme crochet en les sparant par des virgules : [Category("Action"), Description("Occurs when...")] Cela donne donc pour notre vnement : [Category("Action")] [Description("Occurs when the Details button is clicked.")] public event EventHandler DetailsButtonClick; Vrifiez ! Si vous retournez prsent sur le formulaire principal, que vous slectionnez le contrle FriendsArea et que vous allez dans la zone des vnements de linspecteur de proprits, vous pourrez voir dans la catgorie Action votre vnement avec la description souhaite Nous voulons galement que cet vnement soit lvnement par dfaut du contrle. Pour ce faire, placez lattribut DefaultEvent devant la classe du contrle en prcisant le nom de lvnement par dfaut :

[DefaultEvent("DetailsButtonClick")] public partial class FriendsArea : UserControl Reconstruisez le projet et vrifiez : le double clic sur le contrle FriendsArea cre prsent la mthode associe lvnement DetailsButtonClick. Nous voulons aussi quil soit possible dajouter depuis linspecteur de proprits une liste damis. Vu que les amis sont forcment parmi les contacts, il faut que lon puisse ajouter des contacts (nom, prnom, adresse) et prciser si ceux-ci sont des amis ou pas Nous avons dj cod une proprit permettant dtablir la liste des contacts dans le contrle : public List<Contact> List { set { myList = value; } } Mais il savre que cette dfinition est doublement insuffisante. En effet, si on ajoute une liste de contacts qui contient des amis en passant par cette proprit, la liste ne sera pas filtre et les amis ne seront pas affichs dans la ListBox. Il faut donc effectuer une premire modification : public List<Contact> List { set { myList = value; foreach (Contact c in myList) if (c.IsFriend) listBoxFriends.Items.Add(c.Name + " " + c.FirstName); } } Maintenant que les amis sont ajouts la ListBox, il faut pouvoir afficher cette proprit dans linspecteur de proprits. Mais pas daffichage si la proprit ne peut pas tre lu (logique). Il faut donc ajouter un accesseur get cette proprit. Ajoutons au passage une petite description et classons la dans une catgorie. [Category("Data")] [Description("The contacts in the list")] public List<Contact> List { get { return myList; } set { myList = value; foreach (Contact c in myList) if (c.IsFriend) listBoxFriends.Items.Add(c.Name + " " + c.FirstName); } }

Reconstruisez le projet et allez voir dans la catgorie Data du contrle FriendsArea qui se trouve sur le formulaire principal.

Attention : Pour pouvoir ajouter des lments dans une collection, il faut imprativement que le mot (Collection) soit inscrit dans la case droite sinon, cela signifie que votre collection est null et vous narriverez rien y mettre ! Cliquez sur le petit bouton qui apparait dans la partie droite Une fentre souvre et vous propose dajouter des lments la liste de contacts. Super ! Cliquez sur le bouton Ajouter et Visual Studio vous crache un message la figure . Le message est trs clair : le constructeur de notre classe Contact na pas t trouv. Pourtant il existe, mais uniquement avec des paramtres. Visual Studio a besoin d un constructeur sans paramtre pour pouvoir crer un objet via nimporte quelle interface. Il suffit donc dajouter notre classe Contact un constructeur sans paramtre : public Contact() { } Et maintenant marche ! Vous pouvez ajouter autant de contacts que vous le voulez. A chaque contact ajout, vous pouvez dfinir chacune des proprits du contact enfin presque celles-ci sont en effet grises, impossible de modifier ces proprits. Et cest parfaitement normal puisque celles-ci sont en lecture seule. public string Name { get { return name; } } Modifiez les toutes de manire ce quelles puissent dfinir chacun des champs de la classe Contact. public string Name { get { return name; } set { name = value; } } Mais ce nest toujours pas fini (cela serait-il donc sans fin ?) car si vous tentez dajouter un Contact maintenant, vous aurez une insulte dun nouveau genre :

Et pour rsoudre ce dernier problme, il faut, comme indiqu, marquer la classe Contact avec lattribut Serializable.

[Serializable] public class Contact Ajoutez prsent un ami cette fameuse liste, qui nous a pos tant de problmes jusqu e l (ce nest malheureusement pas fini). Reconstruisez le projet et boum ! Une nouvelle erreur :

Apparemment lditeur naime pas convertir des listes de contact en tableau de contacts et vice-versa. On va donc se simplifier le travail et demander notre proprit List de ne renvoyer quun tableau plutt quune liste. [Category("Data")] [Description("The contacts in the list")] public Contact[] List { get { return myList.ToArray(); } set { myList = new List<Contact>(value); foreach (Contact c in myList) if (c.IsFriend) listBoxFriends.Items.Add(c.Name + " " + c.FirstName); } } Reconstruisez le projet et corrigez les erreurs et les avertissements en supprimant le code problmatique. Ici le code qui pose problme est li au fichier ressource du formulaire principal. Allez dans le fichier MainForm.Designer.cs et supprimez donc la ligne : this.friendsArea1.List = ((System.Collections.Generic.List<Chapi Allez galement dans le fichier ressource MainForm.resx et supprimez la ressource ayant un lien avec le contrle FriendsArea.

A prsent, la reconstruction du projet fonctionne correctement et vous pouvez ajouter un ami votre liste damis sans que la formulaire principal ne parte en vrille Ajoutez donc un ami (pas seulement un contact : un ami !) la liste des contacts depuis linspecteur de proprits. Lami est bien ajout dans la liste mais vous ne le voyez pas safficher dans la ListBox comme il devrait le faire lorsque le programme est excut. On peut faire cela en ajoutant encore un attribut (encore un) devant la proprit List : il sagit de DesignerSerializationVisibility [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]

Si vous retournez maintenant sur le formulaire principal, vous pouvez voir que votre ami (ou vos amis si vous en avez mis plusieurs dans la liste) saffiche dans la ListBox.

Finalement notre proprit ressemble quelque chose du genre : [Category("Data")] [Description("The contacts in the list")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Contact[] List { get { return myList.ToArray(); } set { myList = new List<Contact>(value); foreach (Contact c in myList) if (c.IsFriend) listBoxFriends.Items.Add(c.Name + " " + c.FirstName); } } Voyons au passage comment utiliser les attributs DefaultValue et Browsable. Nous allons ajouter ces attributs aux proprits de notre classe Contact et voir ce quils font. Par exemple, modifiez les proprits suivantes [DefaultValue(false)] public bool IsFriend { get { return isFriend; } set { isFriend = value; } }

[DefaultValue(null)] [Browsable(false)] public byte[] Photo { get { return photo; } set { photo = value; } } et retournez dans la proprit List du contrle FriendsArea via linspecteur de proprit. Ajoutez un contact et regardez bien :

Vous constaterez deux choses : la proprit Photo a disparu et la valeur par dfaut de la proprit est affiche sans gras alors que si lon modifie cette valeur et que celle -ci nest pas celle tablit par dfaut, elle saffiche en gras. Outre laspect esthtique, dfinir des valeurs par dfaut permet de rduire le code car le s valeurs par dfaut ne sont pas redfinies dans le code gnr automatiquement avec lditeur Ajoutez galement des attributs DefaultValue aux autres proprits de la classe Contact Voila pour les attributs, nous avons fait le tour des principaux Finissez-en avec le contrle FriendsArea en traitant son vnement par dfaut dans le formulaire principal private void friendsArea1_DetailsButtonClick(object sender, EventArgs e) { contactArea1.Contact = friendsArea1.SelectedContact; } et noubliez pas quil faut que la liste de contact du formulaire principal soit en permanence dans le contrle FriendsArea //Dans le constructeur de MainForm friendsArea1.DynList = myContacts; //Dans la classe FriendsArea [Browsable(false)] public List<Contact> DynList { set { myList = value; } } Testez votre application !

Fin
Occupez vous maintenant du dernier contrle : PhotoArea. Rien de difficile ici, au clic sur un bouton, vous ouvrez une OpenFileDialog, rcuprez limage, la stockez dans la proprit Photo du Contact sous forme binaire et vice-versa. Le code du bouton Modifier nest donc gure compliqu, il suffit de savoir un petit peu utiliser une OpenFileDialog - que nous traiterons ici en code, mme sil est possible de la crer avec le Designer (essayez ensuite avec le Designer) - et comment transformer une image Image en un tableau de bytes (il faut passer par la classe MemoryStream de lespace System.IO). Le code donne alors quelque chose du genre : /* Il faut que le contact existe, sinon la suite n'a pas besoin * d'tre excute. */ if (currentContact != null) { //Cration de l'OpenFileDialog OpenFileDialog ofd = new OpenFileDialog(); //On rcupre le chemin des "Mes Documents" string myDocs = Environment.GetFolderPath( Environment.SpecialFolder.MyDocuments); //On configure l'OpenFileDialog ofd.Title = "Choisissez une image"; ofd.Multiselect = false; ofd.InitialDirectory = myDocs; ofd.Filter = "Fichiers JPEG(*.jpg,*.jpeg) | *.jpeg;*.jpg"; /* On affiche l'OpenFileDialog et on attend que l'utilisateur * appuie sur OK. */ if (ofd.ShowDialog() == DialogResult.OK) { /* On vrifie que l'utilisateur bien choisi un fichier * existant. */ if (System.IO.File.Exists(ofd.FileName)) { /* On rcupre le chemin de ce fichier et on demande * la PictureBox d'en afficher l'image. */ pictureBox.Image = Image.FromFile(ofd.FileName); /* On cre une zone tampon en mmoire pour contenir les * donnes binaires du fichier image... */ System.IO.MemoryStream ms = new System.IO.MemoryStream(); /* ... que l'on rcupre via la PictureBox... */ pictureBox.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); /* ... et qu'on stocke finalement sous forme binaire dans * la proprit Photo du contact actuel. */ currentContact.Photo = ms.ToArray(); } else { /* Si le fichier n'existe pas, on informe l'utilisateur * du problme. */ MessageBox.Show("Le fichier spcifi n'existe pas", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }

Remarque : Noubliez pas de crer le champ currentContact et sa proprit associe. La proprit devant grer des images cadeau ! [Browsable(false)] public Contact Contact { get { return currentContact; } set { currentContact = value; /* Ne pas oublier de traiter l'affichage automatique * des images. */ if (currentContact != null && currentContact.Photo != null) { //On rcupre les donnes binaire de la classe Contact System.IO.MemoryStream ms = new System.IO.MemoryStream( currentContact.Photo); /* La classe Bitmap a un constructeur prenant une Stream * en paramtre, profitons en ! */ pictureBox.Image = new Bitmap(ms); } else { /* Si le contact n'a pas d'image, on en met une vide * la place. */ pictureBox.Image = new Bitmap(10, 10); } } } Remarque : Limage pouvant tre absolument nimporte quoi et de toutes dimensions, rglez la proprit SizeMode de la PictureBox sur Zoom. Cela redimensionnera limage afficher de manire ce que ses dimensions restent proportionnelles et infrieures celles de la PictureBox. Ajoutez ensuite ce contrle au formulaire principal Tout va bien. Maintenant, il faut ajouter le code dans le formulaire principal pour passer le Contact en question PhotoArea lorsquun lment de la ListBox est slectionn Nous avons dj la proprit SelectedContact dans la classe FriendsArea mais nous ne savons pas dans le formulaire principal quand un lment est slectionn dans la ListBox Il nous manque en effet un vnement dans le contrle FriendsArea : //Il faut ajouter cet vnement personnalis... [Category("Action")] [Description("Occurs when a Contact is selected in the ListBox.")] public event EventHandler SelectedContactInBoxChanged; private void listBoxFriends_SelectedIndexChanged(object sender, EventArgs e) { // [...] //... et cet "appel"... if (SelectedContactInBoxChanged != null) SelectedContactInBoxChanged(sender, e); }

On peut prsent traiter cet vnement depuis le formulaire principal.


private void friendsArea1_SelectedContactInBoxChanged(object sender, EventArgs e) { photoArea1.Contact = friendsArea1.SelectedContact; }

Aurions-nous enfin termin ? Presque, il reste activer et dsactiver les diffrentes GroupBox aux bons moments Tout cela se gre bien sr dans le formulaire principal. Initialement, la liste tant vide, il faut que les GroupBox Mes amis et Photo soient inactives. Rglez donc la proprit Enabled des contrles FriendsArea et PhotoArea sur False depuis linspecteur de proprit. Le reste se passe dans le code private void addContact(object sender, EventArgs e) { myContacts.Add(contactArea1.Contact); //Un contact a t ajout, on peut activer FriendsAtrea friendsArea1.Enabled = true; //Sans oublier de nettoyer tous les champs du contrle contactArea1.Clear(); } private void friendsArea1_DetailsButtonClick(object sender, EventArgs e) { //Des dtails sont demands, on dsative ContactArea contactArea1.Enabled = false; contactArea1.Contact = friendsArea1.SelectedContact; } private void friendsArea1_SelectedContactInBoxChanged(object sender, EventArgs e) { /* Un lment a t slectionn dans la ListBox, * il faut activer la zone de photo. */ photoArea1.Enabled = true; photoArea1.Contact = friendsArea1.SelectedContact; } Mais il manque encore la ractivation de la zone Contact lorsque la ListBox perd le focus. Il va donc falloir ajouter un vnement dans le contrle FriendsArea qui signale au formulaire que la ListBox a perdu le focus Et bien allons-y : //L'vnement personnalis... [Category("Focus")] [Description("Occurs when the ListBox is no longer the active control of the form.")] public event EventHandler LeaveBox; //L'vnement Leave de la ListBox private void listBoxFriends_Leave(object sender, EventArgs e) { if (LeaveBox != null) LeaveBox(sender, e); }

Et ensuite, dans le formulaire principal : private void friendsArea1_LeaveBox(object sender, EventArgs e) { //... on vide la zone contact et on la ractive ... contactArea1.Clear(); contactArea1.Enabled = true; }

Ne pas oublier galement que les dtails du contact peuvent tre affichs pour un contact appartenant la ComboBox. Nous appellerons donc lvnement LeaveBox dans la mthode traitant lvnement SelectedIndexChanged de la ComboBox ainsi que sur le clic du bouton Ajouter Aprs cela, lapplication est termine, vous pouvez la tester totalement. Remarque : Cependant, certaines erreurs nont pas t anticipes. Essayez donc de les corriger.

Pour aller plus loin


Vous souvenez vous de cette remarque ? Remarque : [] Vu que lon ajoute que les noms et prnoms du contact dans la ComboBox, on na pas directement accs celui-ci et il va falloir effectuer une nouvelle recherche pour le retrouver et modifier sa proprit IsFriend. En fait, on pourrait se passer de cette recherche en sachant que les items de la ComboBox ne sont non pas de type string mais de type object ! On pourrait donc passer linstance de Contact toute entire lors de lajout de litem mais il y aurait des surcharges de mthodes faire (juste une en fait) pour que laffichage du contact soit bon. Nous verrons ce cas tout la fin de ce chapitre. Le mme problme sera rencontr par la suite pour rcuprer un contact de la ListBox : il faudra encore effectuer une recherche. Nous voici la fin du chapitre et nous allons voir, rapidement, comment nous aurions pu faire autrement et nous passer ainsi de cette mthode de recherche ListBox et ComboBox prennent dans leur liste ditems des objets. Toutes les classes tant des objets, nous pouvons directement passer notre Contact la liste ditems de la ComboBox et de la ListBox. private void buttonSearch_Click(object sender, EventArgs e) { comboBoxResults.Items.Clear(); /* [...] */ //Dans la condition de la boucle... /* Version "Pour aller plus loin" */ comboBoxResults.Items.Add(c); //On ajoute ici TOUT le contact la ComboBox /* [...] */ } De mme au moment de lajout dans la ListBox.

private void buttonAdd_Click(object sender, EventArgs e) { /* Version "Pour aller plus loin" */ Contact cct = (Contact)comboBoxResults.SelectedItem; cct.IsFriend = true; listBoxFriends.Items.Add(cct); //On ajoute ici TOUT le contact la ListBox /* [...] */ } La mthode getContact devient alors inutile et la proprit SelectedContact est simplifie : public Contact SelectedContact { get { /* Version "Pour aller plus loin" */ if (listBoxFriends.SelectedItems.Count == 1) return (Contact)listBoxFriends.SelectedItem; //else return (Contact)comboBoxResults.SelectedItem; } } Mais il y a un nouveau problme. En effet, si vous excutez votre application avec ce nouveau code, vous ne verrez pas, ni dans la ListBox ni dans la ComboBox, dcrit le nom du contact suivi de son prnom mais un texte incomprhensible Cest normal car vous navez fait que passer une classe vos ListBox et ComboBox. Ces contrles utilisent, pour afficher des objets sous forme de texte, la mthode ToString() : ils appellent pour chaque objet la mthode ToString() et affichent la chane renvoye par la mthode. Etant donn que notre classe Contact na pas sa propre mthode ToString(), cest la mthod e par dfaut qui est appele par nos ListBox et ComboBox et cette mthode renvoie laffichage que vous avez pu voir. Pour rsoudre ce problme, il suffit simplement de surcharger la mthode ToString() : de la rcrire dans notre classe Contact pour quelle renvoie un affichage nous convenant. Dans la classe Contact, vous devrez donc ajouter public override string ToString() { return Name + " " + FirstName; } A prsent tout fonctionne convenablement. Cette dernire technique est largement prfrable la premire (qui consistait reffectuer une recherche de contact chaque fois) et sera privilgie dans ce type dapplication. Cela ne veut pas dire quil faut passer chaque fois un objet vos ComboBox, ListBox ou autre, mais simplement que si cela sy prte bien (simplifie le code, augmente la vitesse dexcution, etc.).

Chapitre 5 Multifentres, suite

Maintenant que nous avons vu, massivement, comment crer ses propres vnements, que vous commencez devenir un virtuose de la proprit un tel point que vous en mettez de partout et que les interfaces un peu complexes grer ne vous font plus peur, nous allons pouvoir revenir sur les applications multifentres et voir comment grer les communications entre formulaires enfants.

Application

Crez et remplissez les quatre formulaires. Modifiez-en les noms Nous nommerons ici : dans FORM MERE : la ListBox : "listBox" le bouton FF1 : "buttonFF1" le bouton FF2 : "buttonFF2" le bouton FF3 : "buttonFF3" dans FF1 : la TextBox : "textBoxFF1" le bouton Vider : "buttonVider1" le bouton >> FF3 : "buttonFF13" le bouton >> FF2 : "buttonFF12" dans FF2 : le bouton Transfrer : "buttonTransfert" dans FF3 : la TextBox : "textBoxFF3" le bouton Vider : "buttonVider1" le bouton >> FF1 : "buttonFF31" le bouton >> FF2 : "buttonFF32"

Les trois formulaires enfants ont les proprits suivantes en commun : MinimizeBox sur False MaximizeBox sur False StartPosition sur CenterParent FormBorderStyle sur Fixed3D TopMost sur True A chaque fois quun bouton est cliqu, lvnement est signal dans la ListBox. Quand du texte est modifi, quand le formulaire est affich, ferm, activ, dsactiv, lvnement est signal dans la ListBox. Il va donc y avoir beaucoup dvnement traiter ici. Lorsque le bouton >> FF2 est cliqu, le texte de la TextBox du formulaire est transmis au formulaire FF2. On attend alors que lutilisateur clique sur lunique bouton de FF2 pour que le transfert se termine et que le texte passe dans le formulaire oppos au formulaire dorigine Commencez par crer tous les vnements Click de tous les boutons et occupez vous du code ncessaire louverture des formulaires enfants depuis FORM MERE (un clic sur FF1 ouvre le formulaire FF1, un clic sur ). Remarque : Utilisez ici la mthode Show() pour affichez les formulaires enfants. En effet, si vous utilisez ShowDialog(), vous ne pourrez plus accder au formulaire principal pour ouvrir les autres formulaires enfants et ne pourrez donc jamais avoir plus dun formulaire enfant affich sim ultanment. Nous allons nous occuper tout de suite des vnements directement accessibles depuis le formulaire parent. Ce sont les vnements standards des formulaires enfants : Activated Deactivate Shown FormClosed Pour allger le code, nous utiliserons les mthodes anonymes de C# 2.0. ff1.Activated += delegate(object sender, EventArgs e) { listBox.Items.Add("FF1 est active."); }; Remarque : Si vous tes encore sous C# 1.1, cest pareil, sauf que vous crez une mthode pour chaque nouvel vnement et placez le code ajoutant du texte la ListBox en son sein. Utiliser les mthodes anonymes va nous permettre ici de nous passer de plus dune vingtaine mthodes (nommes). Ci-dessous, le code traitant lun des formulaires enfant, placer dans le constructeur du formulaire principal : public MainForm() { InitializeComponent(); //Les vnements associs ff1 ff1.Activated += delegate(object sender, EventArgs e) { listBox.Items.Add("FF1 est active."); };

ff1.Deactivate += delegate(object sender, EventArgs e) { listBox.Items.Add("FF1 est dsactive."); }; ff1.Shown += delegate(object sender, EventArgs e) { listBox.Items.Add("Affichage de FF1."); }; ff1.FormClosed += delegate(object sender, FormClosedEventArgs e) { listBox.Items.Add("Fermeture de FF1."); }; //... } Remarque : Pensez crer les instances des formulaires enfants Le code traitant les autres formulaires est du mme genre Nous allons ensuite avoir besoin dinformations sur les contrles que contiennent nos formulaires enfants. Pour cela, vous devez savoir prsent quil est ncessaire de crer nos vnements personnaliss Dans le formulaire FF1, nous aurons donc besoin dun vnement personnalis par contrle (puisque nous nallons traiter quun seul des vnements de ces contrles). public public public public event event event event EventHandler EventHandler EventHandler EventHandler TextInBoxChanged; ButtonViderClick; ButtonFF2Click; ButtonFF3Click;

Vous ne devriez pas avoir de mal ensuite appeler ces vnements aux bons moments Nous allons ensuite avoir besoin de rcuprer le texte qui se trouve dans la TextBox. A cela, vous devez rpondre : Proprit ! Il faut crire une proprit qui renvoie ou modifie ce texte. [DefaultValue("")] public string TextInBox { get { return textBoxFF1.Text; } set { textBoxFF1.Text = value; } } Le formulaire enfant FF3 se traite de la mme manire Pour le formulaire FF2, cest encore plus simple vu quil ny a quun seul bouton : public event EventHandler ButtonTransfertClick; /* [...] */ private void buttonTransfert_Click(object sender, EventArgs e) { if (ButtonTransfertClick != null) ButtonTransfertClick(sender, e); }

On peut alors ajouter dans le formulaire principal, encore une fois en utilisant les mthodes anonymes, le code affichant dans la ListBox quand le bouton Vider est cliqu, quand le texte dune des TextBox change Par exemple, pour le changement de texte ff1.TextInBoxChanged += delegate(object sender, EventArgs e) { listBox.Items.Add("Le texte dans FF1 a t modifi : " + ff1.TextInBox); }; Fates de mme pour tous les autres vnements restant traiter Nous allons voir prsent comment organiser les transferts de donnes. Deux possibilits se prsentent : la TextBox nest pas vide lorsquon clique sur lun des boutons de transfert la TextBox est vide depuis le formulaire enfant lorsquun des boutons de transfert est cliqu Nous allons tudier ici ces deux cas.

Premier cas
Le premier cas se traite assez rapideme nt Pour les transferts seffectuant directement de FF1 FF3, il suffit de modifier certains des vnements dj utiliss : ff1.ButtonFF3Click += delegate(object sender, EventArgs e) { listBox.Items.Add("Le bouton >> FF3 a t cliqu."); ff3.TextInBox = ff1.TextInBox; }; De mme pour lopration inverse : ff3.ButtonFF1Click += delegate(object sender, EventArgs e) { listBox.Items.Add("Le bouton << FF1 a t cliqu."); ff1.TextInBox = ff3.TextInBox; }; Ltape intermdiaire (le passage par le formulaire FF2) demande un peu plus de rflexion car il faut tenir compte du sens et de lunicit du transfert (celui-ci ne peut avoir lieu quune fois et cliquer plusieurs fois sur le bouton Transfrer ne devra rien faire une fois la premire passe). Mais cela reste assez simple tout de mme. Nous avons besoin de connatre sur le formulaire FF2 la provenance du transfert : est-ce le bouton << FF2 ou le bouton >> FF2 qui a t cliqu ? Pour cela, on peut par exemple stocker linformation dans une numration. Commenons par la crer ajoutez la dans votre programme au mme rang quune classe

public enum ComingFrom { None, FF1, FF3 } Dfinissons-la ensuite dans notre formulaire principal ( ajouter parmi les champs) : ComingFrom from = ComingFrom.None; Il ne reste plus qu sen servir aux bons endroits ff1.ButtonFF2Click += delegate(object sender, EventArgs e) { listBox.Items.Add("Le bouton >> FF2 a t cliqu."); from = ComingFrom.FF1; }; //... plus loin... ff3.ButtonFF2Click += delegate(object sender, EventArgs e) { listBox.Items.Add("Le bouton << FF2 a t cliqu."); from = ComingFrom.FF3; }; //... plus loin... ff2.ButtonTransfertClick += delegate(object sender, EventArgs e) { listBox.Items.Add("Le bouton Transfert a t cliqu."); if (from == ComingFrom.FF1) ff3.TextInBox = ff1.TextInBox; else if (from == ComingFrom.FF3) ff1.TextInBox = ff3.TextInBox; //Le transfert est unique... from = ComingFrom.None; }; Voila, cest tout ce quil y a faire dans ce cas l Passons au second cas qui va nous demander un peu plus defforts.

Second cas
Dans ce cas ci, nous devons nettoyer les TextBox ds quun des boutons de transfert est cliqu private void buttonFF13_Click(object sender, EventArgs e) { if (ButtonFF3Click != null) ButtonFF3Click(sender, e); textBoxFF1.Text = ""; } Fates de mme pour les autres vnements La proprit TextInBox va donc rarement servir pour extraire le texte de la TextBox et il va falloir trouver un autre moyen de conserver le texte.

Et le seul moyen qui semble se prsenter, cest dajouter de faire passer la chane de caractres dans lvnement aprs, cest trop tard ! Il va donc falloir crer de nouveaux types dvnements, qui nexistent pas encore. Fini les EventHandler traditionnels, nous de crer notre propre Handler. Pour cela, on a encore deux choix : soit on cre un Handler comme le EventHandler mais avec un troisime paramtre de type string. soit on cre un Handler dune forme un peu plus standard qui ne prend que deux paramtres. Nous allons coder ici la deuxime possibilit, qui, dune certaine manire, englobe la premire Revoyons un peu les paramtres que demandait le EventHandler. Il fallait : un premier paramtre de type object un second de type EventArgs A quoi correspondaient donc ces paramtres ? Le premier, lobject, que nous nommions sender, contenait en fait lobjet metteur de lvnement. Par exemple, lvnement Click dun bouton contient dans son sender, le bouton lui-mme mais sous forme dun objet. Remarque : Pour rcuprer le contrle contenu dans le sender, il suffit de faire un transtypage. Le second paramtre, de type EventArgs, est celui qui va nous intresser davantage. Bien que EventArgs en lui-mme nait pas beaucoup dintrt (car il ne contient auc une mthode, proprit de plus que la classe Object), les autres classes qui sy apparentes commencent tre intressantes. Par exemple, la classe MouseEventArgs, utilise pour les vnements du style MouseClick, MouseDown ou autre, fournit des informations intressantes sur ltat de la souris lorsque lvnement est survenu. De nouvelles proprits apparaissent dans cette classe : Button Clicks Delta Location X Y Nous pourrions donc en faire autant avec notre propre EventArgs. Commenons donc par crire notre propre EventArgs : il sagit dcrire une classe, dont le nom se terminerait, par convention, par EventArgs, et hritant de la classe de base EventArgs. Cette classe doit tre capable de stocker notre chane de caractres et devra donc comporter un champ de type string et une proprit renvoyant sa valeur. La classe ressemblera donc quelque chose du genre : /* On cre notre classe et on la fait hriter de * EventArgs (avec les deux points). */ public class StringTransfertEventArgs : EventArgs { //Notre champs pour stocker la chaine private string chaine;

//Un constructeur par dfaut public StringTransfertEventArgs() : this(String.Empty) /* On appele ici le * constructeur ci* dessous. */ { } /* Un autre qui permet de donner une chane * notre classe StringTransfertEventArgs. */ public StringTransfertEventArgs(string chaine) : base() /* On appelle ici le constructeur * de la classe dont on hrite : * on appele donc le constructeur * de la classe EventArgs. */ { this.chaine = chaine; } //La proprit qui renvoie la chaine public string Chaine { get { return chaine; } /* Pas d'accesseur set, nous ne voulons * pas que quelqu'un d'autre part nous * puisse modifier la valeur de la chaine : * cela ne voudrait plus rien dire si celle-ci * peut tre modifie n'importe quand... */ } } Remarques : Pensez crer un fichier spcialement pour cette classe (et nommez le comme la classe). Limplmentation de la classe est ici intgralement traite, avec la prsence des deux constructeurs et de la proprit accessible uniquement en lecture seule. String.Empty est quivalent "" Maintenant, nous aimerions bien que nos vnements personnaliss sur nos boutons >> FF2 et >> FF3 ressemble ceci public event StringTransfertEventHandler ButtonFF2Click; public event StringTransfertEventHandler ButtonFF3Click; o le nouvel Handler en question prendrait en paramtre un type object et un type StringTransfertEventArgs. Mais ce Handler nexiste pas encore Si vous avez bonne mmoire et que vous lisez attentivement, vous vous rappellerez peut-tre quil tait crit quelque part que EventHandler tait en fait un dlgu : un pointeur de mthode . Nous devons donc crer un dlgu qui, comme EventHandler, ne renverra rien mais devra prendre deux arguments en paramtre (lobject et le StringTransfertEventArgs). En voici la dclaration, que vous placerez dans votre code au mme rang quune classe.. . public delegate void StringTransfertEventHandler( object sender, StringTransfertEventArgs e );

Modifiez ensuite les deux vnements ButtonFF2Click et ButtonFF3Click comme indiqu ci-dessus. Ce qui entraine quil va falloir modifier nos appels sur ces vnements et crer un objet StringTransfertEventArgs private void buttonFF13_Click(object sender, EventArgs e) { if (ButtonFF3Click != null) ButtonFF3Click( sender, /* On cre un objet StringTransfertEventArgs et on lui /* passe (via son constructeur) le texte de la TextBox...*/ new StringTransfertEventArgs(textBoxFF1.Text) ); textBoxFF1.Text = ""; } Modifiez de mme les autres vnements similaires dans les formulaires FF1 et FF3 Vous allez galement devoir effectuez quelques petites modifications dans le formulaire principal. Si vous ne voyez pas lesquelles, recompilez et consultez la liste derreurs La suite est trs semblable au premier cas //champs ComingFrom from = ComingFrom.None; string temp = String.Empty; //... un peu plus loin... ff1.ButtonFF2Click += delegate(object sender, StringTransfertEventArgs e) { listBox.Items.Add("Le bouton >> FF2 a t cliqu."); temp = e.Chaine; //Stockage temporaire de la chane (sinon on la perd) from = ComingFrom.FF1; }; ff1.ButtonFF3Click += delegate(object sender, StringTransfertEventArgs e) { listBox.Items.Add("Le bouton >> FF3 a t cliqu."); ff3.TextInBox = e.Chaine; //On rcupre dsormais la chaine via e /* Premier cas */ //ff3.TextInBox = ff1.TextInBox; }; et surtout ff2.ButtonTransfertClick += delegate(object sender, EventArgs e) { listBox.Items.Add("Le bouton Transfert a t cliqu."); if (from == ComingFrom.FF1) ff3.TextInBox = temp; else if (from == ComingFrom.FF3) ff1.TextInBox = temp; /* La suite peut varier selon le comportement que l'on veut * avoir pour le bouton Transfrer... */ temp = String.Empty; //Facultatif puisqu'on a la suivante... //Le transfert est unique... from = ComingFrom.None; };

Remarque : A propos de lnumration ComingFrom. Celle-ci ne servant que dans la classe du formulaire principal, vous pouvez, si vous voulez que celle-ci soit rendue inaccessible aux autres classes de votre programme, lajouter la classe MainForm plutt qu lespace de nom de votre application public partial class MainForm : Form { FF1 ff1 = new FF1(); FF2 ff2 = new FF2(); FF3 ff3 = new FF3(); ComingFrom from = ComingFrom.None; string temp = String.Empty; protected enum ComingFrom { None, FF1, FF3 } Voila, cest termin Testez lapplication et vrifiez de ne rien avoir oubli (en la testant dans tous les sens possibles et imaginables)

Chapitre 6 A vous de jouer

Dans ce chapitre, fini les corrections et laide permanente, vous de vous dbrouiller tout seul enfin presque.

Help me !
Pas de panique, vous ntes fort heureusement pas seul dans votre tche. Vous avez, entre autres, pour vous aider : Microsoft Developper Network qui liste lintgralit des classes de C# dans sa library en fournissant des exemples dans la plupart des cas. MSDN est la fois disponible en local (installation avec Visual C#) et sur internet. Les nombreux forums de programmation que vous pourrez trouver sur internet et notamment le site de Moteurprog. Cependant, si vous tes un peu dgourdit et patient (cest l gnralement que cest le plus difficile), MSDN vous fournit toutes les informations ncessaires pour que votre application puisse aboutir. A noter cependant que laide MSDN ne fournit pas dexemples directs dutilisation pratique de Visual Studio pour tel ou tel contrle (vous avez le texte mais pas les images). Tout est donn en code. Aprs, cest vous de faire le lien entre les lments du code et linspecteur de proprits.

Exemple : La TreeView
Vous ne vous tes jamais servi dune TreeView et vous voulez savoir comment faire. Plutt que de crier immdiatement sur tous les toits que vous avez besoin daide, commencez par mener votre petite enqute, voire si vous ne pourriez pas vous en sortir tout seul. Cest la fois gratifiant et instructif. Pour cela, commencez par ajouter la TreeView votre application via le Designer. Et voyez si vous avez vraiment besoin de MSDN pour linstant

Essayez diffrentes proprits qui se trouvent dans linspecteur de proprits pour voir ce quelles font Vous devriez arriver assez facilement ainsi crer un arbre dans ce style :

Mais cela ne vous suffit pas, vous voulez que votre arbre ragisse aux entres utilisateurs, que votre arbre volue pendant que votre application sexcute Il va donc falloir obligatoirement passer par le code et cest l que MSDN va surement devenir trs utile. En effet, mme si vous avez disposition toutes les mthodes de la TreeView, vous aurez certainement du mal, si vous ntes pas habitu utiliser le contrle, de passer par MSDN pour obtenir quelques informations quant la faon de sen servir. Effectuez donc une recherche sur la TreeView dans MSDN (local ou en ligne) Vous devriez trouver entre autres : TreeView, classe TreeView, membres TreeNode, classe

Dernires informations
Il se peut que vous ayez besoin pour votre application dajouter des composants externes, non inclus dans le .NET Framework la base. Cest tout fait possible bien sr mais il y a deux cas distinguer : Le composant a t fait dans un langage non .NET mais utilise la technologie COM pour tre exploitable sous .NET. Dans ce cas, il suffit dajouter la rfrence de lapplication depuis longlet COM Le composant a t fait pour .NET et se trouve dans une DLL, un fichier OCX ou autre... Dans ce cas, pas de problme, ajoutez votre fichier DLL au projet (pensez galement ajouter la DLL dans le rpertoire o lexcutable est compil). Dans tous les cas, vous devez passer par lexplorateur de solution :

Si vous voulez ajouter plus particulirement des contrles (externes), quils soient .NET ou non Vous pouvez ajouter des contrles votre Toolbox en y faisant un clic droit Choose Items. Des fentres semblables aux prcdentes saffichent alors et vous pouvez choisir le contrle que vous voulez ajouter la Toolbox

Si vous avez besoin dun composant non fourni par dfaut avec le .NET Framework, effectuez une recherche sur internet. Certains sites proposent des lots de composants (gnralement payant), dautres le composant qui vous intresse seul (gratuit ou payant).

A vous de jouer
Ci-aprs, une srie dexercices, classs par difficult croissante, qui vous fera progresser petit petit. Plus vous avancerez dans les exercices, plus vous aurez de code manipuler. Exercice 1 : Solo Messenger

Comportement : Vous tapez du texte dans le contrle 1 et en cliquant sur le contrle 2, le texte est ajout au contrle 3 avec en plus marqu devant : "Jai dit : ". Le texte du contrle 1 est alors automatiquement effac. Conseil : Rien de plus, rien de moins. Libre vous de rendre linterface la plus agrable possible (notamment dans les moments de redimensionnement de la fentre).

Exercice 2 : Jouez

Comportement : En lanant lapplication, une de vos musiques est automatiquement joue par le lecteur Windows Media Player. Conseil : Intressez vous aux proprits du composant en question. Remarque : Lapparence du lecteur ne dpend que de sa version. Ici, cest la version 11 qui a t utilise.

Exercice 3 : Additionneur Comportement : Lutilisateur ne peut additionner que des chiffres. A chaque clic sur un chiffre, le chiffre suivi de " + " est ajout la TextBox (multiligne et avec scrollbars). En cliquant sur le bouton Calculer, le rsultat final de laddition est affich (suivi de " + " lui aussi). En cliquant sur le bouton Vider, on vide la TextBox et remet zro le compteur. Le contenu de la TextBox ne peut pas tre modifi autrement que par les boutons Le formulaire est verrouill : impossible den changer les dimensions. Conseil : Effectuez les additions au fur et mesure que lutilisateur clique sur un chiffre, cest beaucoup plus simple et tout fait adapt ce cas trs particulier.

Exercice 4 : Friends

Comportement : Vous ajoutez le nom de la personne tape dans le contrle 1 dans le contrle 3 en cliquant sur le 2. Aprs slection (unique !) dans le contrle 3, vous pouvez faire passer (elle nexistera plus alors dans le contrle dorigine) la slection dans le contrle 5 en cliquant sur le 4 et vice-versa en cliquant sur le 6. Conseil : Pensez vrifiez que la personne na pas dj t ajoute dans les contrles dans lune des deux listes avant de lajouter dans la liste de gauche.

Exercice 5 : Notepad Ouvrez Notepad (ou Bloc-notes si vous prfrez) et refaites exactement le mme logiciel en C# en ne codant cependant pas les fonctions : Mise en page Imprimer Rechercher Rechercher le suivant Remplacer Atteindre Police Barre dtat Rubrique daide Le choix dencodage Attention : Noubliez surtout pas les raccourcis claviers, ni les botes de sauvegarde, douverture de documents, etc. et aussi que lorsque vous ouvrez/enregistrez un fichier, son nom saffiche en titre de form Conseil : Intressez vous au contrle RichTextBox, la classe DateTime et la proprit ShortcuKeys.

Exercice 6 : MyWeb

Comportement : Lutilisateur entre ladresse internet du site quil veut visiter dans la TextBox, valide avec le bouton OK ou en appuyant sur la touche Entrer. Le chargement saffiche alors dans la barre dtat avec marqu ct "Chargement en cous". Une fois le chargement termin, la barre dtat disparait et la page saffiche automatiquement Lutilisateur peut alors basculer tout moment entre la page Page, o il voit la page web comme dans nimporte quel navigateur internet, et la page Source, o tout le code source de la page charge est affich. Lutilisateur ne doit pas pouvoir modifier le code source !

Exercice 7 : QCM Comportement : La ListBox propose trois QCM diffrents. En en choisissant un, lutilisateur change instantanment les questions et rponses se trouvant droite. Les rponses sont uniques. Quand lutilisateur a fini, il clique sur le bouton et une bote de dialogue apparait pour lui indiquer le nombre derreurs quil a commis ou sil a fait tout juste. Le premier QCM de la liste est slectionn par dfaut au lancement de lapplication.

Vous trouverez divers QCM sur ce site : http://quizz.e-qcm.net/. Limitez vous cinq questions par QCM pour ne pas rendre lexercice trop long mais vous pouvez faire plus bien entendu. Conseil : Nutilisez pas ici de contrles personnaliss : linterface est trs simple et ne change jamais. Seuls les textes changent ! Allez donc voir du ct du code. Exercice 7 bis Mme exercice que prcdemment mais remplacez les ComboBox par des RadioButton (et effectuez les modifications qui simposent).

Exercice 8 : Fates le tri

Comportement : Lutilisateur entre du texte, choisi le rang de ce texte (il a droit plusieurs choix) et en validant, le texte est ajout larbre aux rangs spcifis. Par dfaut, au lancement de lapplication, larbre contient trois nuds de bases : rang 1, rang 2, rang 3.

Exercice 9 : PictureViewer Comportement : En ouvrant un fichier de type image (et uniquement de type image, pas dautre choix), une nouvelle fentre incluse dans la principale est ajoute. Cette nouvelle fentre ne contient que limage, affiche 100% (et la fentre fait la taille de limage). Lutilisateur peut alors zoomer sur chacune des images slectionnes. Le zoom se fait par tape : 10, 20, 33, 50, 66, 75, 80, 90, 100, 150, 200, 300, 400, 500%. Attention : En passant dune fentre lautre, lancien zoom est automatiquement rtabli. Le zoom dpend de limage (et donc de la fentre) et nest pas globalis toutes les images. Conseil : Utilisez une PictureBox.

Exercice 10 : Notepad (suite) Reprenez lexercice 5 mais codez prsent toutes les fonctionnalits de Notepad et ajoutez-y mme la fonction rtablir avec son raccourci : Ctrl+Y. Exercice 11 : Calculatrice

Calculatrice effectuant toutes les oprations de base sur des nombres (plusieurs chiffres) positifs ou ngatifs, fonctions de trigonomtrie, etc. mod correspond loprateur modulo et prend deux paramtres : mod(5,2) signifie 5 modulo 2 (en mathmatiques, on sait que 5 1[2]). Comportement : Lutilisateur entre son opration en appuyant sur les boutons ou sur les touches de son clavier (ne pas oublier sin, cos, pi).

Lopration saffiche gauche dans le contrle TextBox au fur et mesure que lutilisateur lentre. En appuyant sur le bouton Calculer, lopration est effectue et le rsultat, prcd du signe gal es t affich sur la ligne daprs. Le prochain calcul commence sur la ligne suivante. Le bouton Nettoyer vide lcran. Il est impossible de revenir sur une opration prcdente : le calcul ne seffectue que sur la dernire opration entre et non encore calcule ! Belle calculatrice ! Remarques : Ici la difficult nest pas de crer linterface mais plutt dtablir lalgorithme traitant les lments fournis par linterface et de relier correctement ces deux ensembles. Les angles seront exprims en radians ! Pensez traiter un maximum derreurs (par exemple : les nombres entrs dans la fonction mod ne sont pas des entiers, etc.) Exercice 12 : Explorateur

Comportement : Le logiciel se lance par dfaut sur le Poste de Travail. Lorsque lutilisateur clique sur un fichier dans la TreeView ou dans la ListView, les proprits du fichier sont affiches dans la zone verte. Sil fait un simple clic sur un dossier dans la TreeView, le contenu est affich dans la ListView. Sil clique sur un dossier dans la ListView, son nom, sa taille (totale), le nombre de fichiers, de dossiers quil contient est affich dans zone verte. Sil double clic sur un dossier dans la TreeView ou dans la ListView et que celui-ci nest pas vide, il est dvelopp dans la TreeView et dans la ListView. La slection multiple est interdite. Conseils : Utilisez des contrles personnaliss pour chacun de vos lments spars par un Splitter et nhsitez pas crer de nouveaux fichiers, de nouvelles classes Notez que le temps de calcul de taille dun dossier peut prendre un certain temps (car il faut parcourir chaque sous dossier, fichier, etc.). Vous devrez donc utiliser les Thread pour ne pas paralyser votre application et rafraichir les donnes affiches (taille, nombre de sous dossiers, fichiers) rgulirement pour montrer que votre application travaille