Publié
dimanche 14 mars 2010 22:15
par
Audrey
A l'occasion d'un projet client, j'ai utilisé RIA Services avec Silverlight 3 (mais cela fonctionne aussi avec la version 4), et je l'ai utilisé pour une interface façon Maitre / Détail. Voici comment j'ai procédé pour arriver à mes fins.
Mise à jour avec Silverlight 4 RTW et RIA Services RC2Nous allons prendre pour notre exemple la base de données Northwind avec ses tables Customers et Orders, et générer un ADO.NET Entity Data Model via Entity Framework :

Voici l'interface que l'on souhaite réaliser, une ComboBox et une DataGrid. Suivant le client (Customers) sélectionné dans la ComboBox, les commandes correspondantes (Orders) s'afficheront dans la DataGrid :

Pour réaliser cela, je me suis servie des
DomainDataSource fournis par WCF RIA Services. Ils permettent de relier facilement avec du code XAML les interfaces utilisateurs et les données exposées via un DomainService.
Dans notre projet Silverlight, il ne faut pas oublier d'ajouter les espaces de noms dont on a besoin :
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Ria"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:domain="clr-namespace:RIADomainSourceParam.Web"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:data="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:domain="clr-namespace:RIADomainSourceParam.Web"
-
System.Windows.Controls.Ria : pour utiliser les DomainDataSource
-
System.Windows.Controls.Data : pour pouvoir utiliser la DataGrid
-
RIADomainSourceParam.Web : le projet Web qui contient le DomainService déclarer auparavant qui va nous permettre d'interroger notre Entity Data Model.
-
System.Windows.Controls.DomainServices : pour utiliser les
DomainDataSource
-
RIADomainSourceParam.Web :
le projet Web qui contient le DomainService déclarer auparavant qui va
nous permettre d'interroger notre Entity Data Model.
Ensuite il faut déclarer un premier
DomainDataSource pour la ComboBox :
<
riaControls:DomainDataSource x:Name="sourceCustomers" QueryName="GetCustomers" AutoLoad="True">
<riaControls:DomainDataSource.DomainContext>
<domain:NorthwindContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<ComboBox x:Name="CbCustomers" ItemsSource="{Binding Data,ElementName=sourceCustomers}"
ItemTemplate="{StaticResource DataTemplateComboBoxItelCustomers}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0"
SelectionChanged
="C
bCustomers_SelectionChanged" />
Dans les propriétés de notre DomainDataSource, on renseigne QueryName avec le nom de la requête générée et exposée par et dans notre DomainService, ici "GetCustomers", afin de lister tous les clients présents dans la table Customers.
public IQueryable<Customers> GetCustomers()
{
return this.ObjectContext.Customers;
}
La propriété AutoLoad par défaut à "true" permet de charger les données automatiquement au chargement de l'interface. Ensuite, on renseigne le DomainContext, ici à "NorthwindContext".
Pour la ComboBox, on effectue le binding suivant pour la propriété ItemsSource, en faisant un lien vers le nom de notre DomainDataSource "sourceCustomers". Puis on abonne notre contrôle à l'évènement SelectionChanged afin de pouvoir savoir lorsque l'utilisateur sélectionne un client.
Et voilà notre ComboBox est maintenant reliée à nos données et elle peut afficher tous les noms des clients de la base de données !
Ensuite nous souhaitons mettre à jour notre DataGrid suivant le client sélectionné. Pour cela, il va falloir d'abord écrire une requête Linq permettant de sélectionner toutes les commandes de ce client. Pour cela, nous allons ajouter une méthode dans notre DomainService :
public IQueryable<Orders> GetOrdersWithParams(string myCustomerID)
{
var query = from cust in this.ObjectContext.Orders
where cust.CustomerID == myCustomerID
select cust;
return query;
}
Notre méthode prend en paramètre une chaine de caractère correspondant à l'identifiant du client sélectionné. Nous allons pouvoir déclarer un nouveau DomainDataSource pour notre DataGrid.
<riaControls:DomainDataSource x:Name="sourceOrders" QueryName="GetOrdersWithParams" AutoLoad="False">
<riaControls:DomainDataSource.QueryParameters>
<riaControls:ControlParameter ParameterName="myCustomerID"
ControlName="CbCustomers"
PropertyName="SelectedItem.CustomerID"
RefreshEventName="SelectionChanged"/>
</riaControls:DomainDataSource.QueryParameters>
<riaControls:DomainDataSource.DomainContext>
<domain:NorthwindContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource >
<riaControls:DomainDataSource x:Name="sourceOrders" QueryName="GetOrdersWithParams" AutoLoad="False">
<riaControls:DomainDataSource.QueryParameters>
<riaControls:Parameter ParameterName="myCustomerID"
Value="{Binding ElementName=
CbCustomers
, Path=SelectedItem.CustomerID}" />
</riaControls:DomainDataSource.QueryParameters>
<riaControls:DomainDataSource.DomainContext>
<domain:NorthwindContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<data:DataGrid x:Name="DgOrders" ItemsSource="{Binding Data, ElementName=sourceOrders}"
AutoGenerateColumns="true" Grid.Row="1" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
On renseigne la propriété
QueryName avec le nom de la méthode que
l'on a déclaré auparavant "GetOrdersWithParams". La propriété
AutoLoad
est mise à "false", afin de ne charger les informations des commandes seulement lorsque
l'utilisateur aura lui même sélectionné un client. Au déclenchement de l'évènement
SelectionChanged de notre ComboBox, nous pourrons alors effectuer le Load du
DomainDataSource :
private void CbCustomers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
sourceOrders.Load();
}On ajoute ensuite le bloc
DomainDataSource.QueryParameters dans notre DomainDataSource afin de pouvoir renseigner le paramètre qui va être utilisé dans notre requête Linq. Pour cela on renseigne les propriétés suivantes :
ParameterName : le nom du paramètre dans notre méthode myCustomerID
ControlName : le contrôle d'où vient la valeur du paramètre, ici notre ComboBox CbCustomers
PropertyName : la propriété de notre contrôle contenant la valeur, ici SelectedItem.CustomerID
RefreshEventName : l'évènement permettant la mise à jour de la valeur du paramètre, ici SelectionChanged
- ParameterName : le nom du paramètre dans notre méthode myCustomerID
- Value : permet de donner la valeur du paramètre soit en passant une valeur soit en bindant avec la propriété d'un contrôle ici notre ComboBox
Puis on renseigne de la même manière que le précédent
DomainContext à la valeur "NorthwindContext". Puis nous pouvons effectuer le binding de notre DataGrid, avec sa propriété
ItemsSource en renseignant l'ElementName avec le nom de notre
DomainDataSource "sourceOrders".
Et voilà ! Du XAML et une seule ligne de code-behind pour une interface Maitre-Détail !
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 :