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.
Conseil : |
---|
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
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.
Dans le volet Modèles installés, développez le nœud Visual Basic ou Visual C# et sélectionnez la catégorie Silverlight.
Sélectionnez le modèle Application métier Silverlight et nommez l'application HRApp.
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.
Générez et exécutez (F5) l'application, puis explorez l'implémentation par défaut.
Fermez votre navigateur Web.
Pour configurer l'application
Dans l'Explorateur de solutions, dans le projet client, ouvrez MainPage.xaml.
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}}"/>
Dans l'Explorateur de solutions, développez le dossier Assets, puis le dossier Resources.
Ouvrez le fichier ApplicationStrings.resx.
Modifiez la ressource ApplicationName en HR Application.
Enregistrez et fermez le fichier ApplicationStrings.resx.
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.
Sélectionnez le modèle Page Silverlight de la catégorie Silverlight des Modèles installés et nommez-le EmployeeList.xaml.
Cliquez sur Ajouter.
Ouvrez EmployeeList.xaml s'il ne s'ouvre pas automatiquement.
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>
Enregistrez le fichier EmployeeList.xaml.
Ouvrez MainPage.xaml.
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}"/>
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.
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
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.
Dans la catégorie Données, sélectionnez le modèle ADO.NET Entity Data Model.
Donnez-lui le nom AdventureWorks.edmx, puis cliquez sur Ajouter.
L'Assistant Entity Data Model s'ouvre.
Sur la page Choisir le contenu du modèle, cliquez sur Générer à partir de la base de données, puis sur Suivant.
Sur la page Choisir votre connexion de données, créez une connexion à la base de données AdventureWorks.
Nommez les paramètres de connexion de l'entité AdventureWorks_DataEntities puis cliquez sur Suivant.
Sur la page Choisir vos objets de base de données, développez le nœud Tables.
Ajoutez des coches devant les tables Employé, PurchaseOrderDetailet PurchaseOrderHeader.
Nommez l'espace de noms du modèle AdventureWorks_DataModel, puis cliquez sur Terminer.
L'Entity Data Model s'affiche dans le concepteur.
Générez la solution.
Pour ajouter un objet service de domaine et transmettre une requête de données
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.
Dans la catégorie Web, sélectionnez le modèle Classe DomainService.
Nommez le nouvel article OrganizationService.
Cliquez sur Ajouter.
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é.
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.
Cliquez sur OK.
Les fichiers OrganizationService.cs/vb et OrganizationService.metadata.cs/vb sont ajoutés au projet.
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é.
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); }
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.
Ouvrez EmployeeList.xaml.
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.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" />
Enregistrez EmployeeList.xaml.
Ouvrez EmployeeList.xaml.cs/vb.
Ajoutez les instructions using ou Imports suivantes.
Imports System.ServiceModel.DomainServices.Client
using HRApp.Web; using System.ServiceModel.DomainServices.Client;
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 classeOrganizationService
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) { } }
Exécutez l'application.
Cliquez sur le lien Liste des employés pour consulter le DataGrid.
Pour ajouter une requête personnalisée
Dans le projet HRApp.Web, ouvrez OrganizationService.cs/vb.
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); }
Générez la solution.
Dans le projet client, ouvrez EmployeeList.xaml.cs/vb.
Dans le constructeur, remplacez l'appel à
GetEmployeesQuery()
par un appel àGetSalariedEmployeesQuery()
._OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
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.
Pour ajouter une source de données de domaine
Ouvrez EmployeeList.xaml.
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.
Conseil : 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.Pour les solutions C#, ajoutez la déclaration d'espace de noms suivante au fichier XAML.
xmlns:ds="clr-namespace:HRApp.Web"
Pour les solutions Visual Basic, ajoutez la déclaration d'espace de noms suivante au fichier XAML.
xmlns:ds="clr-namespace:HRApp"
Nommez le contrôle
employeeDataSource
DomainDataSource 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>
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>
Remplacez DataGrid par le XAML suivant :
<sdk:DataGrid AutoGenerateColumns="True" IsReadOnly="True" Name="dataGrid1" MinHeight="100" Height="Auto" ItemsSource="{Binding Data, ElementName=employeeDataSource}" />
Ouvrez EmployeeList.xaml.cs/vb.
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()); }
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
Ouvrez EmployeeList.xaml.
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>
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.
Ouvrez EmployeeList.xaml.
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>
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>
Exécutez l'application et cliquez sur le lien Liste des employés.
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.
Ouvrez EmployeeList.xaml.
Depuis la Boîte à outils, faites glisser un contrôle DataPager juste sous le DataGrid.
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" />
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.
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
Ouvrez EmployeeList.xaml.
Ajoutez la déclaration d'espace de noms suivante.
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
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>
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.
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
Ouvrez le fichier EmployeeList.xaml.
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>
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">
Ouvrez EmployeeList.xaml.cs/vb.
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(); }
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; }
Exécutez l'application et cliquez sur le lien Liste des employés.
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.
Apportez des modifications aux données des employés et cliquez sur OK.
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
Dans le projet serveur HRApp.Web, ouvrez OrganizationService.cs/vb. Fichier
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; }
Générez la solution.
Ouvrez EmployeeList.xaml.
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"/>
Ouvrez EmployeeList.xaml.cs/vb.
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(); }
Exécutez l'application et cliquez sur le lien Liste des employés.
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.
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
Dans le projet serveur HRApp.web, ouvrez OrganizationService.metadata.cs/vb.
Ajoutez les attributs suivants aux propriétés
Gender
etVacationHours
.<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; }
Générez la solution.
Exécutez l'application et cliquez sur le lien Liste des employés.
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.
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.
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
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.
Dans la catégorie Code, sélectionnez le modèle Fichier de code.
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.Cliquez sur Ajouter.
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" }); } } } }
Ouvrez OrganizationService.metadata.cs/vb.
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; }
Générez la solution.
Exécutez l'application et cliquez sur le lien Liste des employés.
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.
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.
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
Dans le projet HRApp, ajoutez un nouvel élément.
Dans la catégorie Silverlight, sélectionnez le modèle Fenêtre enfant Silverlight.
Nommez le nouvel élément EmployeeRegistrationWindow.xaml.
Cliquez sur Ajouter.
Ouvrez EmployeeRegistrationWindow.xaml.cs/vb.
Si vous utilisez C#, ajoutez l'instruction using suivante.
using HRApp.Web;
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; }
Ouvrez EmployeeRegistrationWindow.xaml.
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"
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>
Ouvrez EmployeeRegistrationWindow.xaml.cs/vb.
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; } }
Ouvrez EmployeeList.xaml.
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>
Ouvrez EmployeeList.xaml.cs/vb.
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(); }
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(); } }
Ouvrez OrganizationService.cs/vb.
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); } }
Exécutez l'application et cliquez sur le lien Liste des employés.
Cliquez sur le bouton Ajouter un employé.
La fenêtre EmployeeRegistration s'ouvre.
Ajoutez les données dans la fenêtre et activez la case à cocher Salarié.
Cliquez sur OK.
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
Ouvrez OrganizationService.cs/vb.
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; }
Ouvrez EmployeeList.xaml.cs/vb.
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;
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; }
Exécutez l'application et cliquez sur le lien Liste des employés.
Sélectionnez un enregistrement d'employé et cliquez sur le bouton Approuver un congé sabbatique.
Vous êtes redirigé vers la fenêtre de connexion.
Cliquez sur le lien S'inscrire maintenant.
Complétez les champs requis pour créer un compte.
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
Dans le projet HRApp, cliquez avec le bouton droit sur le dossier Views, puis cliquez sur Ajouter et sur Nouvel élément.
Ajoutez une nouvelle page Silverlight nommée PurchaseOrders.xaml.
Ouvrez PurchaseOrders.xaml.
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>
Ouvrez MainPage.xaml.
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"/>
Ouvrez OrganizationService.metadata.cs/vb.
Ajoutez les attributs Include et Composition à la propriété
PurchaseOrderDetails
dans la classePurchaseOrderHeaderMetadata
.<Include()> _ <Composition()> _ Public Property PurchaseOrderDetails As EntityCollection(Of PurchaseOrderDetail)
[Include] [Composition] public EntityCollection<PurchaseOrderDetail> PurchaseOrderDetails { get; set; }
Ouvrez OrganizationService.cs/vb.
Changez la méthode
GetPurchaseOrderHeaders
afin que les enregistrements associés dansPurchaseOrderDetails
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); }
Ouvrez PurchaseOrders.xaml.
Dans le menu Données, cliquez sur Afficher les sources de données pour ouvrir la fenêtre Sources de données.
Faites glisser le nœud PurchaseOrderHeader sur l'aire de conception de PurchaseOrders.xaml.
Un DataGrid avec les colonnes de la table PurchaseOrderHeader s'affiche.
Dans la fenêtre Sources de données, développez le nœud PurchaseOrderHeader.
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.
Un DataGrid avec les colonnes de la table PurchaseOrderDetails s'affiche.
Dans la vue XAML, trouvez les contrôles DataGrid de
PurchaseOrderHeader
etPurchaseOrderDetails
.Supprimez la propriété
Width=”400”
de chaque DataGrid afin qu'il prenne toute la largeur disponible.Avant le DataGrid de PurchaseOrderHeader, ajoutez le contrôle TextBlock suivant afin d'étiqueter les données.
<TextBlock Text="Order Headers"></TextBlock>
Avant le DataGrid de PurchaseOrderDetails, ajoutez le contrôle TextBlock suivant afin d'étiqueter les données.
<TextBlock Text="Order Details"></TextBlock>
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>
Exécutez l'application et cliquez sur le lien Bons de commande.
Sélectionnez des enregistrements différents dans le DataGrid de PurchaseOrderHeader.
Remarquez que les registres PurchaseOrderDetail associés s'affichent automatiquement.
É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