À la découverte d'Avalon Partie II : Mon premier écran avec Avalon

Jean-Alain Baeyens

Pour ne pas déroger aux pratiques courantes, nous allons commencer l'étude d'Avalon par le très traditionnel « Hello world ». ♪

- Titre : À la découverte d'Avalon Partie II : Mon premier écran avec Avalon

- Auteur : Jean-Alain Baeyens

- Parution : 11 septembre 2005

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2005 Jean-Alain Baeyens. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Avertissement

- II. Remerciements

- III. Créer un projet pour Avalon

- IV. Le code XAML

- IV-A. Décrire l'interface graphique en XAML

- IV-B. Tester notre code XAML avec XAMLPad

- IV-C. Inclure le code XAML dans Visual Studio

- V. La compilation

- VI. La gestion des évènements

- VII. Conclusion

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 ».

Le contenu de MyApp.xaml

<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>

Le contenu de MyApp.xaml.cs

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 ».

Le contenu de Window1.xaml

<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>

Le contenu de Window1.xaml.cs

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.

Le fichier Window.xaml modifié

<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>

Notre fichier Window1.xaml.cs

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 ».