Procédure pas à pas : Présentation des Services RIA

Cette procédure pas à pas présente un grand nombre de fonctionnalités des Services RIA WCF. Vous y créerez une application Services RIA qui récupère des données depuis les tables de l'exemple de base de données AdventureWorks OLTP. Vous commencerez par récupérer les données en spécifiant le LoadOperation. Vous récupèrerez ensuite ces données à l'aide du contrôle DomainDataSource. Vous spécifierez le tri, le filtrage et la pagination du contrôle de présentation des données et vous ajouterez un contrôle DataForm pour présenter une vue détaillée des données. Vous appliquerez des règles de validation aux champs et vous autoriserez l'utilisateur à modifier la valeur des données. Vous limiterez l'accès d'une opération de domaine aux utilisateurs authentifiés. Enfin, vous définirez l'association entre deux tables associées et afficherez les données liées.

TipConseil :
Pour voir des procédures pas à pas plus courtes et commencer en créant une solution Services RIA plus basique, consultez Procédure pas à pas : Création d'une solution de Services RIA ou Procédure pas à pas : Utilisation du modèle Application métier Silverlight.

Configuration requise

Cette procédure pas à pas, ainsi que les autres procédures du même type présentées dans la documentation des Services RIA WCF, nécessite au préalable l'installation et la configuration correctes de plusieurs programmes, tels que Visual Studio 2010 et le Developer Runtime et SDK Silverlight, en plus des Services RIA WCF et du kit de ressources des Services RIA WCF. Ces procédures nécessitent également l'installation et la configuration de SQL Server 2008 R2 Express with Advanced Services et l'installation de la base de données AdventureWorks OLTP et LT.

Vous trouverez des instructions détaillées pour satisfaire chacune de ces conditions préalables dans les rubriques du nœud Conditions préalables pour les Services RIA WCF. Suivez ces instructions avant de poursuivre, pour être sûr de rencontrer le moins de problèmes possibles en effectuant ces procédures pas à pas des Services RIA .

Création et installation de la solution

Dans cette section, vous allez créer et configurer la solution.

Pour créer une application WCF RIA Services

  1. Dans Visual Studio 2010, créez un projet Services RIA en sélectionnant Fichier, Nouveau, puis Projet.

    La boîte de dialogue Nouveau projet s'affiche.

  2. Dans le volet Modèles installés, développez le nœud Visual Basic ou Visual C# et sélectionnez la catégorie Silverlight.

  3. Sélectionnez le modèle Application métier Silverlight et nommez l'application HRApp.

    RIA_HRAppStart

  4. Cliquez sur OK.

    Observez la structure de la solution ainsi créée :

    • La solution comporte deux projets : un projet client Silverlight nommé HRApp et un projet serveur d'application Web ASP.NET nommé HRApp.Web.

    • La solution par défaut contient un grand nombre de fonctionnalités automatiquement implémentées, dont la navigation, la connexion/ déconnexion des utilisateurs et l'enregistrement des nouveaux utilisateurs.

    RIA_HRAppStructure

  5. Générez et exécutez (F5) l'application, puis explorez l'implémentation par défaut.

  6. Fermez votre navigateur Web.

Pour configurer l'application

  1. Dans l'Explorateur de solutions, dans le projet client, ouvrez MainPage.xaml.

  2. Dans la vue XAML, trouvez le TextBlock nommé ApplicationNameTextBlock.

    Comme le montre le balisage suivant, vous pouvez voir que le nom de l'application est récupéré depuis une ressource.

    <TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}" 
                       Text="{Binding ApplicationStrings.ApplicationName, Source={StaticResource ResourceWrapper}}"/>
    
  3. Dans l'Explorateur de solutions, développez le dossier Assets, puis le dossier Resources.

  4. Ouvrez le fichier ApplicationStrings.resx.

  5. Modifiez la ressource ApplicationName en HR Application.

  6. Enregistrez et fermez le fichier ApplicationStrings.resx.

  7. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le dossier Views, puis cliquez sur Ajouter et sur Nouvel élément.

    La boîte de dialogue Ajouter un nouvel élément s'affiche.

  8. Sélectionnez le modèle Page Silverlight de la catégorie Silverlight des Modèles installés et nommez-le EmployeeList.xaml.

    RIA_HRAppAddPage

  9. Cliquez sur Ajouter.

  10. Ouvrez EmployeeList.xaml s'il ne s'ouvre pas automatiquement.

  11. Ajoutez le XAML suivant entre les balises <Grid>.

    <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource 
      PageScrollViewerStyle}" >
        <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
    
            <TextBlock Text="Employee List" Style="{StaticResource HeaderTextStyle}"/>
    
        </StackPanel>
    </ScrollViewer>
    
  12. Enregistrez le fichier EmployeeList.xaml.

  13. Ouvrez MainPage.xaml.

  14. Ajoutez un nouveau bouton de lien hypertexte en haut de la page en ajoutant le XAML suivant entre les deux boutons de lien hypertexte existants.

    <HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}" NavigateUri="/EmployeeList" TargetName="ContentFrame" Content="Employee List"/>
    
    <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
    
  15. Exécutez l'application et notez le nouveau lien Liste des employés à l'angle supérieur droit de la page, entre les liens Accueil et À propos de. Cliquez sur ce lien pour afficher « Liste des employés » dans le corps de la page.

    RIA_HRAppPageView

Affichage de données

Dans cette section, vous allez créer un ADO.NET Entity Data Model pour les tables de l'exemple de base de données AdventureWorks. Vous allez ensuite créer un service de domaine qui expose les entités et affiche ces données dans le projet client.

Pour ajouter une source de données

  1. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le projet HRApp.Web, puis cliquez sur Ajouter et sur Nouvel élément.

    La boîte de dialogue Ajouter un nouvel élément s'affiche.

  2. Dans la catégorie Données, sélectionnez le modèle ADO.NET Entity Data Model.

    RIA_HRAppAddEntity

  3. Donnez-lui le nom AdventureWorks.edmx, puis cliquez sur Ajouter.

    L'Assistant Entity Data Model s'ouvre.

  4. Sur la page Choisir le contenu du modèle, cliquez sur Générer à partir de la base de données, puis sur Suivant.

  5. Sur la page Choisir votre connexion de données, créez une connexion à la base de données AdventureWorks.

  6. Nommez les paramètres de connexion de l'entité AdventureWorks_DataEntities puis cliquez sur Suivant.

  7. Sur la page Choisir vos objets de base de données, développez le nœud Tables.

  8. Ajoutez des coches devant les tables Employé, PurchaseOrderDetailet PurchaseOrderHeader.

  9. Nommez l'espace de noms du modèle AdventureWorks_DataModel, puis cliquez sur Terminer.

    L'Entity Data Model s'affiche dans le concepteur.

  10. Générez la solution.

Pour ajouter un objet service de domaine et transmettre une requête de données

  1. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le projet HRApp.Web, puis cliquez sur Ajouter et sur Nouvel élément.

    La boîte de dialogue Ajouter un nouvel élément s'affiche.

  2. Dans la catégorie Web, sélectionnez le modèle Classe DomainService.

    RIA_HRAppAddService

  3. Nommez le nouvel article OrganizationService.

  4. Cliquez sur Ajouter.

  5. Dans la boîte de dialogue Ajouter une nouvelle classe de service de domaine, sélectionnez Employé, PurchaseOrderDetail et PurchaseOrderHeader dans la liste Entités, puis sélectionnez Activer la modification pour chaque entité.

  6. Vérifiez que les cases à cocher Activer l'accès client et Générer des classes associées pour les métadonnées sont activées.

  7. Cliquez sur OK.

    Les fichiers OrganizationService.cs/vb et OrganizationService.metadata.cs/vb sont ajoutés au projet.

  8. Ouvrez le fichier OrganizationService.cs/vb.

    Remarquez que les méthodes de requête, d'insertion, de mise à jour et de suppression ont été créées pour chaque entité. Une méthode de requête est toujours créée pour une entité. Les méthodes d'insertion, de mise à jour et de suppression ont été ajoutées parce qu'Activer la modification a été sélectionné.

  9. Personnalisez la méthode de requête GetEmployees() pour retourner des employés triés par EmployeeID en remplaçant le code généré par le code suivant.

    Public Function GetEmployees() As IQueryable(Of Employee)
        Return Me.ObjectContext.Employees.OrderBy(Function(e) e.EmployeeID)
    End Function
    
    public IQueryable<Employee> GetEmployees()
    {
        return this.ObjectContext.Employees.OrderBy(e => e.EmployeeID);
    }
    
  10. Générez la solution.

    La construction de la solution génère le contexte de domaine et les entités dans le projet client.

  11. Ouvrez EmployeeList.xaml.

  12. Depuis la boîte à outils, faites glisser un contrôle DataGrid vers le mode Design juste après le contrôle TextBlock.

    Faire glisser un DataGrid vers le mode Design permet d'ajouter une référence à l'assembly System.Windows.Controls.Data et d'ajouter le préfixe sdk à l'élément Page.

  13. Changez les valeurs par défaut du contrôle DataGrid en supprimant les propriétés Hauteur et Largeur, en le transformant en contrôle en lecture seule, en le paramétrant pour qu'il génère automatiquement des colonnes et en fixant sa hauteur au minimum.

    <sdk:DataGrid AutoGenerateColumns="True" IsReadOnly="True" Name="dataGrid1" MinHeight="100" />
    
  14. Enregistrez EmployeeList.xaml.

  15. Ouvrez EmployeeList.xaml.cs/vb.

  16. Ajoutez les instructions using ou Imports suivantes.

    Imports System.ServiceModel.DomainServices.Client
    
    using HRApp.Web;
    using System.ServiceModel.DomainServices.Client;
    
  17. Créez la classe OrganizationContext et chargez les données employé en ajoutant le code suivant à EmployeeList.xaml.cs/vb.

    La classe OrganizationContext est automatiquement générée dans le projet client d'après la classe OrganizationService du projet serveur.

    Partial Public Class EmployeeList
        Inherits Page
    
        Dim _OrganizationContext As New OrganizationContext
        Public Sub New()
            InitializeComponent()
            Me.dataGrid1.ItemsSource = _OrganizationContext.Employees
            _OrganizationContext.Load(_OrganizationContext.GetEmployeesQuery())
        End Sub
    
        'Executes when the user navigates to this page.
        Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    
        End Sub
    End Class
    
    public partial class EmployeeList : Page
    {
        OrganizationContext _OrganizationContext = new OrganizationContext();
        public EmployeeList()
        {
            InitializeComponent();
            this.dataGrid1.ItemsSource = _OrganizationContext.Employees;
            _OrganizationContext.Load(_OrganizationContext.GetEmployeesQuery());
        }
    
        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }
    }
    
  18. Exécutez l'application.

  19. Cliquez sur le lien Liste des employés pour consulter le DataGrid.

    RIA_HRAppDataGrid

Pour ajouter une requête personnalisée

  1. Dans le projet HRApp.Web, ouvrez OrganizationService.cs/vb.

  2. Ajoutez une nouvelle méthode nommée GetSalariedEmployees en ajoutant le code suivant au corps de la classe.

    Public Function GetSalariedEmployees() As IQueryable(Of Employee)
        Return Me.ObjectContext.Employees.Where(Function(e) e.SalariedFlag = True).OrderBy(Function(e) e.EmployeeID)
    End Function
    
    public IQueryable<Employee> GetSalariedEmployees()
    {
        return this.ObjectContext.Employees.Where(e => e.SalariedFlag == true).OrderBy(e => e.EmployeeID);
    }
    
  3. Générez la solution.

  4. Dans le projet client, ouvrez EmployeeList.xaml.cs/vb.

  5. Dans le constructeur, remplacez l'appel à GetEmployeesQuery() par un appel à GetSalariedEmployeesQuery().

    _OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
    
    _OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
    
  6. Exécutez l'application et cliquez sur le lien Liste des employés.

    Remarquez que la valeur SalariedFlag est activée pour tous les employés affichés. Les employés dont l'ID est EmployeeID 1, 2 et 4 n'apparaissent plus dans la liste parce qu'ils ne sont pas salariés.

    RIA_HRAppFilteredDataGrid

Pour ajouter une source de données de domaine

  1. Ouvrez EmployeeList.xaml.

  2. Depuis la Boîte à outils, faites glisser le contrôle DomainDataSource vers le mode Design, juste avant le DataGrid. Le DomainDataSource peut apparaître au bas de la liste des contrôles.

    TipConseil :
    Si le contrôle DomainDataSource ne se trouve pas dans la Boîte à outils, cliquez avec le bouton droit dans la Boîte à outils et cliquez sur Choisir les éléments. Sous l'onglet Composants Silverlight, activez la case à cocher DomainDataSource et cliquez sur OK.

    Lorsque vous faites glisser le contrôle DomainDataSource vers le mode Design, une référence portant le préfixe riaControls est créée pour l'espace de noms System.Windows.Controls dans l'élément Page. Une icône de source de données s'affiche également dans l'angle inférieur gauche du mode Design.

  3. Pour les solutions C#, ajoutez la déclaration d'espace de noms suivante au fichier XAML.

    xmlns:ds="clr-namespace:HRApp.Web"
    
  4. Pour les solutions Visual Basic, ajoutez la déclaration d'espace de noms suivante au fichier XAML.

    xmlns:ds="clr-namespace:HRApp"
    
  5. Nommez le contrôle employeeDataSourceDomainDataSource et paramétrez les méthodes LoadSize, AutoLoad et la méthode de requête en remplaçant le XAML existant par le XAML suivant.

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
    </riaControls:DomainDataSource>
    
  6. Paramétrez le DomainContext du DomainDataSource en ajoutant le XAML suivant.

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
        <riaControls:DomainDataSource.DomainContext>
            <ds:OrganizationContext/>
        </riaControls:DomainDataSource.DomainContext>
    </riaControls:DomainDataSource>
    
  7. Remplacez DataGrid par le XAML suivant :

    <sdk:DataGrid AutoGenerateColumns="True" IsReadOnly="True" Name="dataGrid1" MinHeight="100" Height="Auto" ItemsSource="{Binding Data, ElementName=employeeDataSource}" />
    
  8. Ouvrez EmployeeList.xaml.cs/vb.

  9. Dans le constructeur, supprimez ou commentez le code afin de créer l'instance OrganizationContext, l'appel à GetSalariedEmployeesQuery() et le code permettant de paramétrer la propriété ItemsSource du contrôle DataGrid.

    Vous n'avez plus besoin de charger explicitement les données puisque le DomainDataSource le fera automatiquement.

    'Dim _OrganizationContext As New OrganizationContext
    Public Sub New()
        InitializeComponent()
        'Me.dataGrid1.ItemsSource = _OrganizationContext.Employees
        '_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
    
    End Sub
    
    //OrganizationContext _OrganizationContext = new OrganizationContext();
    public EmployeeList()
    {
        InitializeComponent();
        //this.dataGrid1.ItemsSource = _OrganizationContext.Employees;
        //_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
    }
    
  10. Exécutez l'application et cliquez sur le lien Liste des employés.

    L'application fonctionne de la même façon qu'auparavant.

Pour ajouter des fonctions de tri, de filtrage et de pagination à la source de données

  1. Ouvrez EmployeeList.xaml.

  2. Dans le DomainDataSource, ajoutez le SortDescriptors suivant pour spécifier la façon dont les données sont triées dans le DataGrid.

    Ce XAML montre comment trier la colonne VacationHours par ordre croissant.

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
        <riaControls:DomainDataSource.DomainContext>
            <ds:OrganizationContext/>
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.SortDescriptors>
            <riaControls:SortDescriptor PropertyPath="VacationHours" Direction="Ascending" />
        </riaControls:DomainDataSource.SortDescriptors>
    </riaControls:DomainDataSource>
    
  3. Exécutez l'application et cliquez sur le lien Liste des employés.

    Les données sont triées par VacationHours et vous pouvez changer le sens de tri en cliquant sur l'en-tête de colonne.

  4. Ouvrez EmployeeList.xaml.

  5. Pour autoriser l'utilisateur à filtrer les enregistrements retournés en fournissant une valeur, ajoutez le XAML suivant avant le DataGrid.

    Le XAML ajoute un contrôle TextBox afin que l'utilisateur puisse entrer une valeur.

    <StackPanel Orientation="Horizontal" 
      HorizontalAlignment="Left">
        <TextBlock VerticalAlignment="Center" 
        Text="Min Vacation Hours Filter" />
        <TextBox x:Name="vacationHoursText" Width="75" 
      FontSize="11" Margin="4" Text="0"/>
    </StackPanel>
    
  6. Dans le DomainDataSource, ajoutez un descripteur de filtre lié au contrôle TextBox que vous avez ajouté à l'étape précédente.

    <riaControls:DomainDataSource.FilterDescriptors>
        <riaControls:FilterDescriptor 
             PropertyPath="VacationHours" 
             Operator="IsGreaterThanOrEqualTo"
             IgnoredValue=""
             Value="{Binding ElementName=vacationHoursText, Path=Text}"  >
        </riaControls:FilterDescriptor>
    </riaControls:DomainDataSource.FilterDescriptors>
    
  7. Exécutez l'application et cliquez sur le lien Liste des employés.

  8. Dans la zone de texte Filtre Heures absence min., tapez 70.

    Remarquez que les employés figurant dans la liste ont une valeur VacationHours supérieure ou égale à 70.

    RIA_HRAppVacationFilter

  9. Ouvrez EmployeeList.xaml.

  10. Depuis la Boîte à outils, faites glisser un contrôle DataPager juste sous le DataGrid.

  11. Donnez à la taille de page la valeur 5 et paramétrez la source comme dans le XAML suivant.

    <sdk:DataPager PageSize="5" Source="{Binding Data, ElementName=employeeDataSource}" HorizontalAlignment="Left" />
    
  12. Exécutez l'application et cliquez sur le lien Liste des employés.

    Vous ne voyez plus que 5 lignes de données filtrées par page et les contrôles Pager au-dessous du DataGrid.

    RIA_HRAppPagedData

Création d'un affichage maître/détaillé

Dans cette section, vous allez utiliser le contrôle DataForm du kit de ressources Silverlight pour fournir une vue détaillée des données. Par défaut, le modèle de projet Application métier Silverlight contient le binaire System.Windows.Controls.Data.DataForm.Toolkit.dll dans le dossier Libs.

Pour ajouter un DataForm

  1. Ouvrez EmployeeList.xaml.

  2. Ajoutez la déclaration d'espace de noms suivante.

    xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
    
  3. Après le contrôle DataPager, ajoutez le XAML suivant pour ajouter un contrôle DataForm.

    Ce XAML définit les attributs DataForm et spécifie les colonnes à afficher.

    <dataForm:DataForm x:Name="dataForm1" Header="Employee Information"
            AutoGenerateFields="False" HorizontalAlignment="Left"
            AutoEdit="False" AutoCommit="False" Width="400"
            CurrentItem="{Binding SelectedItem, ElementName=dataGrid1}" Margin="0,12,0,0">
        <dataForm:DataForm.EditTemplate>
            <DataTemplate>
                <StackPanel>
                    <dataForm:DataField Label="Employee ID">
                        <TextBox IsReadOnly="True" 
                  Text="{Binding EmployeeID, Mode=OneWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Login ID">
                        <TextBox Text="{Binding LoginID, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Hire Date">
                        <TextBox Text="{Binding HireDate, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Marital Status">
                        <TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Gender">
                        <TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Vacation Hours">
                        <TextBox Text="{Binding VacationHours, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Sick Leave Hours">
                        <TextBox Text="{Binding SickLeaveHours, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Active">
                        <CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                </StackPanel>
            </DataTemplate>
        </dataForm:DataForm.EditTemplate>
    </dataForm:DataForm>
    
  4. Exécutez l'application et cliquez sur le lien Liste des employés.

    Le DataForm affiche le détail des éléments sélectionnés dans le DataGrid.

    RIA_HRAppDataForm

Mise à jour de la base de données

Si vous sélectionnez la case à cocher Activer la modification dans la boîte de dialogue Nouvelle classe de service de domaine, des méthodes sont générées dans la couche de service de domaine pour mettre à jour, insérer et supprimer l'entité. Dans cette section, vous allez ajouter des boutons d'édition à l'interface utilisateur de la liste des employés afin d'autoriser les utilisateurs à exécuter ces opérations.

Pour mettre à jour un enregistrement

  1. Ouvrez le fichier EmployeeList.xaml.

  2. Après le contrôle DataForm, ajoutez le XAML suivant pour ajouter un bouton Envoyer.

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,12,0,0">
        <Button x:Name="submitButton" Width="75" Height="23"  
            Content="Submit" Margin="4,0,0,0" Click="submitButton_Click"/>
    </StackPanel>
    
  3. Dans le contrôle DomainDataSource, spécifiez un gestionnaire d'événements pour l'événement SubmittedChanges.

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True" SubmittedChanges="employeeDataSource_SubmittedChanges">
    
  4. Ouvrez EmployeeList.xaml.cs/vb.

  5. Ajoutez le gestionnaire d'événements suivant pour l'événement de clic sur le bouton.

    Le submitButton est désactivé pour empêcher l'utilisateur de soumettre la modification une nouvelle fois, puisque l'opération est déjà traitée.

    Private Sub submitButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        submitButton.IsEnabled = False
        employeeDataSource.SubmitChanges()
    End Sub
    
    private void submitButton_Click(object sender, RoutedEventArgs e)
    {
        submitButton.IsEnabled = false;
        employeeDataSource.SubmitChanges();
    }
    
  6. Ajoutez un gestionnaire d'événements pour l'événement SubmittedChanges qui vérifie si l'opération d'envoi a réussi et qui active submitButton.

    Private Sub employeeDataSource_SubmittedChanges(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SubmittedChangesEventArgs)
        If (e.HasError) Then
            MessageBox.Show(String.Format("Changes were not saved: {0}", e.Error.Message))
            e.MarkErrorAsHandled()
        End If
        submitButton.IsEnabled = True
    End Sub
    
    private void employeeDataSource_SubmittedChanges(object sender, SubmittedChangesEventArgs e)
    {
        if (e.HasError)
        {
            MessageBox.Show(string.Format("Changes were not saved: {0}", e.Error.Message));
            e.MarkErrorAsHandled();
        }
        submitButton.IsEnabled = true;
    }
    
  7. Exécutez l'application et cliquez sur le lien Liste des employés.

  8. Sélectionnez un employé et cliquez sur l'icône crayon, à l'angle supérieur droit du formulaire de données, pour autoriser les modifications.

    Vous pouvez maintenant modifier tous les champs modifiables.

  9. Apportez des modifications aux données des employés et cliquez sur OK.

  10. Cliquez sur le bouton Envoyer pour enregistrer les données.

    Les modifications ne sont enregistrées que sur la base de données du serveur lorsque vous cliquez sur le bouton Envoyer.

Pour ajouter des méthodes personnalisées à un service de domaine

  1. Dans le projet serveur HRApp.Web, ouvrez OrganizationService.cs/vb. Fichier

  2. Ajoutez la méthode personnalisée suivante nommée ApproveSabbatical.

    Public Sub ApproveSabbatical(ByVal current As Employee)
        Me.ObjectContext.Employees.AttachAsModified(current)
        current.CurrentFlag = False
    End Sub
    
    public void ApproveSabbatical(Employee current)
    {
        // Start custom workflow here
        this.ObjectContext.Employees.AttachAsModified(current);
        current.CurrentFlag = false;
    }
    
  3. Générez la solution.

  4. Ouvrez EmployeeList.xaml.

  5. Après avoir ajouté le bouton Envoyer, ajoutez le XAML suivant pour ajouter un bouton Approuver un congé sabbatique.

    <Button x:Name="approveSabbatical" Width="115" Height="23"  Content="Approve Sabbatical"  Margin="4,0,0,0" Click="approveSabbatical_Click"/>
    
  6. Ouvrez EmployeeList.xaml.cs/vb.

  7. Ajoutez le gestionnaire d'événements suivant pour l'événement de clic sur le bouton qui appelle l'opération de domaine ApproveSabbatical.

    Private Sub approveSabbatical_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim luckyEmployee As Employee
        luckyEmployee = dataGrid1.SelectedItem
        luckyEmployee.ApproveSabbatical()
        employeeDataSource.SubmitChanges()
    End Sub
    
    private void approveSabbatical_Click(object sender, RoutedEventArgs e)
    {
        Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
        luckyEmployee.ApproveSabbatical();
        employeeDataSource.SubmitChanges();
    }
    
  8. Exécutez l'application et cliquez sur le lien Liste des employés.

  9. Cliquez sur le bouton Approuver un congé sabbatique et notez que la case à cocher CurrentFlag est désactivée pour l'employé sélectionné.

Validation des données

Le contrôle DataForm peut afficher les erreurs de validation depuis la couche Data Access (DAL). Par exemple, si vous entrez une valeur non-entière dans le champ VacationHours, une erreur de validation s'affiche. L'illustration suivante donne un exemple de comportement de validation.

RIA_HRAppValidation

Si vous activez la case à cocher Générer des classes associées pour les métadonnées dans la boîte de dialogue Ajouter une nouvelle classe de service de domaine, un fichier contenant les métadonnées est créé. Dans cette procédure pas à pas, le fichier de métadonnées s'appelle OrganizationService.metadata.cs/vb. Dans cette section, vous allez ajouter des attributs de validation à ce fichier. Les règles de validation seront imposées dans les projets serveur et client.

Vous allez également créer une interface utilisateur qui permettra d'ajouter des enregistrements d'employés dans la base de données. Les règles de validation que vous avez ajoutées dans les sections précédentes seront automatiquement appliquées dans la nouvelle interface utilisateur.

Pour ajouter la validation de base

  1. Dans le projet serveur HRApp.web, ouvrez OrganizationService.metadata.cs/vb.

  2. Ajoutez les attributs suivants aux propriétés Gender et VacationHours.

    <Required()> _
    Public Property Gender As String
    
    <Range(0, 70)> _
    Public Property VacationHours As Short
    
    [Required]
    public string Gender { get; set; }
    
    [Range(0, 70)]
    public short VacationHours { get; set; }
    
  3. Générez la solution.

  4. Exécutez l'application et cliquez sur le lien Liste des employés.

  5. Sélectionnez un employé et cliquez sur l'icône crayon, à l'angle supérieur droit du formulaire de données, pour autoriser les modifications.

  6. Entrez dans le champ Heures absence une valeur qui ne soit pas comprise dans la gamme valide (0-70) et déplacez le focus vers un autre contrôle.

    Vous voyez apparaître une erreur de validation pour les heures d'absence.

    RIA_HRAppRangeValidation

  7. Supprimez la valeur dans le champ Sexe et déplacez le focus vers un autre contrôle.

    Vous voyez apparaître une erreur de validation pour le sexe.

Pour ajouter une validation personnalisée

  1. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le projet HRApp.Web, puis cliquez sur Ajouter et sur Nouvel élément.

    La boîte de dialogue Ajouter un nouvel élément s'affiche.

  2. Dans la catégorie Code, sélectionnez le modèle Fichier de code.

  3. Nommez le nouvel élément OrganizationService.shared.cs ou OrganizationService.shared.vb.

    Les fichiers se terminant par .shared.cs ou .shared.vb sont disponibles à la fois dans le projet serveur et le projet client. Les fichiers partagés vous permettent d'exécuter la même règle de validation dans les deux projets. Après avoir construit la solution dans une étape ultérieure, regardez sur le client dans le dossier caché Generated_Code. Vous y verrez le fichier OrganizationService.shared.cs/vb.

  4. Cliquez sur Ajouter.

  5. Pour créer une classe de validation personnalisée qui vérifie les valeurs affectées à la propriété Gender, ajoutez le code suivant au fichier partagé.

    Imports System
    Imports System.ComponentModel.DataAnnotations
    
    Public Module GenderValidator
        Public Function IsGenderValid(ByVal gender As String, ByVal context As ValidationContext) As ValidationResult
            If gender = "M" OrElse gender = "m" OrElse gender = "F" OrElse gender = "f" Then
                Return ValidationResult.Success
            Else
                Return New ValidationResult("The Gender field only has two valid values 'M'/'F'", New String() {"Gender"})
            End If
        End Function
    End Module
    
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace HRApp.Web
    {
        public static class GenderValidator
        {
            public static ValidationResult IsGenderValid(string gender, ValidationContext context)
            {
                if (gender == "M" || gender == "m" || gender == "F" || gender == "f")
                {
                    return ValidationResult.Success;
                }
                else
                {
                    return new ValidationResult("The Gender field only has two valid values 'M'/'F'", new string[] { "Gender" });
                }
            }
        }
    }
    
  6. Ouvrez OrganizationService.metadata.cs/vb.

  7. Ajoutez l'attribut de validation personnalisée suivant à la propriété Gender.

    <Required()> _
    <CustomValidation(GetType(GenderValidator), "IsGenderValid")> _
    Public Property Gender As String
    
    [CustomValidation(typeof(HRApp.Web.GenderValidator), "IsGenderValid")]
    [Required]
    public string Gender { get; set; }
    
  8. Générez la solution.

  9. Exécutez l'application et cliquez sur le lien Liste des employés.

  10. Sélectionnez un employé et cliquez sur l'icône crayon, à l'angle supérieur droit du formulaire de données, pour autoriser les modifications.

  11. Entrez une valeur dans le champ Sexe qui ne soit ni M ni F et déplacez le focus vers un autre contrôle.

    Le résultat de la validation personnalisée s'affiche.

    RIA_HRAppCustomValidation

Ajout de nouveaux enregistrements

Dans cette section, vous allez ajouter un formulaire qui permet à l'utilisateur de créer un enregistrement dans la table Employé.

Pour ajouter un enregistrement

  1. Dans le projet HRApp, ajoutez un nouvel élément.

  2. Dans la catégorie Silverlight, sélectionnez le modèle Fenêtre enfant Silverlight.

  3. Nommez le nouvel élément EmployeeRegistrationWindow.xaml.

    RIA_HRAppAddChildWindow

  4. Cliquez sur Ajouter.

  5. Ouvrez EmployeeRegistrationWindow.xaml.cs/vb.

  6. Si vous utilisez C#, ajoutez l'instruction using suivante.

    using HRApp.Web;
    
  7. Ajoutez une propriété pour la nouvelle entité Employee créée avec les valeurs utilisateur.

    Public Property NewEmployee As Employee
    
    public Employee NewEmployee { get; set; }
    
  8. Ouvrez EmployeeRegistrationWindow.xaml.

  9. Ajoutez la déclaration d'espace de noms suivante à EmployeeRegistrationWindow.xaml pour pouvoir utiliser le contrôle DataForm dans cette fenêtre.

    xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
    
  10. Ajoutez le contrôle DataForm suivant à EmployeeRegistrationWindow.xaml juste avant le bouton Annuler.

    <dataForm:DataForm x:Name="addEmployeeDataForm"   AutoGenerateFields="False" AutoCommit="True" AutoEdit="True" CommandButtonsVisibility="None">
        <dataForm:DataForm.EditTemplate>
            <DataTemplate>
                <StackPanel>
                    <dataForm:DataField Label="Login ID">
                        <TextBox Text="{Binding LoginID, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="National ID">
                        <TextBox Text="{Binding NationalIDNumber, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Title">
                        <TextBox Text="{Binding Title, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Marital Status">
                        <TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Gender">
                        <TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Salaried">
                        <CheckBox IsChecked="{Binding SalariedFlag, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Active">
                        <CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }" />
                    </dataForm:DataField>
                </StackPanel>
            </DataTemplate>
        </dataForm:DataForm.EditTemplate>
    </dataForm:DataForm>
    
  11. Ouvrez EmployeeRegistrationWindow.xaml.cs/vb.

  12. Ajoutez le code suivant pour créer une instance d'Employee et gérer la validation de la nouvelle instance ou l'annulation de l'insertion.

    Partial Public Class EmployeeRegistrationWindow
        Inherits ChildWindow
    
        Public Sub New()
            InitializeComponent()
            NewEmployee = New Employee
            addEmployeeDataForm.CurrentItem = NewEmployee
            addEmployeeDataForm.BeginEdit()
        End Sub
    
        Public Property NewEmployee As Employee
    
        Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles OKButton.Click
            Me.addEmployeeDataForm.CommitEdit()
            Me.DialogResult = True
        End Sub
    
        Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles CancelButton.Click
            NewEmployee = Nothing
            addEmployeeDataForm.CancelEdit()
            Me.DialogResult = False
        End Sub
    
    End Class
    
    public partial class EmployeeRegistrationWindow : ChildWindow
    {
        public EmployeeRegistrationWindow()
        {
            InitializeComponent();
            NewEmployee = new Employee();
            addEmployeeDataForm.CurrentItem = NewEmployee;
            addEmployeeDataForm.BeginEdit();    
        }
    
        public Employee NewEmployee { get; set; }
    
        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            addEmployeeDataForm.CommitEdit();
            this.DialogResult = true;
        }
    
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            NewEmployee = null;
            addEmployeeDataForm.CancelEdit();
            this.DialogResult = false;
        }
    }
    
  13. Ouvrez EmployeeList.xaml.

  14. Entre le DataPager et le DataForm, ajoutez le XAML suivant pour créer un bouton nommé addNewEmployee.

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,12,0,0">
        <Button x:Name="addNewEmployee" Width="90" Height="23"  Content="Add Employee"  Margin="4,0,0,0" Click="addNewEmployee_Click"/>
    </StackPanel>
    
  15. Ouvrez EmployeeList.xaml.cs/vb.

  16. Ajoutez le code suivant pour gérer l'événement de clic sur le bouton et afficher la fenêtre EmployeeRegistration.

    Private Sub addNewEmployee_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim addEmp As New EmployeeRegistrationWindow()
        AddHandler addEmp.Closed, AddressOf addEmp_Closed
        addEmp.Show()
    End Sub
    
    private void addNewEmployee_Click(object sender, RoutedEventArgs e)
    {
        EmployeeRegistrationWindow addEmp = new EmployeeRegistrationWindow();
        addEmp.Closed += new EventHandler(addEmp_Closed);
        addEmp.Show();
    }
    
  17. Ajoutez la méthode suivante pour gérer l'événement closed pour la fenêtre EmployeeRegistration.

    Private Sub addEmp_Closed(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim emp As EmployeeRegistrationWindow = sender
        If Not emp.NewEmployee Is Nothing Then
            Dim _OrganizationContext As OrganizationContext = employeeDataSource.DomainContext
            _OrganizationContext.Employees.Add(emp.NewEmployee)
            employeeDataSource.SubmitChanges()
        End If
    End Sub
    
    void addEmp_Closed(object sender, EventArgs e)
    {
        EmployeeRegistrationWindow emp = (EmployeeRegistrationWindow)sender;
        if (emp.NewEmployee != null)
        {
            OrganizationContext _OrganizationContext = (OrganizationContext)(employeeDataSource.DomainContext);
            _OrganizationContext.Employees.Add(emp.NewEmployee);
            employeeDataSource.SubmitChanges();
        }
    }
    
  18. Ouvrez OrganizationService.cs/vb.

  19. Modifiez la méthode InsertEmployee en ajoutant le code suivant.

    Public Sub InsertEmployee(ByVal employee As Employee)
        employee.HireDate = DateTime.Now
        employee.ModifiedDate = DateTime.Now
        employee.VacationHours = 0
        employee.SickLeaveHours = 0
        employee.rowguid = Guid.NewGuid()
        employee.ContactID = 1001
        employee.BirthDate = New DateTime(1967, 3, 18)
    
        If ((employee.EntityState = EntityState.Detached) _
                    = False) Then
            Me.ObjectContext.ObjectStateManager.ChangeObjectState(employee, EntityState.Added)
        Else
            Me.ObjectContext.Employees.AddObject(employee)
        End If
    End Sub
    
    public void InsertEmployee(Employee employee)
    {
        employee.HireDate = DateTime.Now;
        employee.ModifiedDate = DateTime.Now;
        employee.VacationHours = 0;
        employee.SickLeaveHours = 0;
        employee.rowguid = Guid.NewGuid();
        employee.ContactID = 1001;
        employee.BirthDate = new DateTime(1967, 3, 18);
    
        if ((employee.EntityState != EntityState.Detached))
        {
            this.ObjectContext.ObjectStateManager.ChangeObjectState(employee, EntityState.Added);
        }
        else
        {
            this.ObjectContext.Employees.AddObject(employee);
        }
    }
    
  20. Exécutez l'application et cliquez sur le lien Liste des employés.

  21. Cliquez sur le bouton Ajouter un employé.

    La fenêtre EmployeeRegistration s'ouvre.

    RIA_Employee_Registration

  22. Ajoutez les données dans la fenêtre et activez la case à cocher Salarié.

  23. Cliquez sur OK.

  24. Rafraîchissez la page et vérifiez que le nouvel employé s'affiche dans le DataGrid.

Authentification des utilisateurs

Dans cette section, vous allez limiter l'accès à la méthode ApproveSabbatical aux seuls utilisateurs authentifiés.

Pour ajouter l'authentification

  1. Ouvrez OrganizationService.cs/vb.

  2. Ajoutez l'attribut RequiresAuthentication à la méthode ApproveSabbatical.

    Lorsque vous appliquez l'attribut RequiresAuthentication à une opération de domaine, vous garantissez que seuls les utilisateurs authentifiés pourront appeler l'opération. Si un utilisateur anonyme clique sur le bouton Approuver un congé sabbatique, l'opération n'est pas exécutée.

    <RequiresAuthentication()> _
    Public Sub ApproveSabbatical(ByVal current As Employee)
        Me.ObjectContext.Employees.AttachAsModified(current)
        current.CurrentFlag = False
    End Sub
    
    [RequiresAuthentication]
    public void ApproveSabbatical(Employee current)
    {
        // Start custom workflow here
        this.ObjectContext.Employees.AttachAsModified(current);
        current.CurrentFlag = false;
    }
    
  3. Ouvrez EmployeeList.xaml.cs/vb.

  4. Ajoutez les instructions using ou Imports suivantes.

    Imports System.ServiceModel.DomainServices.Client.ApplicationServices
    Imports HRApp.LoginUI
    
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using HRApp.LoginUI;
    
  5. Modifiez la méthode approveSabbatical_Click et ajoutez un gestionnaire LoggedIn pour vérifier si l'utilisateur est authentifié.

    Private Sub approveSabbatical_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        If WebContext.Current.User IsNot Nothing AndAlso WebContext.Current.User.IsAuthenticated Then
            Dim luckyEmployee As Employee = dataGrid1.SelectedItem
            luckyEmployee.ApproveSabbatical()
            employeeDataSource.SubmitChanges()
        Else
            AddHandler WebContext.Current.Authentication.LoggedIn, AddressOf Current_LoginCompleted
            Dim newWindow As New LoginRegistrationWindow
            newWindow.Show()
        End If
    End Sub
    
    Private Sub Current_LoginCompleted(ByVal sender As Object, ByVal e As AuthenticationEventArgs)
        Dim luckyEmployee As Employee = dataGrid1.SelectedItem
        luckyEmployee.ApproveSabbatical()
        employeeDataSource.SubmitChanges()
        RemoveHandler WebContext.Current.Authentication.LoggedIn, AddressOf Current_LoginCompleted
    End Sub
    
    private void approveSabbatical_Click(object sender, RoutedEventArgs e)
    {
        if (WebContext.Current.User.IsAuthenticated)
        {
            Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
            luckyEmployee.ApproveSabbatical();
            employeeDataSource.SubmitChanges();
        }
        else
        {
            WebContext.Current.Authentication.LoggedIn += Authentication_LoggedIn;
            new LoginRegistrationWindow().Show();
        }
    }
    
    private void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
    {
        Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
        luckyEmployee.ApproveSabbatical();
        employeeDataSource.SubmitChanges();
    
        WebContext.Current.Authentication.LoggedIn -= Authentication_LoggedIn;
    }
    
  6. Exécutez l'application et cliquez sur le lien Liste des employés.

  7. Sélectionnez un enregistrement d'employé et cliquez sur le bouton Approuver un congé sabbatique.

    Vous êtes redirigé vers la fenêtre de connexion.

  8. Cliquez sur le lien S'inscrire maintenant.

  9. Complétez les champs requis pour créer un compte.

  10. Cliquez sur OK.

    Vous êtes connecté sur ce compte et votre nom s'affiche dans une barre au-dessous des liens de navigation.

Affichage de données liées

Avec les Services RIA , vous pouvez facilement utiliser des données provenant de tables associées. Dans cette section, vous allez ajouter une nouvelle Page Silverlight et afficher des données provenant des tables PurchaseOrderHeader et PurchaseOrderDetail. Vous pouvez aussi personnaliser les opérations de modification des données de façon à ce que les données liées soient modifiées ensemble. Pour voir un exemple de modification des données dans des tables associées via une opération de domaine, consultez Hiérarchies de composition.

Pour afficher les données de tables associées

  1. Dans le projet HRApp, cliquez avec le bouton droit sur le dossier Views, puis cliquez sur Ajouter et sur Nouvel élément.

  2. Ajoutez une nouvelle page Silverlight nommée PurchaseOrders.xaml.

  3. Ouvrez PurchaseOrders.xaml.

  4. Ajoutez le XAML suivant entre les balises <Grid>.

    <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource 
      PageScrollViewerStyle}" >
        <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
    
            <TextBlock Text="Purchase Orders" Style="{StaticResource HeaderTextStyle}"/>
        </StackPanel>
    </ScrollViewer>
    
  5. Ouvrez MainPage.xaml.

  6. Après le lien EmployeeList, ajoutez le XAML suivant afin d'inclure un lien vers la page PurchaseOrders.

    <Rectangle x:Name="Divider3" Style="{StaticResource DividerStyle}"/>
    
    <HyperlinkButton x:Name="Link4" Style="{StaticResource LinkStyle}" NavigateUri="/PurchaseOrders" TargetName="ContentFrame" Content="Purchase Orders"/>
    
  7. Ouvrez OrganizationService.metadata.cs/vb.

  8. Ajoutez les attributs Include et Composition à la propriété PurchaseOrderDetails dans la classe PurchaseOrderHeaderMetadata.

    <Include()> _
    <Composition()> _
    Public Property PurchaseOrderDetails As EntityCollection(Of PurchaseOrderDetail)
    
    [Include]
    [Composition]
    public EntityCollection<PurchaseOrderDetail> PurchaseOrderDetails { get; set; }
    
  9. Ouvrez OrganizationService.cs/vb.

  10. Changez la méthode GetPurchaseOrderHeaders afin que les enregistrements associés dans PurchaseOrderDetails soient eux aussi récupérés par la requête.

    Public Function GetPurchaseOrderHeaders() As IQueryable(Of PurchaseOrderHeader)
        Return Me.ObjectContext.PurchaseOrderHeaders.Include("PurchaseOrderDetails").OrderBy(Function(p) p.PurchaseOrderID)
    End Function
    
    public IQueryable<PurchaseOrderHeader> GetPurchaseOrderHeaders()
    {
        return this.ObjectContext.PurchaseOrderHeaders.Include("PurchaseOrderDetails").OrderBy(p => p.PurchaseOrderID);
    }
    
  11. Ouvrez PurchaseOrders.xaml.

  12. Dans le menu Données, cliquez sur Afficher les sources de données pour ouvrir la fenêtre Sources de données.

  13. Faites glisser le nœud PurchaseOrderHeader sur l'aire de conception de PurchaseOrders.xaml.

    RIA_Order_Header

    Un DataGrid avec les colonnes de la table PurchaseOrderHeader s'affiche.

  14. Dans la fenêtre Sources de données, développez le nœud PurchaseOrderHeader.

  15. Faites glisser le nœud PurchaseOrderDetails, situé à l'intérieur du nœud PurchaseOrderHeader, sur l'aire de conception placée juste sous le DataGrid de PurchaseOrderHeader.

    RIA_Order_Details

    Un DataGrid avec les colonnes de la table PurchaseOrderDetails s'affiche.

  16. Dans la vue XAML, trouvez les contrôles DataGrid de PurchaseOrderHeader et PurchaseOrderDetails.

  17. Supprimez la propriété Width=”400” de chaque DataGrid afin qu'il prenne toute la largeur disponible.

  18. Avant le DataGrid de PurchaseOrderHeader, ajoutez le contrôle TextBlock suivant afin d'étiqueter les données.

    <TextBlock Text="Order Headers"></TextBlock>
    
  19. Avant le DataGrid de PurchaseOrderDetails, ajoutez le contrôle TextBlock suivant afin d'étiqueter les données.

    <TextBlock Text="Order Details"></TextBlock>
    
  20. Pour limiter le nombre d'enregistrements récupérés, ajoutez le descripteur de filtre suivant au contrôle DomainDataSource.

    <riaControls:DomainDataSource.FilterDescriptors>
        <riaControls:FilterDescriptor PropertyPath="PurchaseOrderID" Operator="IsLessThan" Value="10"></riaControls:FilterDescriptor>
    </riaControls:DomainDataSource.FilterDescriptors>
    

    Les éléments suivants montrent le XAML complet pour PurchaseOrders.xaml.

    <navigation:Page x:Class="HRApp.Views.PurchaseOrders" 
               xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
               xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
               mc:Ignorable="d"
               xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
               d:DesignWidth="640" d:DesignHeight="480"
               Title="PurchaseOrders Page" 
               xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" 
               xmlns:my="clr-namespace:HRApp.Web" 
               xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
        <sdk:Page.Resources>
            <CollectionViewSource x:Key="purchaseOrderHeaderPurchaseOrderDetailsViewSource" Source="{Binding Path=Data.PurchaseOrderDetails, ElementName=purchaseOrderHeaderDomainDataSource}" />
        </sdk:Page.Resources>
        <Grid x:Name="LayoutRoot">
            <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource 
              PageScrollViewerStyle}" >
                <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
    
                    <TextBlock Text="Purchase Orders" Style="{StaticResource HeaderTextStyle}"/>
                    <riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my:PurchaseOrderHeader, CreateList=true}" Height="0" LoadedData="purchaseOrderHeaderDomainDataSource_LoadedData_1" Name="purchaseOrderHeaderDomainDataSource" QueryName="GetPurchaseOrderHeadersQuery" Width="0">
                        <riaControls:DomainDataSource.DomainContext>
                            <my:OrganizationContext />
                        </riaControls:DomainDataSource.DomainContext>
                        <riaControls:DomainDataSource.FilterDescriptors>
                            <riaControls:FilterDescriptor PropertyPath="PurchaseOrderID" Operator="IsLessThan" Value="10"></riaControls:FilterDescriptor>
                        </riaControls:DomainDataSource.FilterDescriptors>
                    </riaControls:DomainDataSource>
                    <TextBlock Text="Order Headers"></TextBlock>
                    <sdk:DataGrid AutoGenerateColumns="False" Height="200" ItemsSource="{Binding ElementName=purchaseOrderHeaderDomainDataSource, Path=Data}" Name="purchaseOrderHeaderDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected">
                        <sdk:DataGrid.Columns>
                            <sdk:DataGridTextColumn x:Name="employeeIDColumn" Binding="{Binding Path=EmployeeID}" Header="Employee ID" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="freightColumn" Binding="{Binding Path=Freight}" Header="Freight" Width="SizeToHeader" />
                            <sdk:DataGridTemplateColumn x:Name="modifiedDateColumn" Header="Modified Date" Width="SizeToHeader">
                                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <sdk:DatePicker SelectedDate="{Binding Path=ModifiedDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellEditingTemplate>
                                <sdk:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=ModifiedDate, StringFormat=\{0:d\}}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellTemplate>
                            </sdk:DataGridTemplateColumn>
                            <sdk:DataGridTemplateColumn x:Name="orderDateColumn" Header="Order Date" Width="SizeToHeader">
                                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <sdk:DatePicker SelectedDate="{Binding Path=OrderDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellEditingTemplate>
                                <sdk:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=OrderDate, StringFormat=\{0:d\}}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellTemplate>
                            </sdk:DataGridTemplateColumn>
                            <sdk:DataGridTextColumn x:Name="purchaseOrderIDColumn" Binding="{Binding Path=PurchaseOrderID, Mode=OneWay}" Header="Purchase Order ID" IsReadOnly="True" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="revisionNumberColumn" Binding="{Binding Path=RevisionNumber}" Header="Revision Number" Width="SizeToHeader" />
                            <sdk:DataGridTemplateColumn x:Name="shipDateColumn" Header="Ship Date" Width="SizeToHeader">
                                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <sdk:DatePicker SelectedDate="{Binding Path=ShipDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, TargetNullValue=''}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellEditingTemplate>
                                <sdk:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=ShipDate, StringFormat=\{0:d\}}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellTemplate>
                            </sdk:DataGridTemplateColumn>
                            <sdk:DataGridTextColumn x:Name="shipMethodIDColumn" Binding="{Binding Path=ShipMethodID}" Header="Ship Method ID" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="statusColumn" Binding="{Binding Path=Status}" Header="Status" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="subTotalColumn" Binding="{Binding Path=SubTotal}" Header="Sub Total" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="taxAmtColumn" Binding="{Binding Path=TaxAmt}" Header="Tax Amt" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="totalDueColumn" Binding="{Binding Path=TotalDue}" Header="Total Due" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="vendorIDColumn" Binding="{Binding Path=VendorID}" Header="Vendor ID" Width="SizeToHeader" />
                        </sdk:DataGrid.Columns>
                    </sdk:DataGrid>
                    <TextBlock Text="Order Details"></TextBlock>
                    <sdk:DataGrid AutoGenerateColumns="False" Height="200" ItemsSource="{Binding Source={StaticResource purchaseOrderHeaderPurchaseOrderDetailsViewSource}}" Name="purchaseOrderDetailsDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected">
                        <sdk:DataGrid.Columns>
                            <sdk:DataGridTemplateColumn x:Name="dueDateColumn" Header="Due Date" Width="SizeToHeader">
                                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <sdk:DatePicker SelectedDate="{Binding Path=DueDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellEditingTemplate>
                                <sdk:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=DueDate, StringFormat=\{0:d\}}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellTemplate>
                            </sdk:DataGridTemplateColumn>
                            <sdk:DataGridTextColumn x:Name="lineTotalColumn" Binding="{Binding Path=LineTotal}" Header="Line Total" Width="SizeToHeader" />
                            <sdk:DataGridTemplateColumn x:Name="modifiedDateColumn1" Header="Modified Date" Width="SizeToHeader">
                                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <sdk:DatePicker SelectedDate="{Binding Path=ModifiedDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellEditingTemplate>
                                <sdk:DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=ModifiedDate, StringFormat=\{0:d\}}" />
                                    </DataTemplate>
                                </sdk:DataGridTemplateColumn.CellTemplate>
                            </sdk:DataGridTemplateColumn>
                            <sdk:DataGridTextColumn x:Name="orderQtyColumn" Binding="{Binding Path=OrderQty}" Header="Order Qty" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="productIDColumn" Binding="{Binding Path=ProductID}" Header="Product ID" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="purchaseOrderDetailIDColumn" Binding="{Binding Path=PurchaseOrderDetailID}" Header="Purchase Order Detail ID" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="purchaseOrderIDColumn1" Binding="{Binding Path=PurchaseOrderID}" Header="Purchase Order ID" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="receivedQtyColumn" Binding="{Binding Path=ReceivedQty}" Header="Received Qty" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="rejectedQtyColumn" Binding="{Binding Path=RejectedQty}" Header="Rejected Qty" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="stockedQtyColumn" Binding="{Binding Path=StockedQty}" Header="Stocked Qty" Width="SizeToHeader" />
                            <sdk:DataGridTextColumn x:Name="unitPriceColumn" Binding="{Binding Path=UnitPrice}" Header="Unit Price" Width="SizeToHeader" />
                        </sdk:DataGrid.Columns>
                    </sdk:DataGrid>
                </StackPanel>
            </ScrollViewer>
        </Grid>
    </navigation:Page>
    
  21. Exécutez l'application et cliquez sur le lien Bons de commande.

  22. Sélectionnez des enregistrements différents dans le DataGrid de PurchaseOrderHeader.

    Remarquez que les registres PurchaseOrderDetail associés s'affichent automatiquement.

    RIA_Details_and_Header

Étapes suivantes

Cette procédure pas à pas vous a présenté un grand nombre de fonctionnalités des Services RIA . Pour connaître certains domaines plus en détail, consultez les autres procédures pas à pas de cette documentation.

Voir aussi

Tâches

Procédure pas à pas : Affichage de données dans une application métier Silverlight
Procédure pas à pas : Utilisation du service d'authentification avec une application métier Silverlight