Procedura dettagliata: panoramica di Servizi RIA

In questa procedura dettagliata viene fornita una panoramica di molte delle funzionalità di WCF RIA Services. Verrà illustrata la creazione di un'applicazione RIA Services che consente di recuperare dati dalle tabelle del database di esempio AdventureWorks OLTP. È innanzitutto necessario recuperare i dati specificando LoadOperation. Si procede quindi al recupero di quei dati mediante il controllo DomainDataSource. Si specificano ordinamento, applicazione di filtri e paging per il controllo della presentazione dei dati e si aggiunge un controllo DataForm per presentare una visualizzazione dettagliata dei dati. Si applicano regole di convalida ai campi consentendo all'utente di modificare i valori dei dati. Si limita l'accesso a un'operazione di dominio agli utenti autenticati. Si definisce, infine, l'associazione tra due tabelle correlate e si visualizzano i relativi dati.

TipSuggerimento:
Per procedure dettagliate più brevi su come iniziare creando una soluzione RIA Services più semplice, vedere Procedura dettagliata: creazione di una soluzione Servizi RIA o Procedura dettagliata: utilizzo del modello Applicazione aziendale di Silverlight.

Prerequisiti

Per l'esecuzione di questa e di altre procedure dettagliate descritte nella documentazione di WCF RIA Services è necessario che siano installati e configurati correttamente alcuni programmi prerequisiti quali Visual Studio 2010 e Silverlight Developer Runtime e SDK, oltre a WCF RIA Services e a WCF RIA Services Toolkit. È inoltre richiesta l'installazione e la configurazione di SQL Server 2008 R2 Express with Advanced Services e l'installazione del database AdventureWorks OLTP e LT.

Le istruzioni dettagliate per soddisfare tali prerequisiti vengono fornite negli argomenti all'interno del nodo Prerequisiti per WCF RIA Services. Seguire tali istruzioni prima di continuare con questa procedura dettagliata in modo da assicurarsi che si verifichi il minor numero possibile di problemi durante l'esecuzione della procedura dettagliata di RIA Services .

Creazione e impostazione della soluzione

In questa sezione, si procederà alla creazione e all'impostazione della soluzione.

Per creare una nuova applicazione WCF RIA Services

  1. In Visual Studio 2010, creare un nuovo progetto RIA Services selezionando File, Nuovo, quindi Progetto.

    Verrà visualizzata la finestra di dialogo Nuovo progetto.

  2. Nel riquadro Modelli installati espandere il nodo Visual Basic o Visual C#, quindi selezionare la categoria Silverlight.

  3. Selezionare il modello Applicazione aziendale di Silverlight e denominare l'applicazione HRApp.

    RIA_HRAppStart

  4. Fare clic su OK.

    Notare la struttura della soluzione creata:

    • La soluzione consiste in due progetti: un progetto client Silverlight denominato HRApp e un progetto server di applicazioni Web ASP.NET denominato HRApp.Web.

    • La soluzione predefinita contiene molte funzionalità implementate automaticamente che includono navigazione, accesso e disconnessione utente e registrazione di nuovi utenti.

    RIA_HRAppStructure

  5. Compilare ed eseguire (F5) l'applicazione ed esplorare l'implementazione predefinita.

  6. Chiudere il browser Web.

Per impostare l'applicazione

  1. In Esplora soluzioni, nel progetto client, aprire MainPage.xaml.

  2. In visualizzazione XAML, individuare l'oggetto TextBlock denominato ApplicationNameTextBlock.

    Notare che il nome dell'applicazione viene recuperato da una risorsa, come mostrato nel markup seguente.

    <TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}" 
                       Text="{Binding ApplicationStrings.ApplicationName, Source={StaticResource ResourceWrapper}}"/>
    
  3. In Esplora soluzioni espandere la cartella Assets, quindi la cartella Resources.

  4. Aprire il file ApplicationStrings.resx.

  5. Modificare la risorsa ApplicationName in HR Application.

  6. Salvare e chiudere il file ApplicationStrings.resx.

  7. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla cartella Views, scegliere Aggiungi, quindi fare clic su Nuovo elemento.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  8. Selezionare il modello Silverlight Page dalla categoria Silverlight di Modelli installati e denominarlo EmployeeList.xaml.

    RIA_HRAppAddPage

  9. Fare clic su Aggiungi.

  10. Aprire EmployeeList.xaml, se non viene aperto automaticamente.

  11. Aggiungere il codice XAML seguente tra i tag <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. Salvare il file EmployeeList.xaml.

  13. Aprire MainPage.xaml.

  14. Aggiungere un nuovo pulsante di collegamento ipertestuale nella parte superiore della pagina aggiungendo il seguente codice XAML tra i due pulsanti di collegamento ipertestuale già esistenti.

    <HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}" NavigateUri="/EmployeeList" TargetName="ContentFrame" Content="Employee List"/>
    
    <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
    
  15. Eseguire l'applicazione e notare il nuovo collegamento Employee List nell'angolo superiore destro della pagina, tra i collegamenti Home page e Informazioni su. Fare clic sul collegamento per visualizzare “Employee List” nel corpo della pagina.

    RIA_HRAppPageView

Visualizzazione di dati

In questa sezione, viene creato un modello ADO.NET Entity Data Model per le tabelle nel database di esempio AdventureWorks. Viene quindi creato un servizio del dominio che espone le entità e ne visualizza i dati nel progetto client.

Per aggiungere un'origine dati

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto HRApp.Web, scegliere Aggiungi, quindi fare clic su Nuovo elemento.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  2. Nella categoria Dati selezionare il modello ADO.NET Entity Data Model.

    RIA_HRAppAddEntity

  3. Denominarlo AdventureWorks.edmx e fare clic su Aggiungi.

    Verrà aperta la procedura guidata Entity Data Model.

  4. Nella pagina Scegli contenuto Model fare clic su Genera da database, quindi su Avanti.

  5. Nella pagina Scegli la connessione dati creare una connessione al database AdventureWorks.

  6. Denominare le impostazioni di connessione dell'entità AdventureWorks_DataEntities quindi fare clic su Avanti.

  7. Espandere il nodo Tabelle nella pagina Seleziona oggetti di database.

  8. Aggiungere segni di spunta accanto alle tabelle Employee, PurchaseOrderDetail e PurchaseOrderHeader.

  9. Assegnare allo spazio dei nomi del modello il nome AdventureWorks_DataModel, quindi scegliere Fine.

    Il modello Entity Data Model verrà visualizzato nella finestra di progettazione.

  10. Compilare la soluzione.

Per aggiungere un oggetto del servizio del dominio ed eseguire una query per i dati

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto HRApp.Web, scegliere Aggiungi, quindi fare clic su Nuovo elemento.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  2. Nella categoria Web, selezionare il modello Classe di DomainService.

    RIA_HRAppAddService

  3. Assegnare al nuovo elemento il nome OrganizationService.

  4. Fare clic su Aggiungi.

  5. Nella finestra di dialogo Aggiungi una nuova classe DomainService, selezionare Dipendente, PurchaseOrderDetail e PurchaseOrderHeader dall'elenco Entità, quindi selezionare Abilita modifica per ciascuna entità.

  6. Assicurarsi che siano selezionate le caselle di controllo Abilita l'accesso client e Genera classi associate per i metadati.

  7. Fare clic su OK.

    I file OrganizationService.cs/vb e OrganizationService.metadata.cs/vb verranno aggiunti al progetto.

  8. Aprire il file OrganizationService.cs/vb.

    Si noti che per ciascuna entità sono stati creati i metodi Query, Insert, Update e Delete. Viene sempre creato un metodo di query per un'entità. I metodi Insert, Update e Delete sono stati aggiunti in quanto è stata selezionata l'opzione Attiva modifica.

  9. Personalizzare il metodo della query GetEmployees() per restituire dipendenti ordinati per EmployeeID sostituendo il codice generato con il codice seguente.

    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. Compilare la soluzione.

    La compilazione della soluzione genera il Contesto del dominio e le entità nel progetto client.

  11. Aprire il file EmployeeList.xaml.

  12. Dalla casella degli strumenti, trascinare un controllo DataGrid nella visualizzazione Progettazione subito dopo il controllo TextBlock.

    Il trascinamento di un controllo DataGrid in visualizzazione Progettazione comporta l'aggiunta un riferimento all'assembly System.Windows.Controls.Data e del prefisso sdk all'elemento di pagina.

  13. Modificare i valori predefiniti per il controllo DataGrid rimuovendo le proprietà Height e Width, rendendolo di sola lettura, impostandolo per generare automaticamente colonne e impostandone l'altezza minima.

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

  15. Aprire il file EmployeeList.xaml.cs/vb.

  16. Aggiungere le istruzioni using o Imports seguenti.

    Imports System.ServiceModel.DomainServices.Client
    
    using HRApp.Web;
    using System.ServiceModel.DomainServices.Client;
    
  17. Creare un'istanza della classe OrganizationContext e caricare i dati dei dipendenti aggiungendo il codice seguente a EmployeeList.xaml.cs/vb.

    La classe OrganizationContext viene generata automaticamente nel progetto client in base alla classe OrganizationService nel progetto server.

    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. Eseguire l'applicazione.

  19. Fare clic sul collegamento Employee List per visualizzare l'elemento DataGrid.

    RIA_HRAppDataGrid

Per aggiungere una query personalizzata

  1. Nel progetto HRApp.Web, aprire OrganizationService.cs/vb.

  2. Aggiungere un nuovo metodo denominato GetSalariedEmployees aggiungendo il codice seguente al corpo della 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. Compilare la soluzione.

  4. Nel progetto client aprire il file EmployeeList.xaml.cs/vb.

  5. Nel costruttore, sostituire la chiamata a GetEmployeesQuery() con una chiamata a GetSalariedEmployeesQuery().

    _OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
    
    _OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
    
  6. Eseguire l'applicazione e fare clic sul collegamento Employee List.

    Notare che per tutti i dipendenti visualizzati il valore SalariedFlag è selezionato. I dipendenti con EmployeeID 1, 2 e 4 non sono più visualizzati nell'elenco, in quanto non stipendiati.

    RIA_HRAppFilteredDataGrid

Per aggiungere un'origine dati di dominio

  1. Aprire il file EmployeeList.xaml.

  2. Dalla casella degli strumenti, trascinare il controllo DomainDataSource nella visualizzazione Progettazione, subito dopo il controllo DataGrid. Il controllo DomainDataSource potrebbe apparire in fondo all'elenco dei controlli.

    TipSuggerimento:
    Se il controllo DomainDataSource non è presente nella casella degli strumenti, fare clic con il pulsante destro del mouse sulla casella degli strumenti, quindi fare clic su Scegli elementi. Nella scheda Componenti Silverlight selezionare DomainDataSource e fare clic su OK.

    Quando si trascina il controllo DomainDataSource in visualizzazione Progettazione, viene creato un riferimento con il prefisso riaControls per lo spazio dei nomi System.Windows.Controls nell'elemento di pagina. Inoltre, un'icona di origine dati viene visualizzata nell'angolo inferiore sinistro della visualizzazione Progettazione.

  3. Per le soluzioni C#, aggiungere la dichiarazione dello spazio dei nomi seguente al file XAML.

    xmlns:ds="clr-namespace:HRApp.Web"
    
  4. Per le soluzioni Visual Basic, aggiungere la dichiarazione dello spazio dei nomi seguente al file XAML.

    xmlns:ds="clr-namespace:HRApp"
    
  5. Denominare il controllo DomainDataSourceemployeeDataSource e impostare LoadSize, AutoLoade il metodo di query sostituendo il codice XAML esistente con il seguente.

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
    </riaControls:DomainDataSource>
    
  6. Impostare DomainContext per DomainDataSource aggiungendo il codice XAML seguente.

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
        <riaControls:DomainDataSource.DomainContext>
            <ds:OrganizationContext/>
        </riaControls:DomainDataSource.DomainContext>
    </riaControls:DomainDataSource>
    
  7. Sostituire l'elemento DataGrid con il codice XAML seguente.

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

  9. Nel costruttore, rimuovere o impostare come commento il codice per creare un'istanza di OrganizationContext, della chiamata a GetSalariedEmployeesQuery()e del codice per impostare la proprietà ItemsSource del controllo DataGrid.

    Non è più necessario caricare i dati in modo esplicito, poiché l'operazione verrà eseguita automaticamente da DomainDataSource.

    '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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

    Il funzionamento dell'applicazione resta lo stesso.

Per aggiungere l'ordinamento, l'applicazione di filtri e il paging all'origine dati

  1. Aprire il file EmployeeList.xaml.

  2. Nella risorsa DomainDataSource aggiungere il seguente oggetto SortDescriptors per stabilire la modalità di ordinamento dei dati nell'elemento DataGrid.

    In questo XAML viene illustrato come ordinare la colonna VacationHours in ordine crescente.

    <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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

    I dati vengono ordinati in base a VacationHours ed è possibile modificare la direzione di ordinamento facendo clic sull'intestazione della colonna.

  4. Aprire il file EmployeeList.xaml.

  5. Per consentire all'utente di filtrare i record restituiti in base a un valore fornito, aggiungere il seguente codice XAML prima dell'elemento DataGrid.

    Il codice XAML aggiunge un controllo TextBox che consente all'utente di immettere valori.

    <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. In DomainDataSource, aggiungere un descrittore di filtro che viene associato al controllo TextBox aggiunto nel passaggio precedente.

    <riaControls:DomainDataSource.FilterDescriptors>
        <riaControls:FilterDescriptor 
             PropertyPath="VacationHours" 
             Operator="IsGreaterThanOrEqualTo"
             IgnoredValue=""
             Value="{Binding ElementName=vacationHoursText, Path=Text}"  >
        </riaControls:FilterDescriptor>
    </riaControls:DomainDataSource.FilterDescriptors>
    
  7. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  8. Nella casella di testo Filtro: Ore ferie min., digitare 70.

    Notare che per i dipendenti elencati il valore VacationHours è superiore o pari a 70.

    RIA_HRAppVacationFilter

  9. Aprire il file EmployeeList.xaml.

  10. Dalla casella degli strumenti, trascinare un controllo DataPager subito sotto all'elemento DataGrid.

  11. Impostare le dimensioni pagina su 5 e impostare l'origine come mostrato nel seguente codice XAML.

    <sdk:DataPager PageSize="5" Source="{Binding Data, ElementName=employeeDataSource}" HorizontalAlignment="Left" />
    
  12. Eseguire l'applicazione e fare clic sul collegamento Employee List.

    Vengono visualizzate solo 5 righe di dati filtrati per pagina e controlli pager sotto all'elemento DataGrid.

    RIA_HRAppPagedData

Creazione di una visualizzazione dettagli/master

In questa sezione, viene utilizzato il controllo DataForm dal Toolkit Silverlight per fornire una visualizzazione dettagliata dei dati. Per impostazione predefinita, il modello di progetto di Applicazione aziendale di Silverlight contiene l'elemento binario System.Windows.Controls.Data.DataForm.Toolkit.dll nella cartella delle librerie.

Per aggiungere un oggetto DataForm

  1. Aprire il file EmployeeList.xaml.

  2. Aggiungere la dichiarazione dello spazio dei nomi seguente.

    xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
    
  3. Aggiungere il controllo DataPager e aggiungere il codice XAML seguente per aggiungere un controllo DataForm.

    Questo codice XAML consente di impostare gli attributi DataForm e specificare le colonne da visualizzare.

    <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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

    L'elemento DataForm consente di visualizzare i dettagli dell'elemento selezionato nell'oggetto DataGrid.

    RIA_HRAppDataForm

Aggiornamento del database

Quando si seleziona la casella di controllo Attiva modifica nella finestra di dialogo Nuova classe DomainService, nel livello del servizio del dominio vengono generati i metodi per aggiornare, inserire ed eliminare l'entità. In questa sezione, vengono aggiunti pulsanti di modifica all'interfaccia utente dell'elenco dei dipendenti, per consentire agli utenti di eseguire tali operazioni.

Per aggiornare un record

  1. Aprire il file EmployeeList.xaml.

  2. Dopo il controllo DataForm aggiungere il codice XAML seguente per aggiungere un pulsante Invia.

    <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. Nel controllo DomainDataSource specificare un gestore eventi per l'evento SubmittedChanges.

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

  5. Aggiungere il seguente gestore eventi per l'evento Click del pulsante.

    submitButton è disabilitato per non consentire l'invio ripetuto della modifica da parte dell'utente durante l'elaborazione dell'operazione.

    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. Aggiungere un gestore eventi per l'evento SubmittedChanges che verifica se l'operazione di invio è stata completata correttamente e abilita 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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  8. Selezionare un dipendente e fare clic sull'icona della matita nell'angolo superiore destro del modulo dati per abilitare la modifica.

    È ora possibile modificare qualsiasi campo modificabile.

  9. Apportare le modifiche ai dati dei dipendenti e fare clic su OK.

  10. Fare clic sul pulsante Invia per salvare i dati.

    Le modifiche vengono salvate nel database sul server solo quando si fa clic sul pulsante Invia.

Per aggiungere metodi personalizzati a un servizio del dominio

  1. Nel progetto server HRApp.Web, aprire OrganizationService.cs/vb. File

  2. Aggiungere il seguente metodo personalizzato denominato 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. Compilare la soluzione.

  4. Aprire il file EmployeeList.xaml.

  5. Dopo il pulsante Invia, aggiungere il codice XAML seguente per aggiungere un pulsante Approva congedo sabbatico.

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

  7. Aggiungere il gestore eventi seguente per l'evento Click del pulsante che chiama l'operazione di dominio 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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  9. Fare clic sul pulsante Approva congedo sabbatico e notare che viene deselezionata la casella di controllo CurrentFlag per il dipendente selezionato.

Convalida dei dati

Il controllo DataForm può presentare errori di convalida dal livello di accesso ai dati (DAL). Se si immette un valore non Integer nel campo VacationHours, ad esempio, verrà visualizzato un errore di convalida. Nella figura seguente viene illustrato un esempio di questo comportamento.

RIA_HRAppValidation

Quando si seleziona la casella di controllo Genera classi associate per i metadati nella finestra di dialogo Nuova classe DomainService, viene creato un file che contiene metadati. In questa procedura dettagliata, il file dei metadati è denominato OrganizationService.metadata.cs/vb. In questa sezione, vengono aggiunti attributi di convalida a questo file. Le regole di convalida verranno applicate nei progetti client e server.

Verrà creata anche un'interfaccia utente per consentire l'aggiunta di nuovi record relativi ai dipendenti al database. Le regole di convalida aggiunte nelle sezioni precedenti verranno applicate automaticamente nella nuova interfaccia utente.

Per aggiungere la convalida di base

  1. Nel progetto server HRApp.web, aprire OrganizationService.metadata.cs/vb.

  2. Aggiungere gli attributi seguenti alle proprietà Gender e 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. Compilare la soluzione.

  4. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  5. Selezionare un dipendente e fare clic sull'icona della matita nell'angolo superiore destro del modulo dati per abilitare la modifica.

  6. Nel campo Ore ferie immettere un valore non compreso nell'intervallo valido (0-70) e spostare lo stato attivo su un altro controllo.

    Viene visualizzato un errore di convalida per le ore di ferie.

    RIA_HRAppRangeValidation

  7. Eliminare il valore nel campo Sesso e spostare lo stato attivo in un altro controllo.

    Viene visualizzato un errore di convalida per il sesso.

Per aggiungere la convalida personalizzata

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto HRApp.Web, scegliere Aggiungi, quindi fare clic su Nuovo elemento.

    Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.

  2. Nella categoria Codice, selezionare il modello File di codice.

  3. Assegnare al nuovo elemento il nome OrganizationService.shared.cs o OrganizationService.shared.vb.

    I file che terminano con l'estensione .shared.cs o .shared.vb sono disponibili sia nei progetti client che in quelli server. I file condivisi consentono di eseguire la stessa regola di convalida in entrambi i progetti. Dopo avere compilato la soluzione in un passaggio successivo, verificare nella cartella nascosta Generated_Code nel client; sarà presente il file OrganizationService.shared.cs/vb.

  4. Fare clic su Aggiungi.

  5. Per creare una classe di convalida personalizzata per la verifica dei valori assegnati alla proprietà Gender, aggiungere il codice seguente al file condiviso.

    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. Aprire il file OrganizationService.metadata.cs/vb.

  7. Aggiungere l'attributo di convalida personalizzato seguente alla proprietà Gender.

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

  9. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  10. Selezionare un dipendente e fare clic sull'icona della matita nell'angolo superiore destro del modulo dati per abilitare la modifica.

  11. Nel campo Gender immettere un valore diverso da M o F e spostare lo stato attivo su un altro controllo.

    Viene visualizzato il risultato della convalida personalizzata.

    RIA_HRAppCustomValidation

Aggiunta di nuovi record

In questa sezione, viene aggiunto un modulo che consente all'utente di creare un nuovo record nella tabella Employee.

Per aggiungere un nuovo record

  1. Aggiungere un nuovo elemento al progetto HRApp.

  2. Nella categoria Silverlight, selezionare il modello Finestra secondaria Silverlight.

  3. Denominare il nuovo elemento EmployeeRegistrationWindow.xaml.

    RIA_HRAppAddChildWindow

  4. Fare clic su Aggiungi.

  5. Aprire il file EmployeeRegistrationWindow.xaml.cs/vb.

  6. Se si utilizza C#, aggiungere l'istruzione using seguente.

    using HRApp.Web;
    
  7. Aggiungere una proprietà per la nuova entità Employee creata con i valori dell'utente.

    Public Property NewEmployee As Employee
    
    public Employee NewEmployee { get; set; }
    
  8. Aprire il file EmployeeRegistrationWindow.xaml.

  9. Aggiungere la seguente dichiarazione dello spazio dei nomi a EmployeeRegistrationWindow.xaml per utilizzare il controllo DataForm in questa finestra.

    xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
    
  10. Aggiungere il controllo DataForm seguente a EmployeeRegistrationWindow.xaml subito prima del pulsante di annullamento.

    <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. Aprire il file EmployeeRegistrationWindow.xaml.cs/vb.

  12. Aggiungere il codice seguente per creare una nuova istanza Employee e gestire il commit della nuova istanza o l'annullamento dell'inserimento.

    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. Aprire il file EmployeeList.xaml.

  14. Tra gli elementi DataPager e DataForm, aggiungere il seguente codice XAML per creare un pulsante denominato 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. Aprire il file EmployeeList.xaml.cs/vb.

  16. Aggiungere il codice seguente per gestire l'evento Click sul pulsante e visualizzare l'elemento EmployeeRegistrationWindow.

    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. Aggiungere il metodo seguente per gestire l'evento closed per EmployeeRegistrationWindow.

    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. Aprire il file OrganizationService.cs/vb.

  19. Modificare il metodo InsertEmployee aggiungendo il codice seguente.

    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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  21. Fare clic sul pulsante Aggiungi dipendente.

    Viene aperto l'elemento EmployeeRegistrationWindow.

    RIA_Employee_Registration

  22. Aggiungere dati nella finestra e selezionare la casella di controllo Stipendiato.

  23. Fare clic su OK.

  24. Aggiornare la pagina e assicurarsi che il nuovo dipendente venga visualizzato nell'elemento DataGrid.

Autenticazione degli utenti

In questa sezione verrà limitato l'accesso al metodo ApproveSabbatical ai soli utenti autenticati.

Per aggiungere l'autenticazione

  1. Aprire il file OrganizationService.cs/vb.

  2. Aggiungere l'attributo RequiresAuthentication al metodo ApproveSabbatical.

    Quando si applica l'attributo RequiresAuthentication a un'operazione di dominio, la chiamata dell'operazione sarà consentita ai soli utenti autenticati. Se un utente anonimo fa clic sul pulsante Approva congedo sabbatico, l'operazione non verrà eseguita.

    <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. Aprire il file EmployeeList.xaml.cs/vb.

  4. Aggiungere le istruzioni using o Imports seguenti.

    Imports System.ServiceModel.DomainServices.Client.ApplicationServices
    Imports HRApp.LoginUI
    
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using HRApp.LoginUI;
    
  5. Modificare il metodo approveSabbatical_Click e aggiungere un gestore LoggedIn per verificare se l'utente è autenticato.

    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. Eseguire l'applicazione e fare clic sul collegamento Employee List.

  7. Selezionare un record del dipendente e fare clic sul pulsante Approva congedo sabbatico.

    L'utente verrà reindirizzato alla finestra di accesso.

  8. Fare clic sul collegamento Registra ora.

  9. Completare tutti i campi obbligatori per creare un nuovo account.

  10. Fare clic su OK.

    Verrà effettuato l'accesso con il nuovo account e il nome dell'utente verrà visualizzato in una barra sotto i collegamenti di navigazione.

Visualizzazione dei dati correlati

Con RIA Services è possibile utilizzare facilmente i dati dalle tabelle correlate. In questa sezione viene aggiunta una nuova pagina Silverlight e vengono visualizzati i dati dalle tabelle PurchaseOrderHeader e PurchaseOrderDetail. È inoltre possibile personalizzare le operazioni di modifica dei dati in modo che i dati correlati vengano modificati insieme. Per un esempio di modifica dei dati nelle tabelle correlate tramite un'operazione di dominio, vedere Gerarchie composizionali.

Per visualizzare i dati dalle tabelle correlate

  1. Nel progetto HRApp fare clic con il pulsante destro del mouse sulla cartella Views, scegliere Aggiungi, quindi fare clic su Nuovo elemento.

  2. Aggiungere una nuova pagina Silverlight denominata PurchaseOrders.xaml.

  3. Aprire PurchaseOrders.xaml.

  4. Aggiungere il seguente codice XAML tra i tag <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. Aprire MainPage.xaml.

  6. Dopo il collegamento EmployeeList, aggiungere il seguente codice XAML per includere un collegamento alla pagina PurchaseOrders.

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

  8. Aggiungere gli attributi Include e Composition alla proprietà PurchaseOrderDetails nella classe PurchaseOrderHeaderMetadata.

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

  10. Modificare il metodo GetPurchaseOrderHeaders in modo che anche i record correlati in PurchaseOrderDetails vengano recuperati con la query.

    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. Aprire PurchaseOrders.xaml.

  12. Scegliere Mostra origini dati dal menu Dati per aprire la finestra Origini dati.

  13. Trascinare il nodo PurchaseOrderHeader nell'area di progettazione per PurchaseOrders.xaml.

    RIA_Order_Header

    Viene visualizzato un elemento DataGrid con colonne provenienti dalla tabella PurchaseOrderHeader.

  14. Nella finestra Origini dati espandere il nodo PurchaseOrderHeader.

  15. Trascinare il nodo PurchaseOrderDetails presente nel nodo PurchaseOrderHeader nell'area di progettazione subito sotto l'elemento DataGrid per PurchaseOrderHeader.

    RIA_Order_Details

    Viene visualizzato un elemento DataGrid con colonne provenienti dalla tabella PurchaseOrderDetails.

  16. In visualizzazione XAML, individuare i controlli DataGrid per PurchaseOrderHeader e PurchaseOrderDetails.

  17. Rimuovere la proprietà Width=”400” da ogni elemento DataGrid in modo da riempire la larghezza disponibile.

  18. Prima dell'elemento DataGrid relativo a PurchaseOrderHeader, aggiungere il seguente controllo TextBlock per etichettare i dati.

    <TextBlock Text="Order Headers"></TextBlock>
    
  19. Prima dell'elemento DataGrid relativo a PurchaseOrderDetails, aggiungere il seguente controllo TextBlock per etichettare i dati.

    <TextBlock Text="Order Details"></TextBlock>
    
  20. Per limitare il numero di record recuperato, aggiungere il descrittore di filtro seguente al controllo DomainDataSource.

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

    Di seguito è riportato il codice XAML completo per 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. Eseguire l'applicazione e fare clic sul collegamento Ordini di acquisto.

  22. Selezionare record diversi nell'elemento DataGrid relativo a PurchaseOrderHeader.

    Si noti che i record di PurchaseOrderDetail correlati vengono visualizzati automaticamente.

    RIA_Details_and_Header

Passaggi successivi

In questa procedura dettagliata è stata fornita una panoramica di molte delle funzionalità di RIA Services . Per dettagli su aree specifiche, vedere le altre procedure dettagliate fornite nella presente documentazione.

Vedere anche

Attività

Procedura dettagliata: visualizzazione di dati in un'applicazione aziendale di Silverlight
Procedura dettagliata: utilizzo del servizio di autenticazione con l'applicazione aziendale di Silverlight