Comme vu dans un
précédent post,
OData (Open Data Protocol) est un protocole qui permet d'exposer des données
via HTTP, qui se base sur l'architecture REST et qui fournit des données en XML formatées en ATOM ou JSON. WCF Data Services inclus dans Silverlight 4 va nous permettre d'exploiter ces données exposées par OData.
Le but est de faire une application Silverlight 4 de type Maître - Détail avec une ComboBox qui permet de choisir un client et une DataGrid qui permet d'afficher les commandes de ce client. Pour cela, nous allons utiliser les tables Customers et Orders du flux OData de Northwind qui se trouve à cette adresse :
http://services.odata.org/Northwind/Northwind.svc/Voici ce qu'expose le flux OData de Northwind :

On crée une solution Silverlight 4, et on ajoute au projet Client une référence au service contenant le flux de données
OData de Northwind. Pour cela, nous allons utiliser
WCF Data Services. Un clic-droit sur le projet Silverlight, puis cliquer sur "Add Service Reference". Une boîte de dialogue apparait et dans le champ "Address", on renseigne l'adresse de notre flux
OData mentionné plus haut et on clique sur le bouton "Go" pour vérifier ce qu'expose ce service.

Après avoir cliqué sur le bouton "Ok", on peut observer les éléments de notre solution et en afficher les fichiers cachés. On constate que
WCF Data Services nous a ajouté 3 nouveaux fichiers :
- Reference.datasvcmap : qui est un fichier de configuration rassemblant les informations concernant notre service.
- Reference.cs : qui contient toutes les propriétés et méthodes générées à partir de notre flux.
- service.edmx : qui contient sous la forme d'un Entity Data Model toutes les informations de notre base de données contenues dans notre flux.

Ensuite on peut construire notre interface en XAML qui va nous permettre d'afficher nos données avec un contrôle ComboBox et un contrôle DataGrid :
<UserControl.Resources> <DataTemplate x:Key="DataTemplateComboBoxItelCustomers"> <TextBlock Text="{Binding ContactName}" /> </DataTemplate> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White" > <Grid.RowDefinitions> <RowDefinition Height="40" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ComboBox Grid.Row="0" ItemTemplate="{StaticResource DataTemplateComboBoxItelCustomers}" Name="cbCustomers"
SelectionChanged="cbCustomers_SelectionChanged" />
<sdk:DataGrid AutoGenerateColumns="True" Grid.Row="1" Name="dgOrders" /> </Grid>Du côté du code-behind, on déclare les membres suivant qui vont nous permettre d'utiliser les données de notre service :
private DataServiceCollection<Customer> _customers;
private DataServiceCollection<Order> _orders;
private Customer _selectedCustomer;
private NorthwindEntities _context;Puis dans le
Loaded de notre User Control, on initialise notre context avec notre service et on initialise les objets qui vont nous permettre de stocker les données concernant les Customers et Orders avec des
DataServiceCollection grâce à
WCF Data Services. Une requête Linq va sélectionner tous les Customers et les ordonner par leur ContactName. Et enfin on appelle la méthode
LoadSync afin de récupérer les données grâce à notre requête Linq :
_context = new NorthwindEntities(new Uri("http://services.odata.org/Northwind/Northwind.svc/"));
_customers = new DataServiceCollection<Customer>();
_customers.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(_customers_LoadCompleted);
_orders = new DataServiceCollection<Order>();
_orders.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(_orders_LoadCompleted);
var query = from g in _context.Customers
orderby g.ContactName
select g;
_customers.LoadAsync(query);Lorsque la méthode
LoadAsync est appelée, l'événement
LoadCompleted est appelé ce qui va nous permettre de savoir lorsque le chargement des données est terminé afin de binder les données à nos contrôles :
void _customers_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
if (_customers.Continuation != null)
{
_customers.LoadNextPartialSetAsync();
}
else
{
cbCustomers.ItemsSource = _customers;
cbCustomers.UpdateLayout();
cbCustomers.SelectedIndex = 0;
}
}
void _orders_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
if (_orders.Continuation != null)
{
_orders.LoadNextPartialSetAsync();
}
else
{
dgOrders.ItemsSource = _orders;
dgOrders.UpdateLayout();
}
}Ensuite dans le
SelectionChanged de la ComboBox contenant les Customers, lorsque l'utilisateur choisi un client, son CustomerID va nous servir dans une requête Linq pour sélectionner les commandes lui correspondant. La méthode
LoadAsync va nous permettre de charger ses données :
_orders.Clear();
_selectedCustomer = cbCustomers.SelectedItem as Customer;
if (_selectedCustomer != null)
{
var query = from g in _context.Orders
where g.CustomerID == _selectedCustomer.CustomerID
select g;
_orders.LoadAsync(query);
} Et voici ce que l'on obtient au final :

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :