Exemplarische Vorgehensweise: Einführung in RIA Services
Diese exemplarische Vorgehensweise bietet einen Überblick über zahlreiche Funktionen in WCF RIA Services. In dieser exemplarischen Vorgehensweise erstellen Sie eine RIA Services -Anwendung, von der Daten aus Tabellen in der AdventureWorks OLTP-Beispieldatenbank abgerufen werden. Zuerst werden die Daten durch Angabe von LoadOperation abgerufen. Diese Daten werden dann mit dem DomainDataSource-Steuerelement abgerufen. Sie geben Sortierung, Filterung und Paging für das Datendarstellungssteuerelement an und fügen ein DataForm-Steuerelement hinzu, um eine ausführliche Ansicht der Daten zu präsentieren. Sie wenden Validierungsregeln auf die Felder an und ermöglichen dem Benutzer das Bearbeiten von Datenwerten. Sie beschränken den Zugriff auf einen Domänenvorgang auf authentifizierte Benutzer. Schließlich definieren Sie die Zuordnung zwischen zwei verknüpften Tabellen und zeigen die verknüpften Daten an.
Tipp: |
---|
Kürzere exemplarische Vorgehensweisen für die ersten Schritte zum Erstellen einer einfacheren RIA Services -Projektmappe finden Sie unter Exemplarische Vorgehensweise: Erstellen einer RIA Services-Projektmappe oder Exemplarische Vorgehensweise: Verwenden der Silverlight-Geschäftsanwendungsvorlage. |
Erforderliche Komponenten
Für diese und die anderen exemplarischen Vorgehensweisen in der WCF RIA Services-Dokumentation müssen zusätzlich zu WCF RIA Services und dem WCF RIA Services-Toolkit mehrere erforderliche Programme installiert und korrekt konfiguriert werden, z. B. Visual Studio 2010, die Silverlight Developer-Laufzeit und das Silverlight-SDK. Zudem müssen Sie SQL Server 2008 R2 Express with Advanced Services installieren und konfigurieren und die AdventureWorks OLTP- und LT-Datenbanken installieren.
Ausführliche Anweisungen für jede dieser erforderlichen Komponenten finden Sie in den Themen unter Erforderliche Komponenten für WCF RIA Services. Folgen Sie den Anweisungen in diesen Themen, bevor Sie mit dieser exemplarischen Vorgehensweise fortfahren, um sicherzustellen, dass beim Ausführen der exemplarischen Vorgehensweisen für RIA Services so wenig Probleme wie möglich auftreten.
Erstellen und Einrichten der Projektmappe
In diesem Abschnitt wird die Projektmappe erstellt und eingerichtet.
So erstellen Sie eine neue WCF RIA Services-Anwendung
Erstellen Sie in Visual Studio 2010 ein neues RIA Services -Projekt, indem Sie Datei, Neu und dann Projekt auswählen.
Das Dialogfeld Neues Projekt wird angezeigt.
Erweitern Sie im Bereich Installierte Vorlagen den Knoten Visual Basic oder Visual C#, und wählen Sie die Kategorie Silverlight aus.
Wählen Sie die Vorlage Silverlight-Geschäftsanwendung aus, und geben Sie für die Anwendung den Namen HRApp ein.
Klicken Sie auf OK.
Beachten Sie die Struktur der Projektmappe, die erstellt wird:
Die Projektmappe besteht aus zwei Projekten: einem Silverlight-Clientprojekt mit dem Namen HRApp und einem ASP.NET-Webanwendungs-Serverprojekt mit dem Namen HRApp.Web.
Die Standardprojektmappe enthält zahlreiche automatisch implementierte Funktionen, einschließlich Navigation, Benutzeranmeldung und -abmeldung sowie Registrierung neuer Benutzer.
Erstellen Sie die Anwendung, und führen Sie sie aus (F5), und untersuchen Sie die Standardimplementierung.
Schließen Sie den Webbrowser.
So richten Sie die Anwendung ein
Öffnen Sie im Projektmappen-Explorer im Clientprojekt "MainPage.xaml".
Suchen Sie in der XAML-Ansicht den TextBlock mit der Bezeichnung
ApplicationNameTextBlock
.Wie aus dem folgenden Markup hervorgeht, wird der Anwendungsname aus einer Ressource abgerufen.
<TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}" Text="{Binding ApplicationStrings.ApplicationName, Source={StaticResource ResourceWrapper}}"/>
Erweitern Sie im Projektmappen-Explorer den Ordner "Assets", und erweitern Sie dann den Ordner "Resources".
Öffnen Sie die Datei "ApplicationStrings.resx".
Ändern Sie die ApplicationName-Ressource in Personalanwendung.
Speichern und schließen Sie die Datei "ApplicationStrings.resx".
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner "Views", klicken Sie auf Hinzufügen und anschließend auf Neues Element.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.
Wählen Sie in Installierte Vorlagen in der Kategorie Silverlight die Vorlage Silverlight-Seite aus, und nennen Sie sie EmployeeList.xaml.
Klicken Sie auf Hinzufügen.
Öffnen Sie "EmployeeList.xaml", wenn die Datei nicht automatisch geöffnet wird.
Fügen Sie folgenden XAML-Code zwischen den
<Grid>
-Tags hinzu.<ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}" > <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}"> <TextBlock Text="Employee List" Style="{StaticResource HeaderTextStyle}"/> </StackPanel> </ScrollViewer>
Speichern Sie die Datei "EmployeeList.xaml".
Öffnen Sie die Datei "MainPage.xaml".
Fügen Sie dem Seitenanfang eine neue Linkschaltfläche hinzu, indem Sie das folgende XAML zwischen den zwei vorhandenen Linkschaltflächen hinzufügen.
<HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}" NavigateUri="/EmployeeList" TargetName="ContentFrame" Content="Employee List"/> <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
Führen Sie die Anwendung aus. Rechts oben auf der Seite befindet sich der Link Mitarbeiterliste (zwischen den Links Startseite und Info). Klicken Sie darauf, um im Text der Seite "Mitarbeiterliste" anzuzeigen.
Anzeigen von Daten
In diesem Abschnitt erstellen Sie für Tabellen in der AdventureWorks-Beispieldatenbank ein ADO.NET Entity Data Model. Anschließend erstellen Sie einen Domänendienst, der die Entitäten verfügbar macht und die Daten im Clientprojekt anzeigt.
So fügen Sie eine Datenquelle hinzu
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt HRApp.Web, klicken Sie auf Hinzufügen, und klicken Sie anschließend auf Neues Element.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.
Wählen Sie in der Kategorie Daten die Vorlage ADO.NET Entity Data Model aus.
Ändern Sie den Namen in AdventureWorks.edmx, und klicken Sie dann auf Hinzufügen.
Der Assistent für Entity Data Model wird geöffnet.
Klicken Sie auf der Seite Modellinhalte auswählen auf Aus Datenbank generieren und dann auf Weiter.
Erstellen Sie auf der Seite Wählen Sie Ihre Datenverbindung aus eine Verbindung zur AdventureWorks-Datenbank.
Benennen Sie die Einstellungen der Entitätsverbindung AdventureWorks_DataEntities, und klicken Sie dann auf Weiter.
Erweitern Sie auf der Seite Wählen Sie Ihre Datenbankobjekte aus den Knoten Tabellen.
Markieren Sie die Tabellen Employee, PurchaseOrderDetail und PurchaseOrderHeader jeweils mit einem Häkchen.
Nennen Sie den Modellnamespace AdventureWorks_DataModel, und klicken Sie dann auf Fertig stellen.
Das Entity Data Model wird im Designer angezeigt.
Erstellen Sie die Projektmappe.
So fügen Sie ein Domänendienstobjekt und eine Abfrage von Daten hinzu
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt HRApp.Web, klicken Sie auf Hinzufügen, und klicken Sie anschließend auf Neues Element.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.
Wählen Sie in der Kategorie Web die Vorlage Domänendienstklasse aus.
Nennen Sie das neue Element OrganizationService.
Klicken Sie auf Hinzufügen.
Wählen Sie im Dialogfeld Neue Domänendienstklasse hinzufügen die Optionen Employee, PurchaseOrderDetail und PurchaseOrderHeader aus der Liste "Entitäten" aus, und wählen Sie dann für jede Entität Bearbeitung aktivieren aus.
Stellen Sie sicher, dass die Kontrollkästchen Clientzugriff aktivieren und Zugeordnete Klassen für Metadaten generieren aktiviert werden.
Klicken Sie auf OK.
Die Dateien "OrganizationService.cs/vb" und "OrganizationService.metadata.cs/vb" werden dem Projekt hinzugefügt.
Öffnen Sie die Datei "OrganizationService.cs/vb".
Für jede Entität wurde eine Abfrage-, Einfüge-, Update- und Löschmethode erstellt. Eine Abfragemethode wird immer für eine Entität erstellt. Die Einfüge-, die Update- und die Löschmethode wurden hinzugefügt, da Bearbeitung aktivieren ausgewählt wurde.
Passen Sie die
GetEmployees()
-Abfragemethode an, damit die nach EmployeeID sortierten Mitarbeiter zurückgegeben werden. Ersetzen Sie dazu den generierten Code durch den folgenden Code.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); }
Erstellen Sie die Projektmappe.
Durch Erstellen der Projektmappe werden der Domänenkontext und die Entitäten im Clientprojekt generiert.
Öffnen Sie die Datei "EmployeeList.xaml".
Ziehen Sie von der Toolbox ein TextBlock-Steuerelement in die Entwurfsansicht, und zwar unmittelbar hinter dem DataGrid-Steuerelement.
Durch Ziehen eines DataGrid in die Entwurfsansicht wird ein Verweis auf die System.Windows.Controls.Data-Assembly hinzugefügt, und das
sdk
-Präfix wird dem Seitenelement hinzugefügt.Ändern Sie die Standardwerte für das DataGrid-Steuerelement, in dem Sie die Eigenschaften Höhe und Breite entfernen und folgende Eigenschaften festlegen: Schreibschutz, automatisches Generieren von Spalten und Mindesthöhe.
<sdk:DataGrid AutoGenerateColumns="True" IsReadOnly="True" Name="dataGrid1" MinHeight="100" />
Speichern Sie die Datei "EmployeeList.xaml".
Öffnen Sie die Datei "EmployeeList.xaml.cs/vb".
Fügen Sie die folgende using- oder Imports-Anweisung hinzu.
Imports System.ServiceModel.DomainServices.Client
using HRApp.Web; using System.ServiceModel.DomainServices.Client;
Instanziieren Sie die
OrganizationContext
-Klasse, und laden Sie Mitarbeiterdaten, indem Sie der Datei "EmployeeList.xaml.cs/vb" den folgenden Code hinzufügen.Die
OrganizationContext
-Klasse wird automatisch im Clientprojekt auf Grundlage derOrganizationService
-Klasse im Serverprojekt generiert.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) { } }
Führen Sie die Anwendung aus.
Klicken Sie auf den Link Mitarbeiterliste, um das DataGrid anzuzeigen.
So fügen Sie eine benutzerdefinierte Abfrage hinzu
Öffnen Sie im HRApp.Web-Projekt die Datei "OrganizationService.cs/vb".
Fügen Sie eine neue Methode mit der Bezeichnung
GetSalariedEmployees
hinzu, indem Sie dem Textkörper der Klasse den folgenden Code hinzufügen.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); }
Erstellen Sie die Projektmappe.
Öffnen Sie im Clientprojekt "EmployeeList.xaml.cs/vb".
Ersetzen Sie im Konstruktor den Aufruf zu
GetEmployeesQuery()
durch einen Aufruf vonGetSalariedEmployeesQuery()
._OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Beachten Sie, dass für alle angezeigten Mitarbeiter der SalariedFlag-Wert aktiviert ist. Mitarbeiter mit EmployeeID 1, 2 und 4 werden nicht mehr in der Liste angezeigt, da sie nicht entlohnt werden.
So fügen Sie eine Domänendatenquelle hinzu
Öffnen Sie die Datei "EmployeeList.xaml".
Ziehen Sie von der Toolbox das DomainDataSource-Steuerelement unmittelbar vor dem DataGrid in die Entwurfsansicht. Die DomainDataSource wird möglicherweise am unteren Rand der Liste der Steuerelemente angezeigt.
Tipp: Wenn sich das DomainDataSource-Steuerelement nicht in der Toolbox befindet, klicken Sie in der Toolbox mit der rechten Maustaste, und klicken Sie anschließend auf Elemente auswählen. Aktivieren Sie auf der Registerkarte Silverlight-Komponenten das Kontrollkästchen DomainDataSource, und klicken Sie auf OK. Wenn Sie das DomainDataSource-Steuerelement in die Entwurfsansicht ziehen, wird für den System.Windows.Controls-Namespace im Page-Element ein Verweis mit dem Präfix
riaControls
erstellt. Außerdem wird links unten in der Entwurfsansicht ein Datenquellensymbol angezeigt.Fügen Sie der XAML-Datei die folgende Namespacedeklaration für C#-Projektmappen hinzu.
xmlns:ds="clr-namespace:HRApp.Web"
Fügen Sie der XAML-Datei die folgende Namespacedeklaration für Visual Basic-Projektmappen hinzu.
xmlns:ds="clr-namespace:HRApp"
Nennen Sie das DomainDataSource-Steuerelement
employeeDataSource
, und legen Sie LoadSize, AutoLoad und die Abfragemethode fest, indem Sie das vorhandene XAML durch das folgende XAML ersetzen.<riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True"> </riaControls:DomainDataSource>
Legen Sie DomainContext für DomainDataSource fest, indem Sie das folgende XAML hinzufügen.
<riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True"> <riaControls:DomainDataSource.DomainContext> <ds:OrganizationContext/> </riaControls:DomainDataSource.DomainContext> </riaControls:DomainDataSource>
Ersetzen Sie DataGrid durch das folgende XAML:
<sdk:DataGrid AutoGenerateColumns="True" IsReadOnly="True" Name="dataGrid1" MinHeight="100" Height="Auto" ItemsSource="{Binding Data, ElementName=employeeDataSource}" />
Öffnen Sie die Datei "EmployeeList.xaml.cs/vb".
Entfernen Sie im Konstruktor den Code, bzw. kommentieren Sie ihn aus, um die
OrganizationContext
-Instanz, den Aufruf vonGetSalariedEmployeesQuery()
und den Code zu instanziieren und um die ItemsSource-Eigenschaft des DataGrid-Steuerelements festzulegen.Sie müssen nicht mehr explizit Daten laden, da DomainDataSource dies automatisch übernimmt.
'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()); }
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Die Anwendung funktioniert ebenso wie zuvor.
So fügen Sie der Datenquelle Sortierung, Filterung und Paging hinzu
Öffnen Sie die Datei "EmployeeList.xaml".
Fügen Sie in DomainDataSource die folgenden SortDescriptors hinzu, um anzugeben, wie Daten in DataGrid sortiert werden.
Dieses XAML zeigt, wie die Spalte "VacationHours" in aufsteigender Reihenfolge sortiert wird.
<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>
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Die Daten werden nach "VacationHours" sortiert, und Sie können die Sortierrichtung durch Klicken auf die Spaltenüberschrift ändern.
Öffnen Sie die Datei "EmployeeList.xaml".
Damit der Benutzer durch Angabe eines Werts nach den zurückzugebenden Datensätzen filtern kann, fügen Sie vor DataGrid das folgende XAML hinzu.
Das XAML fügt ein TextBox-Steuerelement hinzu, damit der Benutzer einen Wert eingeben kann.
<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>
Fügen Sie in DomainDataSource einen Filterdeskriptor hinzu, der an das zuvor hinzugefügte TextBox-Steuerelement gebunden ist.
<riaControls:DomainDataSource.FilterDescriptors> <riaControls:FilterDescriptor PropertyPath="VacationHours" Operator="IsGreaterThanOrEqualTo" IgnoredValue="" Value="{Binding ElementName=vacationHoursText, Path=Text}" > </riaControls:FilterDescriptor> </riaControls:DomainDataSource.FilterDescriptors>
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Geben Sie im Textfeld Min Vacation Hours Filter 70 ein.
Bei den aufgeführten Mitarbeitern sind die Werte für VacationHours größer oder gleich 70.
Öffnen Sie die Datei "EmployeeList.xaml".
Ziehen Sie von der Toolbox ein DataPager-Steuerelement, und platzieren Sie es unmittelbar unterhalb von DataGrid.
Legen Sie die Seitengröße auf 5 fest, und legen Sie die Quelle entsprechend der Darstellung im folgenden XAML fest.
<sdk:DataPager PageSize="5" Source="{Binding Data, ElementName=employeeDataSource}" HorizontalAlignment="Left" />
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Sie sehen nur 5 Zeilen mit gefilterten Daten pro Seite und Pager-Steuerelemente unter DataGrid.
Erstellen einer Master-/Detailansicht
In diesem Abschnitt erstellen Sie mithilfe des DataForm-Steuerelements im Silverlight-Toolkit eine ausführliche Ansicht der Daten. Standardmäßig enthält die Silverlight-Geschäftsanwendungs-Projektvorlage die System.Windows.Controls.Data.DataForm.Toolkit.dll-Binärdatei im Ordner "Libs".
So fügen Sie ein DataForm hinzu
Öffnen Sie die Datei "EmployeeList.xaml".
Fügen Sie die folgende Namespacedeklaration hinzu.
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
Fügen Sie nach dem DataPager-Steuerelement das folgende XAML hinzu, um ein DataForm-Steuerelement hinzuzufügen.
Dieses XAML legt die DataForm-Attribute fest und gibt die anzuzeigenden Spalten an.
<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>
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Das DataForm zeigt Details des im DataGrid ausgewählten Elements.
Aktualisieren der Datenbank
Wenn Sie das Kontrollkästchen Bearbeitung aktivieren im Dialogfeld Neue Domänendienstklasse aktivieren, werden Methoden in der Domänendienstebene generiert, um die Entität zu aktualisieren, einzufügen und zu löschen. In diesem Abschnitt fügen Sie der Benutzeroberfläche der Mitarbeiterliste Bearbeitungsschaltflächen hinzu, um Benutzern die Ausführung dieser Vorgänge zu ermöglichen.
So aktualisieren Sie einen Datensatz
Öffnen Sie die Datei "EmployeeList.xaml".
Fügen Sie nach dem DataForm-Steuerelement das folgende XAML hinzu, um eine Schaltfläche mit der Bezeichnung "Senden" hinzuzufügen.
<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>
Geben Sie im DomainDataSource-Steuerelement für das SubmittedChanges-Ereignis einen Ereignishandler an.
<riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True" SubmittedChanges="employeeDataSource_SubmittedChanges">
Öffnen Sie die Datei "EmployeeList.xaml.cs/vb".
Fügen Sie den folgenden Ereignishandler für das Schaltflächen-Klickereignis hinzu.
Die
submitButton
wird deaktiviert, um zu verhindern, dass der Benutzer die Änderung erneut sendet, während der Vorgang bearbeitet wird.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(); }
Fügen Sie einen Ereignishandler für das SubmittedChanges-Ereignis hinzu, der überprüft, ob der Sendevorgang erfolgreich abgeschlossen wurde, und
submitButton
aktiviert.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; }
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Wählen Sie einen Mitarbeiter aus, und klicken Sie rechts oben im Datenformular auf das Stiftsymbol, um die Bearbeitung zu aktivieren.
Sie können jetzt jedes bearbeitbare Feld ändern.
Nehmen Sie Änderungen an den Mitarbeiterdaten vor, und klicken Sie auf OK.
Klicken Sie auf Senden, um die Daten zu speichern.
Änderungen werden nur dann in der Datenbank auf dem Server gespeichert, wenn Sie auf die Schaltfläche "Senden" klicken.
So fügen Sie einem Domänendienst benutzerdefinierte Methoden hinzu
Öffnen Sie im HRApp.Web-Serverprojekt die Datei "OrganizationService.cs/vb".
Fügen Sie die folgende benutzerdefinierte Methode mit dem Namen
ApproveSabbatical
hinzu.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; }
Erstellen Sie die Projektmappe.
Öffnen Sie die Datei "EmployeeList.xaml".
Fügen Sie nach der Schaltfläche "Senden" das folgende XAML hinzu, um eine Schaltfläche mit der Bezeichnung "Approve Sabbatical" (Beurlaubung genehmigen) hinzuzufügen.
<Button x:Name="approveSabbatical" Width="115" Height="23" Content="Approve Sabbatical" Margin="4,0,0,0" Click="approveSabbatical_Click"/>
Öffnen Sie die Datei "EmployeeList.xaml.cs/vb".
Fügen Sie den folgenden Ereignishandler für das Schaltflächen-Klickereignis hinzu, durch das der Vorgang der ApproveSabbatical-Domäne aufgerufen wird.
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(); }
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Klicken Sie auf die Schaltfläche Approve Sabbatical. Beachten Sie, dass das Kontrollkästchen "CurrentFlag" für den ausgewählten Mitarbeiter deaktiviert ist.
Validieren von Daten
Das DataForm-Steuerelement kann Validierungsfehler aus der Datenzugriffsebene (DAL) anzeigen. Wenn Sie z. B. einen nicht ganzzahligen Wert im Feld "VacationHours" eingeben, wird ein Validierungsfehler angezeigt. Die folgende Abbildung zeigt ein Beispiel des Validierungsverhaltens.
Wenn Sie das Kontrollkästchen Zugeordnete Klassen für Metadaten generieren im Dialogfeld Neue Domänendienstklasse aktivieren, wird eine Datei, die Metadaten enthält, erstellt. In dieser exemplarischen Vorgehensweise wird die Metadatendatei "OrganizationService.metadata.cs/vb" genannt. In diesem Abschnitt fügen Sie der Datei Validierungsattribute hinzu. Die Validierungsregeln werden in den Client- und Serverprojekten erzwungen.
Sie erstellen außerdem eine Benutzeroberfläche, um das Hinzufügen neuer Mitarbeiterdatensätze zur Datenbank zu ermöglichen. Die Validierungsregeln, die Sie in den vorherigen Abschnitten hinzugefügt haben, werden automatisch in der neuen Benutzeroberfläche angewendet.
So fügen Sie Basisvalidierung hinzu
Öffnen Sie im HRApp.web-Projekt die Datei "OrganizationService.metadata.cs/vb".
Fügen Sie der
Gender
-Eigenschaft und derVacationHours
-Eigenschaft die folgenden Attribute hinzu.<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; }
Erstellen Sie die Projektmappe.
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Wählen Sie einen Mitarbeiter aus, und klicken Sie rechts oben im Datenformular auf das Stiftsymbol, um die Bearbeitung zu aktivieren.
Geben Sie einen Wert im Feld Vacation Hours ein, der nicht innerhalb des gültigen Bereichs (0-70) liegt, und verschieben Sie den Fokus zu einem anderen Steuerelement.
Für Urlaubsstunden wird ein Validierungsfehler angezeigt.
Löschen Sie den Wert im Feld Gender, und verschieben Sie den Fokus zu einem anderen Steuerelement.
Ein Validierungsfehler für die Angabe des Geschlechts wird angezeigt.
So fügen Sie eine benutzerdefinierte Validierung hinzu
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt HRApp.Web, klicken Sie auf Hinzufügen, und klicken Sie anschließend auf Neues Element.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.
Wählen Sie in der Kategorie Code die Vorlage Codedatei aus.
Nennen Sie das neue Element OrganizationService.shared.cs oder OrganizationService.shared.vb.
Dateien, die mit
.shared.cs
oder.shared.vb
enden, sind sowohl in den Client- als auch in den Serverprojekten verfügbar. Freigegebene Dateien ermöglichen es Ihnen, die gleiche Validierungsregel in beiden Projekten auszuführen. Nach dem Erstellen der Projektmappe in einem späteren Schritt finden Sie im ausgeblendeten Ordner "Generated_Code" auf dem Client die Datei "OrganizationService.shared.cs/vb".Klicken Sie auf Hinzufügen.
Um eine benutzerdefinierte Validierungsklasse zu erstellen, mit der die der
Gender
-Eigenschaft zugewiesenen Werte überprüft werden, fügen Sie der freigegebenen Datei den folgenden Code hinzu.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" }); } } } }
Öffnen Sie die Datei "OrganizationService.metadata.cs/vb".
Fügen Sie der
Gender
-Eigenschaft das folgende benutzerdefinierte Validierungsattribut hinzu.<Required()> _ <CustomValidation(GetType(GenderValidator), "IsGenderValid")> _ Public Property Gender As String
[CustomValidation(typeof(HRApp.Web.GenderValidator), "IsGenderValid")] [Required] public string Gender { get; set; }
Erstellen Sie die Projektmappe.
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Wählen Sie einen Mitarbeiter aus, und klicken Sie rechts oben im Datenformular auf das Stiftsymbol, um die Bearbeitung zu aktivieren.
Geben Sie einen Wert im Feld Gender ein, der weder M noch W ist und den Fokus zu einem anderen Steuerelement verschiebt.
Das Ergebnis der benutzerdefinierten Validierung wird angezeigt.
Hinzufügen von neuen Datensätzen
In diesem Abschnitt fügen Sie ein Formular hinzu, das dem Benutzer ermöglicht, einen neuen Datensatz in der Tabelle "Employee" zu erstellen.
So fügen Sie einen neuen Datensatz hinzu
Fügen Sie im HRApp-Projekt ein neues Element hinzu.
Wählen Sie in der Kategorie Silverlight die Vorlage Untergeordnetes Silverlight-Fenster aus.
Nennen Sie das neue Element EmployeeRegistrationWindow.xaml.
Klicken Sie auf Hinzufügen.
Öffnen Sie die Datei "EmployeeRegistrationWindow.xaml.cs/vb".
Wenn Sie C# verwenden, fügen Sie die folgende using-Anweisung hinzu.
using HRApp.Web;
Fügen Sie eine Eigenschaft für die neue
Employee
-Entität hinzu, die mit den Benutzerwerten erstellt wird.Public Property NewEmployee As Employee
public Employee NewEmployee { get; set; }
Öffnen Sie die Datei "EmployeeRegistrationWindow.xaml".
Fügen Sie der Datei "EmployeeRegistrationWindow.xaml" die folgende Namespacedeklaration hinzu, um das DataForm-Steuerelement in diesem Fenster zu verwenden.
xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
Fügen Sie der Datei "EmployeeRegistrationWindow.xaml" das folgende DataForm-Steuerelement unmittelbar vor der Schaltfläche "Abbrechen" hinzu.
<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>
Öffnen Sie die Datei "EmployeeRegistrationWindow.xaml.cs/vb".
Fügen Sie den folgenden Code hinzu, um eine neue
Employee
-Instanz zu erstellen und entweder das Ausführen eines Commits für die neue Instanz oder den Abbruch des Einfügevorgangs zu regeln.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; } }
Öffnen Sie die Datei "EmployeeList.xaml".
Fügen Sie zwischen DataPager und DataForm das folgende XAML hinzu, um eine Schaltfläche mit dem Namen
addNewEmployee
zu erstellen.<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>
Öffnen Sie die Datei "EmployeeList.xaml.cs/vb".
Fügen Sie den folgenden Code hinzu, um das Schaltflächen-Klickereignis zu behandeln und das EmployeeRegistrationWindow anzuzeigen.
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(); }
Fügen Sie die folgende Methode hinzu, um das closed-Ereignis für EmployeeRegistrationWindow zu behandeln.
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(); } }
Öffnen Sie die Datei "OrganizationService.cs/vb".
Ändern Sie die
InsertEmployee
-Methode, indem Sie den folgenden Code hinzufügen.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); } }
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Klicken Sie auf die Schaltfläche Mitarbeiter hinzufügen.
Das EmployeeRegistrationWindow wird geöffnet.
Fügen Sie Daten im Fenster hinzu, und aktivieren Sie das Kontrollkästchen Salaried.
Klicken Sie auf OK.
Aktualisieren Sie die Seite, und stellen Sie sicher, dass der neue Mitarbeiter im DataGrid angezeigt wird.
Authentifizieren von Benutzern
In diesem Abschnitt beschränken Sie den Zugriff auf die ApproveSabbatical
-Methode auf authentifizierte Benutzer.
So fügen Sie die Authentifizierung hinzu
Öffnen Sie die Datei "OrganizationService.cs/vb".
Fügen Sie das RequiresAuthentication-Attribut der
ApproveSabbatical
-Methode hinzu.Wenn Sie das RequiresAuthentication-Attribut für einen Domänenvorgang übernehmen, stellen Sie sicher, dass nur authentifizierte Benutzer den Vorgang aufrufen können. Wenn ein anonymer Benutzer auf die Schaltfläche Approve Sabbatical (Beurlaubung genehmigen) klickt, wird der Vorgang nicht ausgeführt.
<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; }
Öffnen Sie die Datei "EmployeeList.xaml.cs/vb".
Fügen Sie die folgende using- oder Imports-Anweisung hinzu.
Imports System.ServiceModel.DomainServices.Client.ApplicationServices Imports HRApp.LoginUI
using System.ServiceModel.DomainServices.Client.ApplicationServices; using HRApp.LoginUI;
Ändern Sie die
approveSabbatical_Click
-Methode, und fügen Sie einen LoggedIn-Handler hinzu, um zu überprüfen, ob der Benutzer authentifiziert ist.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; }
Führen Sie die Anwendung aus, und klicken Sie auf den Link Mitarbeiterliste.
Wählen Sie einen Mitarbeiterdatensatz aus, und klicken Sie auf die Schaltfläche Approve Sabbatical (Beurlaubung genehmigen).
Sie werden an das Anmeldefenster umgeleitet.
Klicken Sie auf den Link Jetzt registrieren.
Füllen Sie die Pflichtfelder aus, um ein neues Konto zu erstellen.
Klicken Sie auf OK.
Sie werden mit diesem Konto angemeldet, und der Name wird in einer Leiste unterhalb der Navigationslinks angezeigt.
Anzeigen von verknüpften Daten
Mit RIA Services können Sie leicht mit Daten aus verknüpften Tabellen arbeiten. In diesem Abschnitt fügen Sie eine neue Silverlight-Seite hinzu und zeigen Daten aus den Tabellen "PurchaseOrderHeader" und "PurchaseOrderDetail" an. Sie können auch die Datenänderungsvorgänge anpassen, damit die verknüpften Daten zusammen geändert werden. Ein Beispiel zum Ändern der Daten in verknüpften Tabellen durch einen Domänenvorgang finden Sie unter Festgelegte Hierarchien.
So zeigen Sie Daten aus verknüpften Tabellen an
Klicken Sie im HRApp-Projekt mit der rechten Maustaste auf den Ordner "Views", klicken Sie auf Hinzufügen und anschließend auf Neues Element.
Fügen Sie eine neue Silverlight-Seite mit dem Namen "PurchaseOrders.xaml" hinzu.
Öffnen Sie die Seite "PurchaseOrders.xaml".
Fügen Sie folgenden XAML-Code zwischen den
<Grid>
-Tags hinzu.<ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource PageScrollViewerStyle}" > <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}"> <TextBlock Text="Purchase Orders" Style="{StaticResource HeaderTextStyle}"/> </StackPanel> </ScrollViewer>
Öffnen Sie die Datei "MainPage.xaml".
Fügen Sie nach dem EmployeeList-Link das folgende XAML hinzu, um einen Link auf die Seite "PurchaseOrders" einzuschließen.
<Rectangle x:Name="Divider3" Style="{StaticResource DividerStyle}"/> <HyperlinkButton x:Name="Link4" Style="{StaticResource LinkStyle}" NavigateUri="/PurchaseOrders" TargetName="ContentFrame" Content="Purchase Orders"/>
Öffnen Sie die Datei "OrganizationService.metadata.cs/vb".
Fügen Sie der
PurchaseOrderDetails
-Eigenschaft das Include-Attribut und das Composition-Attribut in derPurchaseOrderHeaderMetadata
-Klasse hinzu.<Include()> _ <Composition()> _ Public Property PurchaseOrderDetails As EntityCollection(Of PurchaseOrderDetail)
[Include] [Composition] public EntityCollection<PurchaseOrderDetail> PurchaseOrderDetails { get; set; }
Öffnen Sie die Datei "OrganizationService.cs/vb".
Ändern Sie die
GetPurchaseOrderHeaders
-Methode, damit die verknüpften Datensätze inPurchaseOrderDetails
auch mit der Abfrage abgerufen werden.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); }
Öffnen Sie die Seite "PurchaseOrders.xaml".
Klicken Sie im Menü Daten auf Datenquellen anzeigen, um das Datenquellenfenster zu öffnen.
Ziehen Sie den Knoten PurchaseOrderHeader in die Entwurfsoberfläche für "PurchaseOrders.xaml".
Ein DataGrid mit Spalten aus der Tabelle "PurchaseOrderHeader" wird angezeigt.
Erweitern Sie im Fenster Datenquellen den Knoten PurchaseOrderHeader.
Ziehen Sie den Knoten PurchaseOrderDetails, der sich im Knoten PurchaseOrderHeader befindet, zur Entwurfsoberfläche, direkt unterhalb von DataGrid für PurchaseOrderHeader.
Ein DataGrid mit Spalten aus der Tabelle "PurchaseOrderDetails" wird angezeigt.
Suchen Sie in der XAML-Ansicht die DataGrid-Steuerelemente für
PurchaseOrderHeader
als auch fürPurchaseOrderDetails
.Entfernen Sie die
Width=”400”
-Eigenschaft aus jedem DataGrid, damit es die verfügbare Breite ausfüllt.Fügen Sie vor dem PurchaseOrderHeader DataGrid das folgende TextBlock-Steuerelement hinzu, um die Daten zu beschriften.
<TextBlock Text="Order Headers"></TextBlock>
Fügen Sie vor PurchaseOrderDetails DataGrid das folgende TextBlock-Steuerelement hinzu, um die Daten zu beschriften.
<TextBlock Text="Order Details"></TextBlock>
Um die Anzahl von Datensätzen zu beschränken, die abgerufen werden, fügen Sie dem DomainDataSource-Steuerelement den folgenden Filterdeskriptor hinzu.
<riaControls:DomainDataSource.FilterDescriptors> <riaControls:FilterDescriptor PropertyPath="PurchaseOrderID" Operator="IsLessThan" Value="10"></riaControls:FilterDescriptor> </riaControls:DomainDataSource.FilterDescriptors>
Nachfolgend wird das vollständige XAML für "PurchaseOrders.xaml" angezeigt.
<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>
Führen Sie die Anwendung aus, und klicken Sie auf den Link Bestellungen.
Wählen Sie andere Datensätze im PurchaseOrderHeader DataGrid aus.
Beachten Sie, dass die verknüpften PurchaseOrderDetail-Datensätze automatisch angezeigt werden.
Nächste Schritte
In dieser exemplarische Vorgehensweise wurden Ihnen zahlreiche der Funktionen in RIA Services vorgestellt. Details zu bestimmten Bereichen finden Sie in den anderen exemplarischen Vorgehensweisen in dieser Dokumentation.
Siehe auch
Aufgaben
Exemplarische Vorgehensweise: Anzeigen von Daten in einer Silverlight-Geschäftsanwendung
Exemplarische Vorgehensweise: Verwenden des Authentifizierungsdiensts mit der Silverlight-Geschäftsanwendung