I. Introduction▲
Silverlight est l'une des nouvelles technologies nées de chez Microsoft.
Avec, il est possible de créer des applications web riches, des animations, des jeux ?
Voici ce qu'il est, entre autres, capable de réaliser
http://www.tafiti.com/.
Des exemples sont également disponibles sur le site officiel
http://www.silverlight.net.
Silverlight se décline actuellement en deux versions :
- 1.0 qui permet de faire des applications côté client, tout est en Javascript ;
- 2 (anciennement 1.1) qui intègre une version du Framework .NET avec une CLR et qui permet donc d'exécuter du code C# ou VB.NET.
Dans cet article nous apprendrons donc comment utiliser la version 2.
Quelques outils sont requis pour développer en Silverlight 2.
Les outils requis :
- Microsoft Visual Studio 2008 (je ne sais pas si une version Express convient) ;
- Microsoft® Silverlight? 2 Software Development Kit Beta 1 ;
- Microsoft Silverlight Tools Beta 1 for Visual Studio 2008 ;
- Le runtime de Silverlight 2.
Une fois tous ces outils installés nous pouvons commencer.
II. Création du projet▲
Tout d'abord on lance Visual Studio 2008 et on crée un nouveau projet de type Silverlight Application.
Une fois le nom du projet entré, on a le choix entre créer un nouveau projet de type WebSite directement dans notre solution, ou de simplement avoir une page HTML.
Pour notre article j'ai sélectionné la seconde option.
Nous voici donc avec notre projet fraichement créé.
On peut donc apercevoir un mode splité pour notre XAML ce qui est assez agréable. Puis on peut voir les différents fichiers créés par défaut.

Fini donc les fichiers HTML ou JS, nous avons seulement deux fichiers XAML (avec leur .cs correpondant pour le code-behind).
- Page.xaml : notre XAML principal, contient le code de notre application, le code-behind sert pour le code des évènements par exemple.
- App.xaml : contient les Ressources de notre application (les styles par exemple), le code-behind lui sert à manipuler les évènements au niveau de l'application (Application_Startup, Application_Exit…).
Là on peut se demander où est donc notre fameux fichier HTML, c'est simple il se trouve dans le répertoire ClientBin.
Un petit coup d'œil à la ToolBox où on peut voir toute une tripotée de contrôles qui vont donc nous changer la vie par rapport à la version 1.0 et 1.1 alpha. Bref que du bon.
III. Première application▲
Une fois notre projet crée, on va créer notre première application.
On va donc simplement rajouter un bouton qui change de texte lorsque l'on clique dessus.
Remarquons l'Intellisense.
Ici on peut voir la création automatique d'EventHandler (qui n'était pas présente dans la version alpha). Si on clique dessus notre EventHandler est créé dans notre Page.xaml.cs.
Voici donc le code XAML final.
<UserControl x:Class="TestSilverlight2.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="Green">
<Button x:Name="myButton" Content="Click me !" Click="myButton_Click" Width="100" Height="50"></Button>
</Grid>
</UserControl>Un petit tour dans le Page.xaml.cs pour rajouter notre code-behind.
private void myButton_Click(object sender, RoutedEventArgs e)
{
myButton.Content = "You clicked !";
}Voici le résultat visuel.
Une fois qu'on a cliqué dessus.
Et voici donc notre première application en Silverlight 2.
IV. Le positionnement▲
Nous voici donc dans la seconde partie sur le positionnement.
Silverlight 2 inclut trois des systèmes de positionnement de WPF :
- Canvas ;
- StackPanel ;
- Grid.
IV-A. Canvas▲
Le Canvas était le système de positionnement utilisé dans Silverlight 1.0 et 1.1.
Tous les éléments dans un Canvas sont positionnés par deux propriétés : Canvas.Left et Canvas.Top.
<UserControl x:Class="TestSilverlight2.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Canvas x:Name="LayoutRoot" Background="Green">
<Button Content="Bouton 1" Width="100" Height="50" Canvas.Left="10" Canvas.Top="10"/>
<Button Content="Bouton 2" Width="100" Height="50" Canvas.Left="40" Canvas.Top="100"/>
</Canvas>
</UserControl>Le résultat.
IV-B. StackPanel▲
Le StackPanel permet de positionner les éléments les uns en dessous des autres (ou les uns à côté des autres).
<UserControl x:Class="TestSilverlight2.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<StackPanel x:Name="LayoutRoot" Background="Green">
<Button Content="Bouton 1" Width="100" Height="50" Margin="20"/>
<Button Content="Bouton 2" Width="100" Height="50" Margin="20"/>
</StackPanel>
</UserControl>Le résultat.
Comme vous pouvez le voir dans le code, l'écart entre les éléments est spécifié par la propriété Margin.
On peut également changer l'orientation via la propriété Orientation.
<UserControl x:Class="TestSilverlight2.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<StackPanel x:Name="LayoutRoot" Background="Green" Orientation="Horizontal">
<Button Content="Bouton 1" Width="100" Height="50" Margin="20"/>
<Button Content="Bouton 2" Width="100" Height="50" Margin="20"/>
</StackPanel>
</UserControl>IV-C. Grid▲
Et voici le positionnement de type Grid.
Le Grid et le système de positionnement le plus flexible il est basé sur des lignes et des colonnes, il est conceptuellement proche du tableau HTML.
Il suffit de spécifier au contrôle sa colonne ainsi que sa ligne via les propriétés Grid.Column et Grid.Row.
<UserControl x:Class="TestSilverlight2.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="330" Height="180">
<Grid x:Name="LayoutRoot" Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110"/>
<ColumnDefinition Width="110"/>
<ColumnDefinition Width="110"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="60"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Button Content="Bouton 1" Width="100" Height="50" Grid.Column="0" Grid.Row="0"/>
<Button Content="Bouton 2" Width="100" Height="50" Grid.Column="2" Grid.Row="0"/>
<Button Content="Bouton 3" Width="100" Height="50" Grid.Column="0" Grid.Row="2"/>
<Button Content="Bouton 4" Width="100" Height="50" Grid.Column="2" Grid.Row="2"/>
<Button Content="Bouton 5" Width="100" Height="50" Grid.Column="1" Grid.Row="1"/>
</Grid>
</UserControl>Tout comme les tableaux en HTML, on peut fusionner des colonnes et lignes (pour mettre un contrôle sur deux lignes par exemple) avec les propriétés Grid.RowSpan et Grid.ColumnSpan.
V. Utiliser le réseau pour récupérer des infos et remplir un DataGrid▲
Dans cette partie vous allons voir comment récupérer des informations via le réseau et comment remplir un DataGrid.
Tout d'abord nous allons créer un nouveau projet, mais cette fois nous allons aussi créer un projet de type Web Site.
Une fois ceci fait nous allons simplement ajouter une TextBox, un Button et un GridView dans notre XAML.
On place le tout dans un Grid.
<UserControl xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
x:Class="FlickrPhotoViewer.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Flickr="clr-namespace:FlickrPhotoViewer;assembly=FlickrPhotoViewer">
<Grid x:Name="LayoutRoot" Background="#BBF99D">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textSearch" Grid.Column="0"
VerticalAlignment="Center" Margin="10,10,0,10"/>
<Button x:Name="buttonSearch" Click="buttonSearch_Click" Width="50" Height="20" Content="Get" Grid.Column="1"/>
</Grid>
<my:DataGrid x:Name="Photos" AutoGenerateColumns="True" Grid.Row="1" Margin="10,0,10,10"></my:DataGrid>
</Grid>
</UserControl>Le fait d'avoir enlevé les propriétés Width et Height dans la balise UserControl permet à notre contrôle Silverlight d'être redimensionné en même temps que la fenêtre.
Ensuite nous allons aller dans le code-behind pour mettre le code du clic sur le bouton.
Pour cet exemple nous allons récupérer des données via l'API de Flickr. Je vais utiliser leur méthode flickr.photos.search. Pour cela nous allons utiliser une nouveauté de Silverlight 2, c'est le namespace System.Net, qui contient la classe WebClient.
Vous pouvez voir le XML généré par cette méthode ici.
private void buttonSearch_Click(object sender, RoutedEventArgs e)
{
string url = string.Format("http://api.flickr.com/services/rest/?method=flickr.photos.search&" +
"api_key=1cb12f30d9a23d70f00e4a238b4cf1fd&text={0}&machine_tag_mode=&per_page=20",
textSearch.Text);
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri(url));
}
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
// TODO
}
}Maintenant nous allons créer une classe qui représentera une image sur Flickr. On va donc ajouter une nouvelle classe à notre projet et mettre ce code.
public class FlickrPhoto
{
public long Id { get; set; }
public string Owner { get; set; }
public string Title { get; set; }
public string Image { get; set; }
}Nous allons donc stocker l'id, le propriétaire, le titre et l'adresse de l'image. Pour récupérer l'adresse de l'image nous allons utiliser les infos retournées dans le XML à savoir le farm-id, le server-id, l'id et le secret. En effet les photos peuvent être retrouvées via cette URL : http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg.
Maintenant nous allons rajouter le code pour exploiter le XML, pour cela nous allons utiliser LINQ donc il faut avant tout ajouter la référence System.Xml.Linq à notre projet.
private void DisplayFlickrPhotos(string xml)
{
XDocument doc = XDocument.Parse(xml);
var photos = from photo in doc.Descendants("photo")
select new FlickrPhoto
{
Id = (long)photo.Attribute("id"),
Owner = (string)photo.Attribute("owner"),
Title = (string)photo.Attribute("title"),
Image = string.Format("http://farm{0}.static.flickr.com/{1}/{2}_{3}.jpg",
(int)photo.Attribute("farm"),
(int)photo.Attribute("server"),
(long)photo.Attribute("id"),
(string)photo.Attribute("secret"))
};
Photos.ItemsSource = photos;
}On n'oublie pas d'ajouter l'appel à cette méthode à la place du TODO.
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
DisplayFlickrPhotos(e.Result);
}
}Et voici le résultat une fois que l'on a cliqué sur le bouton.
Voilà nous venons de voir qu'il était très simple de faire désormais du Cross Domain, et de jouer avec le XML avec Linq.
Nous allons maintenant améliorer notre GridView, en affichant la photo lorsque l'on clique sur une ligne.
Pour cela nous allons rajouter un Template lorsqu'une ligne est sélectionnée.
<UserControl xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
x:Class="FlickrPhotoViewer.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Flickr="clr-namespace:FlickrPhotoViewer;assembly=FlickrPhotoViewer">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textSearch" Grid.Column="0"
VerticalAlignment="Center" Margin="10,10,0,10"/>
<Button x:Name="buttonSearch" Click="buttonSearch_Click" Width="50" Height="20" Content="Get" Grid.Column="1"/>
</Grid>
<my:DataGrid x:Name="Photos" AutoGenerateColumns="True" RowDetailsVisibilityMode="VisibleWhenSelected"
Grid.Row="1" Margin="10,0,10,10">
<my:DataGrid.RowDetailsTemplate>
<DataTemplate>
<Grid>
<Image Source="{Binding Image}" Width="200" Height="200" />
</Grid>
</DataTemplate>
</my:DataGrid.RowDetailsTemplate>
</my:DataGrid>
</Grid>
</UserControl>Désormais la photo sera affichée quand on cliquera sur une ligne.
VI. Les Styles▲
Les Styles en Silverlight (et WPF) permettent d'appliquer un style à un ensemble de contrôle à l'instar des fichiers .skin en ASP.NET ou encore des fichiers CSS.
Leur déclaration se fait dans le fichier App.xaml.
<Application.Resources>
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="20"/>
</Style>
</Application.Resources>Ici tous les boutons auxquels j'applique ce style auront une largeur de 50 et une hauteur de 20.
Pour appliquer un style, c'est extrêmement simple. Il suffit de le spécifier dans la propriété Style des contrôles.
<Button x:Name="buttonSearch" Click="buttonSearch_Click" Content="Get" Style="{StaticResource ButtonStyle}"/>VII. ListBox et DataBinding▲
Dans cette partie nous allons voir comment afficher des données dans une ListBox.
Tout d'abord nous allons supprimer notre DataGrid pour le remplacer par une ListBox.
<ListBox x:Name="Photos" Grid.Row="1"></ListBox>On lance.
Seulement l'affichage n'est pas top, en effet c'est la méthode ToString() qui est appelée pour afficher les éléments et par défaut elle affiche le namespace et le nom de la classe. Nous allons donc rendre l'affiche plus joli.
Pour cela nous allons utiliser la propriété DisplayMemberPath pour spécifier quelles propriétés de notre classe FilckrPhoto afficher.
<ListBox x:Name="Photos" DisplayMemberPath="Title">
</ListBox>Si on veut afficher plusieurs éléments (par exemple l'id, le titre et même l'image) alors il faut modifier l'ItemTemplate de notre ListBox.
<ListBox x:Name="Photos" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}" Style="{StaticResource ThumbnailStyle}"/>
<TextBlock Text="{Binding Title}" Style="{StaticResource TextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>On n'oublie alors pas d'enlever la propriété DisplayMemberPath.
Avec les styles suivants.
<Style x:Key="ThumbnailStyle" TargetType="Image">
<Setter Property="Margin" Value="10"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Width" Value="50"/>
</Style>
<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="10"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>Chaque item sera donc composé d'une miniature de l'image suivie du titre.
La ListBox supporte la sélection ainsi que le déplacement via les flèches du clavier.
VIII. UserControls▲
Dans cette partie nous allons voir comment créer et utiliser un UserControl en Silverlight. Nous allons donc reprendre l'application précédente et rajouter un panel contenant les informations d'une image lorsque l'on clique sur un item de la ListBox.
On va tout d'abord créer notre UserControl : Add -> New Item
Ajoutons-lui quelques contrôles pour afficher le titre, l'image, le propriétaire et le chemin de l'image ainsi qu'un bouton pour cacher le contrôle.
<UserControl x:Class="FlickrPhotoViewer.FlickrPhotoDetail"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel HorizontalAlignment="Center">
<Button x:Name="btnClose" Content="Fermer" Click="btnClose_Click"/>
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleStyle}"/>
<Image Source="{Binding Image}" Style="{StaticResource ImageStyle}"/>
<TextBlock Text="{Binding Owner}" Style="{StaticResource OwnerStyle}"/>
<TextBox Text="{Binding Image}" IsReadOnly="True"/>
</StackPanel>
</Grid>
</UserControl>Voici le code du clic sur le bouton.
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.Visibility = Visibility.Collapsed;
}On cachera donc notre UserControl quand on cliquera sur le bouton.
Et voici maintenant les styles.
<Style x:Key="TitleStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="30"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="Margin" Value="10"/>
</Style>
<Style x:Key="ImageStyle" TargetType="Image">
<Setter Property="Margin" Value="10"/>
<Setter Property="Height" Value="300"/>
<Setter Property="Width" Value="300"/>
</Style>
<Style x:Key="OwnerStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="Margin" Value="10"/>
</Style>Alors comme vous pouvez voir nous utilisons du DataBinding, et vous vous demandez peut-être où est-ce qu'il va aller chercher ses infos. C'est simple il va aller les chercher dans sa propriété DataContext qui si elle n'est pas définie est celle du contrôle de niveau supérieur. On va donc devoir spécifier le DataContext de notre UserControl au moment de l'afficher.
Tout d'abord nous allons l'ajouter à notre application.
Pour cela il faut d'abord dire où se trouve notre contrôle et lui donner un namespace. On va donc rajouter cette ligne dans notre Page.xaml dans la balise UserControl.
xmlns:Flickr="clr-namespace:FlickrPhotoViewer;assembly=FlickrPhotoViewer"On va donc rajouter notre UserControl à notre application, nous allons le placer tout à la fin et faire en sorte qu'il soit sur les deux lignes de notre Grid.
<Flickr:FlickrPhotoDetail x:Name="PhotoDetail" Grid.RowSpan="2" Visibility="Collapsed"/>On met sa visibilité à Collapsed (caché) par défaut.
Maintenant il ne nous reste plus qu'à l'afficher et définir son DataContext quand on clique sur un item de la ListBox.
On s'abonne donc à l'évènement SelectionChanged.
<ListBox x:Name="Photos" Grid.Row="1" DisplayMemberPath="Title" SelectionChanged="Photos_SelectionChanged">Et voici le code-behind.
private void Photos_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
FlickrPhoto photo = (FlickrPhoto)Photos.SelectedItem;
PhotoDetail.DataContext = photo;
PhotoDetail.Visibility = Visibility.Visible;
}Voici le résultat quand on clique sur un item.
Il ne reste plus qu'à rendre le tout plus joli, mais ça, je vous laisse le faire.
IX. Les Templates▲
Silverlight nous permet de customiser l'apparence de nos contrôles à volonté, par exemple un bouton peut ne pas contenir que du texte.
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Source="absolut.jpg" Width="150" Height="150" Margin="10"/>
<TextBlock Text="Click me !" VerticalAlignment="Center" Margin="25"/>
</StackPanel>
</Button.Content>
</Button>Ou même :
<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<Calendar/>
<TextBlock Text="Click me !" VerticalAlignment="Center" Margin="15"/>
</StackPanel>
</Button.Content>
</Button>Maintenant on va voir comment complètement changer l'apparence d'un contrôle. Imaginons que dans toute notre application nous voulions des boutons ayant ce look.
Nous pouvons réaliser cela en ajoutant un style dans notre App.xaml, ou nous allons définir la propriété Template.
<Style x:Key="StarButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Image Source="etoile.png" Width="200" Height="200"/>
<TextBlock Text="Push Me !" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>Et lorsque nous créons un bouton, ça ne change pas :
<Button Style="{StaticResource StarButton}"/>Le problème ici est que la taille et le texte du bouton sont mis en dur dans le code, mais nous pouvons évidemment remédier à ça.
<Style x:Key="StarButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Image Source="etoile.png" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>Maintenant la taille de l'image sera la même que la taille spécifiée lors de la création du bouton.
J'ai aussi modifié le TextBlock par un ContentPresenter, afin de pouvoir mettre n'importe quel contrôle dans notre bouton (comme plus haut avec un calendrier ou une image).
<Button Style="{StaticResource StarButton}" Width="200" Height="200" Content="Push Me !" />Ou encore :
<Button Style="{StaticResource StarButton}" Width="200" Height="200">
<Button.Content>
<Image Source="absolut.jpg" Width="40" Height="40"/>
</Button.Content>
</Button>X. De Silverlight à WPF▲
Dans cette partie nous allons voir comment passer de notre application Silverlight donc Web à une application WPF donc client lourd.
Tout d'abord il faut créer une nouvelle application WPF.
Ensuite il suffit de copier nos fichiers de notre projet Silverlight dans notre nouveau projet WPF (à priori plus tard ce sera automatique).

Une fois ceci fait il faut également changer les namespaces de nos fichiers Silverlight (ceci sera amélioré par la suite).
<UserControl xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
x:Class="FlickrPhotoViewer.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Flickr="clr-namespace:FlickrPhotoViewer;assembly=FlickrPhotoViewer">Devient par exemple :
<UserControl x:Class="FlickrPhotoViewerDesktop.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Flickr="clr-namespace:FlickrPhotoViewerDesktop">Ensuite on ouvre le fichier Window1.xaml et on rajoute ceci :
<Window x:Class="FlickrPhotoViewerDesktop.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Flickr="clr-namespace:FlickrPhotoViewerDesktop"
Title="Window1" Height="300" Width="300">
<Grid>
<Flickr:Page />
</Grid>
</Window>Et voilà nous avons maintenant une application en WPF et ce sans avoir modifié énormément de choses.
XI. L'application en ligne▲
Et voici sans plus attendre le rendu final : FlickrPhotoViewer
XII. Conclusion▲
Comme vous avez pu le voir au fil de cet article, Silverlight 2 n'a plus rien à voir avec Silverlight 1.1. Il se rapproche de plus en plus de WPF et c'est tant mieux. J'espère que les ingénieurs de chez Microsoft nous réserveront encore de bonnes surprises pour la bêta 2 ou même la release.
XIII. Remerciements▲
Merci à The_badger_man et Cardi pour leurs corrections, ainsi qu'à toute l'équipe .NET.


































