Publié dimanche 14 mars 2010 22:15 par Audrey

[RIA Services] Maitre - Détail et DomainDataSource


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 RC2

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

Northwind

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 :

Maitre Detail Ria Services SL

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 :

Les 10 derniers blogs postés

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01

- SharePoint Online: Script PowerShell pour supprimer une colonne dans tous les sites d’une collection par Blog Technique de Romelard Fabrice le 11-27-2018, 18:01