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.
Suggerimento: |
---|
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
In Visual Studio 2010, creare un nuovo progetto RIA Services selezionando File, Nuovo, quindi Progetto.
Verrà visualizzata la finestra di dialogo Nuovo progetto.
Nel riquadro Modelli installati espandere il nodo Visual Basic o Visual C#, quindi selezionare la categoria Silverlight.
Selezionare il modello Applicazione aziendale di Silverlight e denominare l'applicazione HRApp.
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.
Compilare ed eseguire (F5) l'applicazione ed esplorare l'implementazione predefinita.
Chiudere il browser Web.
Per impostare l'applicazione
In Esplora soluzioni, nel progetto client, aprire MainPage.xaml.
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}}"/>
In Esplora soluzioni espandere la cartella Assets, quindi la cartella Resources.
Aprire il file ApplicationStrings.resx.
Modificare la risorsa ApplicationName in HR Application.
Salvare e chiudere il file ApplicationStrings.resx.
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.
Selezionare il modello Silverlight Page dalla categoria Silverlight di Modelli installati e denominarlo EmployeeList.xaml.
Fare clic su Aggiungi.
Aprire EmployeeList.xaml, se non viene aperto automaticamente.
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>
Salvare il file EmployeeList.xaml.
Aprire MainPage.xaml.
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}"/>
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.
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
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.
Nella categoria Dati selezionare il modello ADO.NET Entity Data Model.
Denominarlo AdventureWorks.edmx e fare clic su Aggiungi.
Verrà aperta la procedura guidata Entity Data Model.
Nella pagina Scegli contenuto Model fare clic su Genera da database, quindi su Avanti.
Nella pagina Scegli la connessione dati creare una connessione al database AdventureWorks.
Denominare le impostazioni di connessione dell'entità AdventureWorks_DataEntities quindi fare clic su Avanti.
Espandere il nodo Tabelle nella pagina Seleziona oggetti di database.
Aggiungere segni di spunta accanto alle tabelle Employee, PurchaseOrderDetail e PurchaseOrderHeader.
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.
Compilare la soluzione.
Per aggiungere un oggetto del servizio del dominio ed eseguire una query per i dati
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.
Nella categoria Web, selezionare il modello Classe di DomainService.
Assegnare al nuovo elemento il nome OrganizationService.
Fare clic su Aggiungi.
Nella finestra di dialogo Aggiungi una nuova classe DomainService, selezionare Dipendente, PurchaseOrderDetail e PurchaseOrderHeader dall'elenco Entità, quindi selezionare Abilita modifica per ciascuna entità.
Assicurarsi che siano selezionate le caselle di controllo Abilita l'accesso client e Genera classi associate per i metadati.
Fare clic su OK.
I file OrganizationService.cs/vb e OrganizationService.metadata.cs/vb verranno aggiunti al progetto.
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.
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); }
Compilare la soluzione.
La compilazione della soluzione genera il Contesto del dominio e le entità nel progetto client.
Aprire il file EmployeeList.xaml.
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.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" />
Salvare il file EmployeeList.xaml.
Aprire il file EmployeeList.xaml.cs/vb.
Aggiungere le istruzioni using o Imports seguenti.
Imports System.ServiceModel.DomainServices.Client
using HRApp.Web; using System.ServiceModel.DomainServices.Client;
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 classeOrganizationService
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) { } }
Eseguire l'applicazione.
Fare clic sul collegamento Employee List per visualizzare l'elemento DataGrid.
Per aggiungere una query personalizzata
Nel progetto HRApp.Web, aprire OrganizationService.cs/vb.
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); }
Compilare la soluzione.
Nel progetto client aprire il file EmployeeList.xaml.cs/vb.
Nel costruttore, sostituire la chiamata a
GetEmployeesQuery()
con una chiamata aGetSalariedEmployeesQuery()
._OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
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.
Per aggiungere un'origine dati di dominio
Aprire il file EmployeeList.xaml.
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.
Suggerimento: 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.Per le soluzioni C#, aggiungere la dichiarazione dello spazio dei nomi seguente al file XAML.
xmlns:ds="clr-namespace:HRApp.Web"
Per le soluzioni Visual Basic, aggiungere la dichiarazione dello spazio dei nomi seguente al file XAML.
xmlns:ds="clr-namespace:HRApp"
Denominare il controllo DomainDataSource
employeeDataSource
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>
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>
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}" />
Aprire il file EmployeeList.xaml.cs/vb.
Nel costruttore, rimuovere o impostare come commento il codice per creare un'istanza di
OrganizationContext
, della chiamata aGetSalariedEmployeesQuery()
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()); }
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
Aprire il file EmployeeList.xaml.
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>
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.
Aprire il file EmployeeList.xaml.
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>
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>
Eseguire l'applicazione e fare clic sul collegamento Employee List.
Nella casella di testo Filtro: Ore ferie min., digitare 70.
Notare che per i dipendenti elencati il valore VacationHours è superiore o pari a 70.
Aprire il file EmployeeList.xaml.
Dalla casella degli strumenti, trascinare un controllo DataPager subito sotto all'elemento DataGrid.
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" />
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.
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
Aprire il file EmployeeList.xaml.
Aggiungere la dichiarazione dello spazio dei nomi seguente.
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
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>
Eseguire l'applicazione e fare clic sul collegamento Employee List.
L'elemento DataForm consente di visualizzare i dettagli dell'elemento selezionato nell'oggetto DataGrid.
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
Aprire il file EmployeeList.xaml.
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>
Nel controllo DomainDataSource specificare un gestore eventi per l'evento SubmittedChanges.
<riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True" SubmittedChanges="employeeDataSource_SubmittedChanges">
Aprire il file EmployeeList.xaml.cs/vb.
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(); }
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; }
Eseguire l'applicazione e fare clic sul collegamento Employee List.
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.
Apportare le modifiche ai dati dei dipendenti e fare clic su OK.
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
Nel progetto server HRApp.Web, aprire OrganizationService.cs/vb. File
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; }
Compilare la soluzione.
Aprire il file EmployeeList.xaml.
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"/>
Aprire il file EmployeeList.xaml.cs/vb.
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(); }
Eseguire l'applicazione e fare clic sul collegamento Employee List.
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.
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
Nel progetto server HRApp.web, aprire OrganizationService.metadata.cs/vb.
Aggiungere gli attributi seguenti alle proprietà
Gender
eVacationHours
.<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; }
Compilare la soluzione.
Eseguire l'applicazione e fare clic sul collegamento Employee List.
Selezionare un dipendente e fare clic sull'icona della matita nell'angolo superiore destro del modulo dati per abilitare la modifica.
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.
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
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.
Nella categoria Codice, selezionare il modello File di codice.
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.Fare clic su Aggiungi.
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" }); } } } }
Aprire il file OrganizationService.metadata.cs/vb.
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; }
Compilare la soluzione.
Eseguire l'applicazione e fare clic sul collegamento Employee List.
Selezionare un dipendente e fare clic sull'icona della matita nell'angolo superiore destro del modulo dati per abilitare la modifica.
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.
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
Aggiungere un nuovo elemento al progetto HRApp.
Nella categoria Silverlight, selezionare il modello Finestra secondaria Silverlight.
Denominare il nuovo elemento EmployeeRegistrationWindow.xaml.
Fare clic su Aggiungi.
Aprire il file EmployeeRegistrationWindow.xaml.cs/vb.
Se si utilizza C#, aggiungere l'istruzione using seguente.
using HRApp.Web;
Aggiungere una proprietà per la nuova entità
Employee
creata con i valori dell'utente.Public Property NewEmployee As Employee
public Employee NewEmployee { get; set; }
Aprire il file EmployeeRegistrationWindow.xaml.
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"
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>
Aprire il file EmployeeRegistrationWindow.xaml.cs/vb.
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; } }
Aprire il file EmployeeList.xaml.
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>
Aprire il file EmployeeList.xaml.cs/vb.
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(); }
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(); } }
Aprire il file OrganizationService.cs/vb.
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); } }
Eseguire l'applicazione e fare clic sul collegamento Employee List.
Fare clic sul pulsante Aggiungi dipendente.
Viene aperto l'elemento EmployeeRegistrationWindow.
Aggiungere dati nella finestra e selezionare la casella di controllo Stipendiato.
Fare clic su OK.
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
Aprire il file OrganizationService.cs/vb.
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; }
Aprire il file EmployeeList.xaml.cs/vb.
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;
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; }
Eseguire l'applicazione e fare clic sul collegamento Employee List.
Selezionare un record del dipendente e fare clic sul pulsante Approva congedo sabbatico.
L'utente verrà reindirizzato alla finestra di accesso.
Fare clic sul collegamento Registra ora.
Completare tutti i campi obbligatori per creare un nuovo account.
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
Nel progetto HRApp fare clic con il pulsante destro del mouse sulla cartella Views, scegliere Aggiungi, quindi fare clic su Nuovo elemento.
Aggiungere una nuova pagina Silverlight denominata PurchaseOrders.xaml.
Aprire PurchaseOrders.xaml.
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>
Aprire MainPage.xaml.
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"/>
Aprire il file OrganizationService.metadata.cs/vb.
Aggiungere gli attributi Include e Composition alla proprietà
PurchaseOrderDetails
nella classePurchaseOrderHeaderMetadata
.<Include()> _ <Composition()> _ Public Property PurchaseOrderDetails As EntityCollection(Of PurchaseOrderDetail)
[Include] [Composition] public EntityCollection<PurchaseOrderDetail> PurchaseOrderDetails { get; set; }
Aprire il file OrganizationService.cs/vb.
Modificare il metodo
GetPurchaseOrderHeaders
in modo che anche i record correlati inPurchaseOrderDetails
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); }
Aprire PurchaseOrders.xaml.
Scegliere Mostra origini dati dal menu Dati per aprire la finestra Origini dati.
Trascinare il nodo PurchaseOrderHeader nell'area di progettazione per PurchaseOrders.xaml.
Viene visualizzato un elemento DataGrid con colonne provenienti dalla tabella PurchaseOrderHeader.
Nella finestra Origini dati espandere il nodo PurchaseOrderHeader.
Trascinare il nodo PurchaseOrderDetails presente nel nodo PurchaseOrderHeader nell'area di progettazione subito sotto l'elemento DataGrid per PurchaseOrderHeader.
Viene visualizzato un elemento DataGrid con colonne provenienti dalla tabella PurchaseOrderDetails.
In visualizzazione XAML, individuare i controlli DataGrid per
PurchaseOrderHeader
ePurchaseOrderDetails
.Rimuovere la proprietà
Width=”400”
da ogni elemento DataGrid in modo da riempire la larghezza disponibile.Prima dell'elemento DataGrid relativo a PurchaseOrderHeader, aggiungere il seguente controllo TextBlock per etichettare i dati.
<TextBlock Text="Order Headers"></TextBlock>
Prima dell'elemento DataGrid relativo a PurchaseOrderDetails, aggiungere il seguente controllo TextBlock per etichettare i dati.
<TextBlock Text="Order Details"></TextBlock>
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>
Eseguire l'applicazione e fare clic sul collegamento Ordini di acquisto.
Selezionare record diversi nell'elemento DataGrid relativo a PurchaseOrderHeader.
Si noti che i record di PurchaseOrderDetail correlati vengono visualizzati automaticamente.
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