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

1er partie: Installation
2ème partie: Ma première fenêtre avec Avalon
3ème partie: Les contrôles courants
4ème partie: Le menu

5ème partie: 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 4 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".

Image non disponible

Les références sont évidemment très différentes entre les deux types de projet.

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
Sélectionnez
<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
Sélectionnez
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
Sélectionnez
<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
Sélectionnez
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

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 noeud. Les propriétés de l'objet sont quant à elles initialisées en utilisant les attributs XML et des noeuds fils.

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.

Image non disponible

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 3 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" utilise 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

 
Sélectionnez

 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.

Image non disponible

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:

 
Sélectionnez
<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.

Image non disponible

V. La compilation

Une fois le projet compilé, nous trouvons le dossier "obj" qui contient le dossier "Debug" et, ou "Release". Ce dossier contient 3 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é 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 autre 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é
Sélectionnez
<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
Sélectionnez
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 d'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.

A très bientôt pour un nouvel article sur les différents contrôles courants disponibles dans "Windows Presentation Foundation".