Introduction a WPF - PARTIE I

Publié le par Jérémy JANISZEWSKI

INTRODUCTION

WPF(Windows Presentation Foundation) est une technologie de Microsoft reposant sur le framework .NET. Cette technologie se base sur Direct3D (dont il n'utilise pas toutes les fonctionnalités) et effectue le rendu d'objets (image, texte, dessin, etc...) en vectoriel, ce qui permet des agrandissements sans avoir un effet de pixellisation.

Le but avoué de cette technologie est de séparer la conception de l'interface graphique (crée par un graphiste et sauvegardée dans un fichier XAML) de la gestion de la dite interface (crée par le développeur C#, VB.NET ou C++)

Nous utiliserons VISUAL STUDIO 2010 pour créer nos programmes. Vous pouvez le télécharger ici. Sélectionnez Frenchau niveau du langage souhaité.

APPRENTISSAGE PAR L'EXEMPLE

Nous apprendrons WPF en créant moultes exemples et lorsque nous aurons acquis les connaissances suffisantes, nous programmerons la table de Mendeleiev (voui, le tableau periodique des éléments chimiques). Ce premier article se concentra sur la création et la modification d'une fenêtre WPF.

Toute application WPF doit avoir l'attribut [STAThread]. Cela signifie que le thread de l'application sera monotâche. Cela nous permet de garder la compatibilité avec COM (modèles de composants objet). En conséquence le thread de l'application ne peut être multitâches.

Commencez par créer un nouveau projet Console. Nommez-le, WPFIntro.
Ensuite pour pouvoir utiliser les bases de WPF, il faut référencer les assemblies suivantes :
-PresentationCore
-PresentationFramework
- System.XAML
- WindowsBase

Pour référencer une assembly, dans l'arborescence du projet, cliquez-droit sur Référenceset sélectionnez Ajouter une référence ...

Une fois les références ajoutées, nous allons pouvoir commencer notre apprentissage.

Pour le moment, nous n'utiliserons que deux classes :
- Application
- Window

EXEMPLE 1 : CREATION DE LA FENÊTRE

Pour pouvoir afficher notre fenêtre, il va nous falloir un objet Application et un objetWindow. L'objet Window s'occupera de gérer la fenêtre, alors que l'objet Application va créer la boucle de messages qui permettra à l'utilisateur d'intéragir avec la fenêtre. Pour pouvoir lancer l'application, il faudra appeler la méthode Run. Il existe deux surchages avec la méthode Run :
- une sans paramètre.
-une avec un objet Window en paramètre.

Nous verrons plus loin comment se servir de la première méthode, pour l'instant, nous utiliserons la deuxième.

Donc dans la méthode Main, nous allons créer notre objet Application comme ceci :

[STAThread]

static void Main(string[] args)

{

    Application app = new Application();
}

Ensuite dans la méthode Run, il nous faudra envoyer la méthode qui crééra notre fenêtre. Nous aurions pû créer notre fenêtre dans la méthode Main et l'envoyer en paramètre de Run, mais ce sera plus facile de s'y retrouver en créant une méthode dédiée. Notre méthode s'appelera CreateWindow. Elle renverra un type Window.

[STAThread]

static void Main(string[] args)

{

Application app = new Application();

app.Run(CreateWindow());

}

 

static private Window CreateWindow()

{

  Window win = new Window();

  return win;

}

CreateWindow est une méthode statique car la référence à cette méthode se situe dans une méthode statique.

Pressez F5 et admirez votre première fenêtre WPF.

Le prochain exemple ajoutera un titre à cette fenêtre.

EXEMPLE 2 : AJOUTER UN TITRE A UNE FENÊTRE

Un objet Window possède une propriété nommée Title. Cette propriété permet d'obtenir ou de définir le titre d'une fenêtre. Pour s'en servir, rien de plus simple, modifiez la méthode CreateWindow comme ceci :

 

staticprivateWindow CreateWindow()

{

Window win = newWindow();

win.Title = "Fenêtre WPF";
return win;

}

 

Pressez F5 et admirez le résultat. Votre fenêtre est dorénavent titrée.

Le prochain exemple va enregistrer un évènement qui détectera un click de souris et affichera une boîte de dialogue contenant le bouton qui a été appuyé ainsi que la position (relative) de la souris dans la fenêtre.

EXEMPLE 3 : ENREGISTREMENT D'UN EVENEMENT

Un objet Window possède un évènement nommé MouseDown.Cet évènement détecte la pression de l'un des boutons de la souris. Pour enregistrer un tel évènement, il faut ajouter += à la suite de l'évènement et donner la méthode à appeler en cas de lever de l'évènement. La méthode CreateWindow devient donc ceci :

 

staticprivateWindow CreateWindow()

{

Window win = newWindow();

win.Title = "Fenêtre WPF";

win.MouseDown += OnMouseDown;

return win;

}

 

L'évènement MouseDown requiert un "event handler" defini en accordance avec le délégué MouseButtonEventHandler, qui prend en premier paramètre un type Object et en deuxième paramètre un type MouseButtonEventArgs. Quelque soit le bouton appuyé sur la souris, cet évènement sera levé.

Il y'a donc une propriété nous permettant de récupérer le bouton qui a été appuyé. Cette propriété, en lecture seule, se nomme ChangedButton.

Cette propriété étant une énumération de type MouseButton, il nous est facile de connaitre le bouton appuyé.

Ensuite nous aurons besoin de la méthode GetPosition qui permet de connaitre la position de la souris par rapport à un élément (à condition que cet élément implémente l'interface IInputElement) et de renvoyer les coordonnées relatives de la souris par rapport à l'élément au format Point.

Enfin, pour afficher notre message, nous aurons besoin de la classe MessageBox. Cette classe contient 12 méthodes statiques nommées Show. Cela permet de définir la boîte de messages de différentes façons.

Nous pouvons afficher une boîte sans icônes, sans titre, mais avec un texte et un seul bouton, comme nous pourrions afficher une boîte avec une icône, un titre, 3 boutons, etc...

Notre méthode est écrite ainsi :

 

staticprivatevoid OnMouseDown(object sender, MouseButtonEventArgs e)

{

Window win = sender asWindow;

if (win != null)

{

MessageBox.Show(string.Format("Bouton cliqué : {0}\nPosition de la souris : {1}",

e.ChangedButton, e.GetPosition(win)),

win.Title);

}

}

 

Remarquez que nous convertissons l'objet nommé sender en un objet Window en utilisant le mot clé as. Ce mot clé est intéressant car il permet de tester la conversion d'un type en un autre.

Imaginons que l'évènement MouseDown ait été enregistré sur divers éléments et que la méthode à appeler pour chacun d'entre eux est la même méthode. Comment pouvons nous savoir si l'élément qui a levé l'évènement est un objet Window ou un objet Button ou tout autre objet ?

Pour cela, vous ne pouvez faire une conversion directement (c'est à dire écrire : (Window)sender), car vous ne connaissez pas le type de l'objet qui a levé l'évènement.

Pour cela vous avez deux possibilités :
- Tester si l'objet est du type voulu et s'il est, le convertir directement.

 

if (sender isWindow)

win = (Window)sender;

 

Soit vous passez le mot clé as. Si la conversion a réussi, alors win vaudra l'objet sender, sinon win vaudra null. C'est pour cela que nous testons si win vaut null, et s'il ne l'est pas nous affichons le message nous permettant de connaître le bouton de souris qui a été cliqué et sa position relative sur la fenêtre.

Pressez F5, et allez cliquer n'importe où sur la fenêtre pour voir ce qu'il s'y passe.

Maintenant, nous allons "simplifier" tout cela, en utilisant le principe de l'héritage.

EXEMPLE 4 : MÊME PROGRAMME MAIS AVEC L'HERITAGE

Nous allons créer deux nouvelles classes : App et MainWindow. Pour cela, cliquez droit sur WPFIntro, sélectionnez Ajouter -> Nouvel élément, puis dans la liste, sélectionnez ensuite Class et nommez-la App. Refaites de même et nommez la deuxième classe MainWindow.

Maintenant, double cliquez sur App.cs. Modifiez le fichier comme suit :

 

sealedclassApp
:
Application
{ }

 

Nous scellons notre classe pour en interdire l'héritage. Remarquez comment en C# nous demandons l'héritage d'un objet. Pour faire un héritage vous érivez 'X : Y' où X représente le nom de votre classe et Y le nom de la classe qui doit servir à l'héritage.

La classe Application contient entre autre, une méthode qui peut être surchargée et se nommant OnStartup. Cette méthode a lieu au démarrage du programme. C'est donc un choix convenable pour créer notre fenêtre Window ici. Sauf que ici, nous utiliserons notre classe MainWindow.

Ouvrez donc le fichier MainWindow.cs, puis modifiez-le comme ceci :

 

sealedclassMainWindow
:
Window
{ }

 

Maintenant, retournez dans le fichier App.cs, et modifiez-le comme ceci :

 

sealedclassApp

: Application

{

sealedoverrideprotectedvoid OnStartup(StartupEventArgs e)

{

MainWindow win = newMainWindow();

win.Title = "Fenêtre WPF";

win.Show();

base.OnStartup(e);

}

}

 

La surcharge d'une méthode passe par le mot clé override. Pour pouvoir utiliser ce mot clé, il faut que la méthode de base soit marquée comme virtual ou abstract.

Donc dans cette méthode, nous créons notre fenêtre, nous la nommons et nous appelons la fonction Show de la fenêtre pour l'afficher à l'écran. Ceci est très important car nous allons nous servir de la méthode Run sans paramètre dans moins de 10 secondes.

Ensuite ouvrez le ficher Program.cs, retirez les méthodes OnMouseDown et CreateWindow et modifier le corps de la méthode Main comme ceci :

 

[STAThread]

staticvoid Main(string[] args)

{

App app = newApp();
app.Run();
}

 

Ensuite pressez F5 et admirez. Vous avez l'affichage de la fenêtre et de son titre. Maintenant, nous allons gérer le clic de la souris et l'affichage de la boîte de dialogue.

Retournez dans le fichier MainWindow.cs. Lorsque vous avez héritez de l'objet Window, vous avez accès à diverses méthodes à surcharger. Celle qui nous interesse s'appelle OnMouseDown. Cette méthode ne prend paramètre qu'un objet du type MouseButtonEventArgs. Cela est normal car la méthode appartient à l'objet Window. Donc ici, nous n'aurons pas besoin de tester si l'objet est de type Window, puisqu'il est.

Donc ajoutez ceci dans la classe MainWindow.

 

sealedoverrideprotectedvoid OnMouseDown(MouseButtonEventArgs e)

{

MessageBox.Show(string.Format("Bouton cliqué : {0}\nPosition de la souris : {1}",

e.ChangedButton, e.GetPosition(this)),

Title);

base.OnMouseDown(e);

}

 

Remarquez que la fonction est plus simple que la version précédente. Le changement le plus important se situe avec la méthode GetPosition.

En effet, nous voulons récupérer la position relative de la souris par rapport à notre fenêtre. Or comment pouvons spécifier à cette méthode qu'elle opère sur notre classe ?

Et bien nous utilisons le mot clé this.

Bien sûr, this spécifiant notre classe, si vous suffixez ce mot par un '.', vous aurez accès à tous les champs non statique de la classe.

Maintenant, pressez F5 et admirez le résultat. Le prochain exemple va montrer comment intercepter la fermeture du programme.

EXEMPLE 5 : INTERCEPTER LA FERMETURE DU PROGRAMME

Nous avons vu que la classe Window possède une méthode surchargeable OnMouseDown qui correspond à ce que vous souhaitez faire lors d'un clic souris. Pour faire ce que vous souhaitez lorsque le programme va fermer, il faut surcharger la méthode OnClosing. Cette méthode prend en argument un objet de type CancelEventArgs qui permet l'annulation de fermeture du programme.

Dans le fichier MainWindow, ajoutez ceci :

 

sealedoverrideprotectedvoid OnClosing(CancelEventArgs e)

{

MessageBoxResult res = MessageBox.Show("Les données n'ont pas été sauvegardées.\nVoulez-vous les sauvegarder ?",

Title,

MessageBoxButton.YesNoCancel,

MessageBoxImage.Question);

e.Cancel = res == MessageBoxResult.Cancel;

base.OnClosing(e);

}

 

Ici, nous demandons la création d'une boîte de dialogue qui affichera les boutons Oui, Non et Annuler. L'icône Question sera afficher et nous récupérons la valeur de la boîte de dialogue dans res.
Ensuite, nous regardons si nous avons cliqué sur Cancel. Si c'est le cas, nous demandons à l'application de ne pas quitter (e.Cancel vaut true si res vaut Cancel)

Les deux derniers exemples que je présenterais dans cet article concerneront la position de la fenêtre à l'écran ainsi que la taille de la fenêtre, puis comment redimensionner manuellement la taille de la fenêtre en utilisant les touches + et - du clavier.

EXEMPLE 6 : MODIFIER LA TAILLE DE LA FENÊTRE ET SA POSITION AU DEMARRAGE DE L'APPLICATION

La classe Window possède quelques propriétés qui permettent de positionner, redimensionner la fenêtre au démarrage de l'application :
- WindowStartupLocation : Permet de positionner la fenêtre en fonction de l'écran, d'une autre fenêtre ou manuellement.
- Width : Définit la longeur de la fenêtre.
- Height : Définit la hauteur de la fenêtre
- Left : Définit la position X de la fenêtre
- Top : Définit la position Y de la fenêtre

Si vous avez définit WindowStartupLocation à CenterScreen ou CenterOwner, les variables Left et Top n'auront aucun effet.

Dans la classe MainWindow, ajoutez ce constructeur qui instancie certaines composantes de la fenêtre.

 

public MainWindow()

{

WindowStartupLocation = WindowStartupLocation.CenterScreen;

Width = 800;

Height = 600;

Left = 0;

Top = 0;

}

 

Si vous pressez F5, vous aurez une fenêtre qui sera affichée au milieu de l'écran. Maintenant si vous changez CenterScreen par Manual, la fenêtre s'affichera aux coordonnées (0,0) de l'écran.

Vous pouvez modifier la taille de la fenêtre en changeant les variables Width et Height et modifier la position en modifiant les variables Left et Top.

Autre exemple :

 

public MainWindow()

{

WindowStartupLocation = WindowStartupLocation.Manual;

Width = 400;

Height = 400;

Left = 260;

Top = 100;

}

 

EXEMPLE 7 : MODIFIER MANUELLEMENT LA TAILLE DE LA FENÊTRE

Pour modifier la taille de la fenêtre, il faut surcharger la méthode OnKeyDown de la classe Window. Nous modifierons la taille de la fenêtre à l'appui des touches + et -. Donc dans la classe MainWindow, ajoutons ceci :

 

sealed override protected void OnKeyDown(KeyEventArgs e)

{

if (e.Key == Key.Add)

{

Width *= 1.1;

Height *= 1.1;

}

elseif (e.Key == Key.Subtract)

{

Width /= 1.1;

Height /= 1.1;
}

base.OnKeyDown(e);

}

 

Et voilà, cette première partie d'introduction à WPF est terminée.

Stay tuned,

@bientôt sur ce blog

Publié dans WPF

Pour être informé des derniers articles, inscrivez vous :
Commenter cet article