I. Avertissement▲
Cet article fait partie d'un ensemble sur Avalon (« Windows Presentation Foundation »). Ceux-ci, bien qu'écrits séparément, forment un tout. À la manière des chapitres d'un livre, vous pouvez accéder directement au sujet qui vous intéresse, mais pour un aperçu complet, il est préférable de commencer la lecture au premier article.
1re partie : Installation
2e partie : Ma première fenêtre avec Avalon
3epartie : Les contrôles courants
4epartie : Le menu
5epartie : Les modèles « Avalon Express Application » et « Navigation Application »
II. Remerciements▲
Je remercie Louis-Guillaume Morand pour la relecture de cet article et ses conseils judicieux.
III. Créer un projet pour Avalon▲
Créez un nouveau projet de type « Visual C# ». Ouvrez la rubrique Avalon. Vous y trouvez quatre templates. Pour l'exemple, j'ai choisi le plus simple, « Avalon Application ». Bien sûr, si vous souhaitez créer le projet avec VB.NET, c'est également possible.
Dans le projet, nous retrouvons comme pour une WinForm classique, le dossier « Properties » et le dossier « References ». Dans l'image ci-dessous vous pouvez comparer à gauche les références nécessaires à un projet « Avalon Application » et à droite les références nécessaires à un projet « Window Application ».
Les références sont évidemment très différentes entre les deux types de projets.
Il est à noter que je compare ici les fichiers générés sous Visual Studio 2005 pour les deux types. Si vous êtes habitué à Visual Studio 2003, vous constaterez certaines différences.
En ce qui concerne le code source proprement dit, le fichier « program.cs » généré pour une application Windows classique est remplacé par le couple « MyApp.xaml », « MyApp.xaml.cs ».
<Application
x
:
Class
=
"AvalonApplication4.MyApp"
xmlns
=
"http://schemas.microsoft.com/winfx/avalon/2005"
xmlns
:
x
=
"http://schemas.microsoft.com/winfx/xaml/2005"
StartingUp
=
"AppStartingUp"
>
<Application.Resources>
</Application.Resources>
</Application>
using
System;
using
System.
Windows;
using
System.
Data;
using
System.
Xml;
using
System.
Configuration;
namespace
AvalonApplication4
{
///
<
summary
>
/// Interaction logic for MyApp.xaml
///
<
/summary
>
public
partial
class
MyApp :
Application
{
void
AppStartingUp
(
object
sender,
StartingUpCancelEventArgs e)
{
Window1 mainWindow =
new
Window1
(
);
mainWindow.
Show
(
);
}
}
}
Le couple « Form1.cs », « Form1.designer.cs » est lui remplacé par « Window1.xaml », « Window1.xaml.cs ».
<Window
x
:
Class
=
"AvalonApplication4.Window1"
xmlns
=
"http://schemas.microsoft.com/winfx/avalon/2005"
xmlns
:
x
=
"http://schemas.microsoft.com/winfx/xaml/2005"
Text
=
"AvalonApplication4"
>
<Grid>
</Grid>
</Window>
using
System;
using
System.
Windows;
using
System.
Windows.
Controls;
using
System.
Windows.
Data;
using
System.
Windows.
Documents;
using
System.
Windows.
Media;
using
System.
Windows.
Shapes;
namespace
AvalonApplication4
{
///
<
summary
>
/// Interaction logic for Window1.xaml
///
<
/summary
>
public
partial
class
Window1 :
Window
{
public
Window1
(
)
{
InitializeComponent
(
);
}
// To use Loaded event put Loaded="WindowLoaded" attribute in root element of .xaml file.
// private void WindowLoaded(object sender, RoutedEventArgs e) {}
// Sample event handler:
// private void ButtonClick(object sender, RoutedEventArgs e) {}
}
}
IV. Le code XAML▲
IV-A. Décrire l'interface graphique en XAML▲
Le principe du XAML est très simple. Il reprend la syntaxe du XML et chaque objet que vous auriez antérieurement défini via l'API, est défini comme un nœud. Les propriétés de l'objet sont quant à elles initialisées en utilisant les attributs XML et des nœuds fils.
IV-B. Tester notre code XAML avec XAMLPad▲
XAMLPad s'utilise assez simplement, il est divisé en deux zones. La zone supérieure affiche le résultat du code XAML que vous tapez dans la zone inférieure. Les informations concernant vos erreurs dans la source XAML sont indiquées dans la barre de statut. Certains codes XAML ne peuvent être directement affichés dans la fenêtre supérieure. Dans ce cas, un message vous invite à presser la touche F5 pour voir le résultat.
Le premier tag XML concerne la définition de la fenêtre elle-même. Nous pouvons par exemple donner le titre et les dimensions de celle-ci.
Contrairement aux API classiques, la propriété « Location » n'est pas disponible pour les contrôles. Pour les positionner dans la fenêtre, il existe trois méthodes. Soit en utilisant un objet « Canvas », soit en utilisant un objet « Table » ou encore en utilisant un objet « Grid ». La classe « Canvas » permet de placer un contrôle basé sur un système de coordonnées alors que les classes « Table » et « Grid » utilisent une grille de lignes et de colonnes. Pour une fenêtre simple, ce qui est typiquement le cas d'une boîte de dialogue, Microsoft recommande l'utilisation du « Grid ». Dans notre exemple simple, elle contient uniquement deux lignes.
Pour le texte, nous allons utiliser un contrôle de type label. La propriété « Grid.Row » sert à définir dans quelle ligne de notre grille doit être placé le « label ». La propriété « Margin » défini les marges autour de notre « label » dans la cellule. J'ai choisi de définir la même marge dans les quatre directions, mais il est possible de définir une valeur différente pour chacune des marges. Nous aurions eu alors par exemple
Margin="20,10,20,10"
Les autres propriétés parlent d'elles-mêmes.
Pour le bouton « OK », un contrôle de type « button » s'impose évidemment. Vous remarquerez que n'ayant pas défini de marge dans mon code, le contrôle sera automatiquement centré dans la ligne de la grille désignée.
Il nous suffit alors de presser la touche F5 pour obtenir le résultat.
IV-C. Inclure le code XAML dans Visual Studio▲
Nous allons inclure dans le fichier « Windows1.xaml » le code que nous venons de tester. Attention ne remplacez pas aveuglément le tag « window ». En effet celui généré dans Visual studio contient un attribut important. L'attribut x:Class=« MaPremiereFenetre.Windows1 » permet effectivement d'associer le code XAML à la classe dotnet.
Le code ainsi complété ne peut être compilé. Nous devons encore y apporter une petite modification. Le code contenait une petite erreur, car les objets de type RowDefinition doivent être inclus dans une collection de type RowDefinitions. Ceci démontre que si XAMLPad est très utile, il semble beaucoup moins regardant sur la syntaxe que le compilateur. Le code définitif est donc :
<Window
x
:
Class
=
"MaPremiereFenetre.Windows1"
xmlns
=
"http://schemas.microsoft.com/winfx/avalon/2005"
xmlns
:
x
=
"http://schemas.microsoft.com/winfx/xaml/2005"
Text
=
"Ma première fenêtre XAML"
Width
=
"300"
Height
=
"200"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label
Name
=
"txtHello"
Height
=
"50px"
FontSize
=
"20"
Margin
=
"20"
Grid.
Row
=
"0"
>
Hello word.
</Label>
<Button
Name
=
"btnOk"
Width
=
"100"
Height
=
"20"
Grid.
Row
=
"1"
>
Ok
</Button>
</Grid>
</Window>
Notre programme donne maintenant le résultat voulu.
V. La compilation▲
Une fois le projet compilé, nous trouvons le dossier « obj » qui contient le dossier « Debug » et, ou « Release ». Ce dossier contient trois fichiers, « AvalonApplication4.Main.g.cs », « MyApp.g.cs », « Window1.g.cs ». Le ficher « AvalonApplication4.Main.g.cs » contient la classe ResourceLoader nécessaire pour la gestion des ressources XAML. Il contient également le point d'entrée du programme. Les fichiers « MyApp.g.cs » et « Window1.g.cs complètent les fichiers »MyApp.xaml.cs« et »Window1.xaml.cs" en leur ajoutant entre autres une séquence d'initialisation.
Ce qui n'est pas visible depuis Visual Studio, c'est que non seulement la compilation a créé un EXE, mais également deux fichiers BAML qui sont des fichiers « binaires » des fichiers XAML originaux. Ces fichiers sont utilisés dans le code source des fichiers générés dont nous venons de parler.
Toutefois, bien qu'il soit toujours très intéressant de connaître au mieux le fonctionnement d'un produit que l'on utilise, nous ne devons pas intervenir à ce niveau et cette partie reste transparente pour nous.
VI. La gestion des évènements▲
La gestion des évènements se fait via une méthode dans votre code comme c'est le cas actuellement. La seule différence est que l'association de la méthode à l'évènement se fait dans le code XAML.
<Window
x
:
Class
=
"MaPremiereFenetre.Windows1"
xmlns
=
"http://schemas.microsoft.com/winfx/avalon/2005"
xmlns
:
x
=
"http://schemas.microsoft.com/winfx/xaml/2005"
Text
=
"Ma première fenêtre XAML"
Width
=
"300"
Height
=
"200"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label
Name
=
"txtHello"
Height
=
"50px"
FontSize
=
"20"
Margin
=
"20"
Grid.
Row
=
"0"
>
Hello word.
</Label>
<Button
Name
=
"btnOk"
Width
=
"100"
Height
=
"20"
Grid.
Row
=
"1"
Click
=
"ButtonClick"
>
OK
</Button>
</Grid>
</Window>
using
System;
using
System.
Windows;
using
System.
Windows.
Controls;
using
System.
Windows.
Data;
using
System.
Windows.
Documents;
using
System.
Windows.
Media;
using
System.
Windows.
Shapes;
namespace
MaPremiereFenetre
{
///
<
summary
>
/// Interaction logic for Window1.xaml
///
<
/summary
>
public
partial
class
Windows1 :
Window
{
public
Windows1
(
)
{
InitializeComponent
(
);
}
private
void
ButtonClick
(
object
sender,
RoutedEventArgs e)
{
this
.
Close
(
);
}
}
}
VII. Conclusion▲
L'utilisation de XAML n'est en définitive qu'une autre manière de coder les API et ne devrait pas représenter une réelle difficulté. Par contre, les API associées à Avalon sont nouvelles et ne disposent pas nécessairement des mêmes fonctionnalités que leurs équivalents en WinForm traditionnelle.
Il est évident qu'actuellement, l'absence d'un RAD XAML dédié au design d'écran rend les choses plus difficiles. D'un autre côté, cela permet de se familiariser directement avec les nouvelles classes.
À très bientôt pour un nouvel article sur les différents contrôles courants disponibles dans « Windows Presentation Foundation ».