Share via


逐步解說:導覽 RIA Services

本逐步解說提供您 WCF RIA Services 中許多功能的概觀。在本逐步解說中,您會建立一個 RIA Services 應用程式,此應用程式會從 AdventureWorks OLTP 範例資料庫中的資料表擷取資料。首先,您要指定 LoadOperation 來擷取資料。接著,您要使用 DomainDataSource 控制項擷取該資料。您要針對資料展示控制項指定排序、篩選,以及分頁,然後加入 DataForm 控制項來呈現詳細的資料檢視。您要將驗證規則套用到欄位,然後讓使用者編輯資料值。您要將網域作業的存取權限制為認證的使用者。最後,您要定義兩個相關資料表之間的關聯,並顯示相關的資料。

Tip提示:
如需較簡短的逐步解說,了解如何藉由建立更基本的 RIA Services 方案快速入門,請參閱逐步解說:建立 RIA Services 方案逐步解說:使用 Silverlight 商務應用程式範本

必要條件

除了 WCF RIA Services 和 WCF RIA Services 工具組之外,在 WCF RIA Services 文件中呈現的這個逐步解說和其他逐步解說還需要正確安裝並設定數個必要程式 (例如 Visual Studio 2010 和 Silverlight 開發人員執行階段和 SDK)。要執行逐步解說還需要安裝並設定 SQL Server 2008 R2 Express with Advanced Services,以及安裝 AdventureWorks OLTP 和 LT 資料庫。

WCF RIA Services 的必要條件節點中的主題也提供符合這些必要條件的詳細指示。請先按照該處提供的指示進行,然後再進行本逐步解說,以確保您在進行本 RIA Services 逐步解說時不會發生問題。

建立與設定方案

在本節中,您要建立與設定方案。

若要建立新的 WCF RIA Services 應用程式

  1. 在 Visual Studio 2010 中,依序選取 [檔案]、[新增] 和 [專案],來建立新的 RIA Services 專案。

    [新增專案] 對話方塊隨即出現。

  2. 展開 [已安裝的範本] 窗格中的 [Visual Basic] 或 [Visual C#] 節點,然後選取 [Silverlight] 類別。

  3. 選取 [Silverlight 商務應用程式] 範本,並將應用程式命名為 HRApp

    RIA_HRAppStart

  4. 按一下 [確定]。

    請注意建立之方案的結構:

    • 此方案由兩個專案所組成:名稱為 HRApp 的 Silverlight 用戶端專案,以及名稱為 HRApp.Web 的 ASP.NET Web 應用程式伺服器專案。

    • 預設的方案包含許多自動實作的功能,包括導覽、使用者登入和登出,以及新使用者註冊。

    RIA_HRAppStructure

  5. 建置並執行 (F5) 應用程式,然後瀏覽預設的實作。

  6. 關閉 Web 瀏覽器。

若要設定應用程式

  1. 在 [方案總管] 的用戶端專案中,開啟 MainPage.xaml。

  2. 在 [XAML] 檢視中,尋找名稱為 ApplicationNameTextBlockTextBlock

    請注意應用程式名稱是從資源所擷取,如以下標記所示。

    <TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}" 
                       Text="{Binding ApplicationStrings.ApplicationName, Source={StaticResource ResourceWrapper}}"/>
    
  3. 展開 [方案總管] 中的 Assets 資料夾,然後展開 Resources 資料夾。

  4. 開啟 ApplicationStrings.resx 檔。

  5. 將 ApplicationName 資源變更為 HR 應用程式

  6. 儲存並關閉 ApplicationStrings.resx 檔。

  7. 以滑鼠右鍵按一下 [方案總管] 中的 Views 資料夾,並按一下 [加入],然後按一下 [新增項目]。

    [加入新項目] 對話方塊隨即顯示。

  8. 從 [已安裝的範本] 的 [Silverlight] 類別選取 [Silverlight 頁面] 範本,並將其命名為 EmployeeList.xaml

    RIA_HRAppAddPage

  9. 按一下 [加入]。

  10. 開啟 EmployeeList.xaml (若未自動開啟)。

  11. <Grid> 標記之間加入下列 XAML。

    <ScrollViewer x:Name="PageScrollViewer" Style="{StaticResource 
      PageScrollViewerStyle}" >
        <StackPanel x:Name="ContentStackPanel" Style="{StaticResource ContentStackPanelStyle}">
    
            <TextBlock Text="Employee List" Style="{StaticResource HeaderTextStyle}"/>
    
        </StackPanel>
    </ScrollViewer>
    
  12. 儲存 EmployeeList.xaml 檔。

  13. 開啟 MainPage.xaml。

  14. 在兩個現有的超連結按鈕之間加入下列 XAML,以便將新的超連結按鈕加入到頁面頂端。

    <HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}" NavigateUri="/EmployeeList" TargetName="ContentFrame" Content="Employee List"/>
    
    <Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
    
  15. 執行應用程式,並注意 [首頁] 和 [關於] 連結間之頁面右上角的新 [員工清單] 連結。按一下該連結,以便在頁面的主體中顯示 [員工清單]。

    RIA_HRAppPageView

顯示資料

在本節中,您要針對 AdventureWorks 範例資料庫中的資料表建立 ADO.NET 實體資料模型。接著,您要建立公開實體,並將該資料顯示在用戶端專案中的網域服務。

若要加入資料來源

  1. 以滑鼠右鍵按一下 [方案總管] 中的 [HRApp.Web 專案],按一下 [加入],然後按一下 [新增項目]。

    [加入新項目] 對話方塊隨即顯示。

  2. 選取 [資料] 類別中的 [ADO.NET 實體資料模型] 範本。

    RIA_HRAppAddEntity

  3. 將名稱變更為 AdventureWorks.edmx,然後按一下 [加入]。

    [實體資料模型精靈] 隨即開啟。

  4. 按一下 [選擇模型內容] 頁面上的 [從資料庫產生],再按 [下一步]。

  5. 在 [選擇您的資料連接] 頁面上,建立 AdventureWorks 資料庫的連接。

  6. 為實體連接設定 AdventureWorks_DataEntities 命名,然後按一下 [下一步]。

  7. 展開 [選擇您的資料庫物件] 頁面上的 [資料表] 節點。

  8. EmployeePurchaseOrderDetailPurchaseOrderHeader 資料表的旁邊加上核取標記。

  9. 將此模型命名空間命名為 AdventureWorks_DataModel,然後按一下 [完成]。

    實體資料模型就會出現在設計工具中。

  10. 建置方案。

若要加入資料的網域服務物件和查詢

  1. 以滑鼠右鍵按一下 [方案總管] 中的 [HRApp.Web 專案],按一下 [加入],然後按一下 [新增項目]。

    [加入新項目] 對話方塊隨即顯示。

  2. 選取 [Web] 類別中的 [DomainService 類別] 範本。

    RIA_HRAppAddService

  3. 將新的項目命名為 OrganizationService

  4. 按一下 [加入]。

  5. 在 [加入新的 DomainService 類別] 對話方塊中,選取 [實體] 清單中的 EmployeePurchaseOrderDetailPurchaseOrderHeader,然後選取每個實體的 [啟用編輯]。

  6. 確保 [啟用用戶端存取] 和 [為中繼資料產生關聯的類別] 核取方塊已選取。

  7. 按一下 [確定]。

    OrganizationService.cs/vb 和 OrganizationService.metadata.cs/vb 檔案隨即加入至專案中。

  8. 開啟 OrganizationService.cs/vb 檔案。

    請注意,系統已經針對每個實體建立查詢、插入、更新和刪除方法。系統永遠會針對實體建立查詢方法。由於選取了 [啟用編輯],因此會加入插入、更新和刪除方法。

  9. 使用下列程式碼取代產生的程式碼,以自訂 GetEmployees() 查詢方法傳回依 EmployeeID 排序的員工。

    Public Function GetEmployees() As IQueryable(Of Employee)
        Return Me.ObjectContext.Employees.OrderBy(Function(e) e.EmployeeID)
    End Function
    
    public IQueryable<Employee> GetEmployees()
    {
        return this.ObjectContext.Employees.OrderBy(e => e.EmployeeID);
    }
    
  10. 建置方案。

    建置方案會在用戶端專案中產生 [網域內容] 和實體。

  11. 開啟 EmployeeList.xaml。

  12. DataGrid 控制項從工具箱拖曳至 TextBlock 正後方的設計檢視。

    DataGrid 拖曳至設計檢視時,會新增 System.Windows.Controls.Data 組件的參考,並將 sdk 前置詞加入至 [頁面] 項目。

  13. 移除 [高度] 和 [寬度] 屬性、使其變成唯讀、將它設定為自動產生資料行,然後設定其最小高度,來變更 DataGrid 控制項的預設值。

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

  15. 開啟 EmployeeList.xaml.cs/vb。

  16. 加入下列 usingImports 陳述式。

    Imports System.ServiceModel.DomainServices.Client
    
    using HRApp.Web;
    using System.ServiceModel.DomainServices.Client;
    
  17. 將下列程式碼加入至 EmployeeList.xaml.cs/vb,以具現化 OrganizationContext 類別並載入員工資料。

    根據伺服器專案中的 OrganizationService 類別,在用戶端專案中會自動產生 OrganizationContext 類別。

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

  19. 按一下 [員工清單] 連結以查看 DataGrid

    RIA_HRAppDataGrid

若要加入自訂查詢

  1. 開啟 HRApp.Web 專案中的 OrganizationService.cs/vb。

  2. 將下列程式碼加入至類別的主體中,藉以加入名稱為 GetSalariedEmployees 的新方法。

    Public Function GetSalariedEmployees() As IQueryable(Of Employee)
        Return Me.ObjectContext.Employees.Where(Function(e) e.SalariedFlag = True).OrderBy(Function(e) e.EmployeeID)
    End Function
    
    public IQueryable<Employee> GetSalariedEmployees()
    {
        return this.ObjectContext.Employees.Where(e => e.SalariedFlag == true).OrderBy(e => e.EmployeeID);
    }
    
  3. 建置方案。

  4. 開啟用戶端專案中的 EmployeeList.xaml.cs/vb。

  5. 在建構函式中,將 GetEmployeesQuery() 的呼叫取代成 GetSalariedEmployeesQuery() 的呼叫。

    _OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
    
    _OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
    
  6. 執行應用程式,然後按一下 [員工清單] 連結。

    請注意,所有顯示的員工都會檢查 SalariedFlag 值。EmployeeID 為 1、2 和 4 的員工不會再出現在清單中,因為這些員工不支薪。

    RIA_HRAppFilteredDataGrid

若要加入網域資料來源

  1. 開啟 EmployeeList.xaml。

  2. DomainDataSource 控制項從 [工具箱] 拖曳至 DataGrid 正前方的設計檢視。DomainDataSource 可能會出現在控制項清單的底部。

    Tip提示:
    如果 DomainDataSource 控制項不在 [工具箱] 中,以滑鼠右鍵按一下 [工具箱],然後按一下 [選擇項目]。核取 [DomainDataSource] 下的 [Silverlight 元件] 索引標籤,然後按一下 [確定]。

    當您將 DomainDataSource 控制項拖曳至設計檢視時,系統會在 [頁面] 項目中,針對 System.Windows.Controls 命名空間建立前置詞為 riaControls 的參考。此外,資料來源圖示會出現在設計檢視的左下角。

  3. 若是 C# 方案,請將下列命名空間宣告加入至 XAML 檔案。

    xmlns:ds="clr-namespace:HRApp.Web"
    
  4. 若是 Visual Basic 方案,請將下列命名空間宣告加入至 XAML 檔案。

    xmlns:ds="clr-namespace:HRApp"
    
  5. DomainDataSource 控制項命名為 employeeDataSource,然後將現有的 XAML 取代成下列 XAML 來設定 LoadSizeAutoLoad 和查詢方法。

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
    </riaControls:DomainDataSource>
    
  6. 加入下列 XAML 來設定 DomainDataSourceDomainContext

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
        <riaControls:DomainDataSource.DomainContext>
            <ds:OrganizationContext/>
        </riaControls:DomainDataSource.DomainContext>
    </riaControls:DomainDataSource>
    
  7. 以下列 XAML 取代 DataGrid

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

  9. 在建構函式中,移除或取消程式碼的註解來具現化 OrganizationContext 執行個體、GetSalariedEmployeesQuery() 的呼叫以及程式碼,以設定 DataGrid 控制項的 ItemsSource 屬性。

    您不再需要明確地載入資料,因為 DomainDataSource 將會自動載入資料。

    'Dim _OrganizationContext As New OrganizationContext
    Public Sub New()
        InitializeComponent()
        'Me.dataGrid1.ItemsSource = _OrganizationContext.Employees
        '_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery())
    
    End Sub
    
    //OrganizationContext _OrganizationContext = new OrganizationContext();
    public EmployeeList()
    {
        InitializeComponent();
        //this.dataGrid1.ItemsSource = _OrganizationContext.Employees;
        //_OrganizationContext.Load(_OrganizationContext.GetSalariedEmployeesQuery());
    }
    
  10. 執行應用程式,然後按一下 [員工清單] 連結。

    應用程式便會如往常般運作。

若要將排序、篩選和分頁加入至資料來源

  1. 開啟 EmployeeList.xaml。

  2. DomainDataSource 中,加入下列 SortDescriptors,以指定在 DataGrid 中排序資料的方式。

    此 XAML 會示範如何以遞增順序排序 VacationHours 資料行。

    <riaControls:DomainDataSource Name="employeeDataSource" LoadSize="20" QueryName="GetSalariedEmployees" AutoLoad="True">
        <riaControls:DomainDataSource.DomainContext>
            <ds:OrganizationContext/>
        </riaControls:DomainDataSource.DomainContext>
        <riaControls:DomainDataSource.SortDescriptors>
            <riaControls:SortDescriptor PropertyPath="VacationHours" Direction="Ascending" />
        </riaControls:DomainDataSource.SortDescriptors>
    </riaControls:DomainDataSource>
    
  3. 執行應用程式,然後按一下 [員工清單] 連結。

    資料是依 VacationHours 排序,而且您可以按一下資料行標頭來變更排序方向。

  4. 開啟 EmployeeList.xaml。

  5. 若要提供一個值來讓使用者篩選要傳回的記錄,請在 DataGrid 前面加入下列 XAML。

    XAML 會加入一個 TextBox 控制項,讓使用者可以輸入值。

    <StackPanel Orientation="Horizontal" 
      HorizontalAlignment="Left">
        <TextBlock VerticalAlignment="Center" 
        Text="Min Vacation Hours Filter" />
        <TextBox x:Name="vacationHoursText" Width="75" 
      FontSize="11" Margin="4" Text="0"/>
    </StackPanel>
    
  6. DomainDataSource 中,加入繫結至您在上一個步驟中加入之 TextBox 控制項的篩選描述元。

    <riaControls:DomainDataSource.FilterDescriptors>
        <riaControls:FilterDescriptor 
             PropertyPath="VacationHours" 
             Operator="IsGreaterThanOrEqualTo"
             IgnoredValue=""
             Value="{Binding ElementName=vacationHoursText, Path=Text}"  >
        </riaControls:FilterDescriptor>
    </riaControls:DomainDataSource.FilterDescriptors>
    
  7. 執行應用程式,然後按一下 [員工清單] 連結。

  8. 在 [假期時數篩選下限] 文字方塊中,輸入 70。

    請注意,列出的員工需要 VacationHours 大於或等於 70。

    RIA_HRAppVacationFilter

  9. 開啟 EmployeeList.xaml。

  10. DataPager 控制項從 [工具箱] 拖曳至 DataGrid 的正下方。

  11. 將頁面大小設為 5,然後設定來源,如以下 XAML 所示。

    <sdk:DataPager PageSize="5" Source="{Binding Data, ElementName=employeeDataSource}" HorizontalAlignment="Left" />
    
  12. 執行應用程式,然後按一下 [員工清單] 連結。

    在每個頁面以及 DataGrid 下方的呼叫器控制項上,您只能看到已篩選資料的 5 個資料列。

    RIA_HRAppPagedData

建立主要/詳細資料檢視

在本節中,您要使用 Silverlight 工具組中的 DataForm 控制項來提供詳細的資料檢視。根據預設,Silverlight 商務應用程式的專案範本包含 Libs 資料夾中的 System.Windows.Controls.Data.DataForm.Toolkit.dll 二進位。

若要加入 DataForm

  1. 開啟 EmployeeList.xaml。

  2. 加入下列命名空間宣告。

    xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
    
  3. DataPager 控制項後面,加入下列 XAML 即可加入 DataForm 控制項。

    此 XAML 會設定 DataForm 屬性,並指定要顯示的資料行。

    <dataForm:DataForm x:Name="dataForm1" Header="Employee Information"
            AutoGenerateFields="False" HorizontalAlignment="Left"
            AutoEdit="False" AutoCommit="False" Width="400"
            CurrentItem="{Binding SelectedItem, ElementName=dataGrid1}" Margin="0,12,0,0">
        <dataForm:DataForm.EditTemplate>
            <DataTemplate>
                <StackPanel>
                    <dataForm:DataField Label="Employee ID">
                        <TextBox IsReadOnly="True" 
                  Text="{Binding EmployeeID, Mode=OneWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Login ID">
                        <TextBox Text="{Binding LoginID, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Hire Date">
                        <TextBox Text="{Binding HireDate, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Marital Status">
                        <TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Gender">
                        <TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Vacation Hours">
                        <TextBox Text="{Binding VacationHours, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Sick Leave Hours">
                        <TextBox Text="{Binding SickLeaveHours, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                    <dataForm:DataField Label="Active">
                        <CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }"  />
                    </dataForm:DataField>
                </StackPanel>
            </DataTemplate>
        </dataForm:DataForm.EditTemplate>
    </dataForm:DataForm>
    
  4. 執行應用程式,然後按一下 [員工清單] 連結。

    DataForm 會顯示在 DataGrid 中選取之項目的詳細資料。

    RIA_HRAppDataForm

更新資料庫

當您選取 [新的 DomainService 類別] 對話方塊中的 [啟用編輯] 核取方塊時,會在網域服務層中產生方法,來更新、插入,以及刪除實體。在本節中,您要將編輯按鈕加入到員工清單的使用者介面,讓使用者可以執行這些作業。

若要更新記錄

  1. 開啟 EmployeeList.xaml 檔。

  2. DataForm 控制項後面,加入下列 XAML 即可加入 [即交] 按鈕。

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,12,0,0">
        <Button x:Name="submitButton" Width="75" Height="23"  
            Content="Submit" Margin="4,0,0,0" Click="submitButton_Click"/>
    </StackPanel>
    
  3. DomainDataSource 控制項中,指定 SubmittedChanges 事件的事件處理常式。

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

  5. 針對按鈕的 Click 事件加入下列事件處理常式。

    系統會停用 submitButton,以防止使用者在處理作業時,再次送出變更。

    Private Sub submitButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        submitButton.IsEnabled = False
        employeeDataSource.SubmitChanges()
    End Sub
    
    private void submitButton_Click(object sender, RoutedEventArgs e)
    {
        submitButton.IsEnabled = false;
        employeeDataSource.SubmitChanges();
    }
    
  6. 針對檢查送出作業是否成功完成並啟用 submitButtonSubmittedChanges 事件,加入事件處理常式。

    Private Sub employeeDataSource_SubmittedChanges(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SubmittedChangesEventArgs)
        If (e.HasError) Then
            MessageBox.Show(String.Format("Changes were not saved: {0}", e.Error.Message))
            e.MarkErrorAsHandled()
        End If
        submitButton.IsEnabled = True
    End Sub
    
    private void employeeDataSource_SubmittedChanges(object sender, SubmittedChangesEventArgs e)
    {
        if (e.HasError)
        {
            MessageBox.Show(string.Format("Changes were not saved: {0}", e.Error.Message));
            e.MarkErrorAsHandled();
        }
        submitButton.IsEnabled = true;
    }
    
  7. 執行應用程式,然後按一下 [員工清單] 連結。

  8. 選取一個員工,然後按一下資料表單右上角的鉛筆圖示來啟用編輯。

    您現在可以修改任何可編輯的欄位。

  9. 對員工資料進行變更,然後按一下 [確定]。

  10. 按一下 [提交] 按鈕以儲存資料。

    只有在按一下 [提交] 按鈕時,才會將變更儲存到伺服器上的資料庫中。

若要將自訂方法加入至網域服務

  1. 開啟 HRApp.Web 伺服器專案中的 OrganizationService.cs/vb。檔案

  2. 加入下列名稱為 ApproveSabbatical 的自訂方法。

    Public Sub ApproveSabbatical(ByVal current As Employee)
        Me.ObjectContext.Employees.AttachAsModified(current)
        current.CurrentFlag = False
    End Sub
    
    public void ApproveSabbatical(Employee current)
    {
        // Start custom workflow here
        this.ObjectContext.Employees.AttachAsModified(current);
        current.CurrentFlag = false;
    }
    
  3. 建置方案。

  4. 開啟 EmployeeList.xaml。

  5. 在 [提交] 按鈕後面,加入下列 XAML 即可加入 [核准休假] 按鈕。

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

  7. 針對呼叫 ApproveSabbatical 網域作業的按鈕 Click 事件,加入下列事件處理常式。

    Private Sub approveSabbatical_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim luckyEmployee As Employee
        luckyEmployee = dataGrid1.SelectedItem
        luckyEmployee.ApproveSabbatical()
        employeeDataSource.SubmitChanges()
    End Sub
    
    private void approveSabbatical_Click(object sender, RoutedEventArgs e)
    {
        Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
        luckyEmployee.ApproveSabbatical();
        employeeDataSource.SubmitChanges();
    }
    
  8. 執行應用程式,然後按一下 [員工清單] 連結。

  9. 按一下 [核准休假] 按鈕,並注意所選員工的 [CurrentFlag] 核取方塊已清除。

驗證資料

DataForm 控制項可以顯示資料存取層 (DAL) 中的驗證錯誤。例如,如果您在 [VacationHours] 欄位中輸入一個非整數值,就會顯示驗證錯誤。下圖顯示驗證行為的範例。

RIA_HRAppValidation

當您選取 [新的 DomainService 類別] 對話方塊中的 [為中繼資料產生關聯的類別] 核取方塊時,包含中繼資料的檔案隨即建立。在本逐步解說中,中繼資料檔案名稱為 OrganizationService.metadata.cs/vb。在本節中,您要將驗證屬性加入至此檔案中。在用戶端和伺服器專案中,將會強制執行驗證規則。

您也要建立一個使用者介面,以便將新的員工記錄加入至資料庫中。您在先前幾節中所加入的驗證規則將會自動在新的使用者介面中套用。

若要加入基本驗證

  1. 開啟 HRApp.web 專案中的 OrganizationService.metadata.cs/vb。

  2. 將下列屬性 (Attribute) 加入至 GenderVacationHours 屬性 (Property) 中。

    <Required()> _
    Public Property Gender As String
    
    <Range(0, 70)> _
    Public Property VacationHours As Short
    
    [Required]
    public string Gender { get; set; }
    
    [Range(0, 70)]
    public short VacationHours { get; set; }
    
  3. 建置方案。

  4. 執行應用程式,然後按一下 [員工清單] 連結。

  5. 選取一個員工,然後按一下資料表單右上角的鉛筆圖示來啟用編輯。

  6. 在 [假期時數] 欄位中,輸入一個有效範圍 (0-70) 之外的值,然後將焦點移到另一個控制項。

    您會看到假期時數的驗證錯誤。

    RIA_HRAppRangeValidation

  7. 刪除 [性別] 欄位中的值,並將焦點移到另一個控制項。

    您會看到性別的驗證錯誤。

若要加入自訂驗證

  1. 以滑鼠右鍵按一下 [方案總管] 中的 [HRApp.Web 專案],按一下 [加入],然後按一下 [新增項目]。

    [加入新項目] 對話方塊隨即顯示。

  2. 選取 [程式碼] 類別中的 [程式碼檔案] 範本。

  3. 將新項目命名為 OrganizationService.shared.csOrganizationService.shared.vb

    結尾為 .shared.cs.shared.vb 的檔案可同時在用戶端和伺服器專案中使用。共用的檔案可讓您在兩個專案中執行相同的驗證規則。在稍後的步驟中建置專案之後,請查詢用戶端上隱藏的 Generated_Code 資料夾,您將會看到 OrganizationService.shared.cs/vb 檔案。

  4. 按一下 [加入]。

  5. 若要建立可驗證指派給 Gender 屬性之值的自訂驗證類別,請將下列程式碼加入至共用的檔案。

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

  7. 將下列自訂驗證屬性 (Attribute) 加入至 Gender 屬性 (Property)。

    <Required()> _
    <CustomValidation(GetType(GenderValidator), "IsGenderValid")> _
    Public Property Gender As String
    
    [CustomValidation(typeof(HRApp.Web.GenderValidator), "IsGenderValid")]
    [Required]
    public string Gender { get; set; }
    
  8. 建置方案。

  9. 執行應用程式,然後按一下 [員工清單] 連結。

  10. 選取一個員工,然後按一下資料表單右上角的鉛筆圖示來啟用編輯。

  11. 在 [性別] 欄位中,輸入一個非 M 或 F 的值,然後將焦點移到另一個控制項。

    自訂驗證的結果隨即出現。

    RIA_HRAppCustomValidation

加入新記錄

在本節中,您要加入一個可讓使用者在 Employee 資料表中建立新記錄的表單。

若要加入新記錄

  1. 在 HRApp 專案中,加入一個新項目。

  2. 選取 [Silverlight] 類別中的 [Silverlight 子視窗] 範本。

  3. 將新項目命名為 EmployeeRegistrationWindow.xaml

    RIA_HRAppAddChildWindow

  4. 按一下 [加入]。

  5. 開啟 EmployeeRegistrationWindow.xaml.cs/vb。

  6. 如果您使用的是 C#,加入下列 using 陳述式。

    using HRApp.Web;
    
  7. 針對使用使用者值建立的新 Employee 實體,加入一個屬性。

    Public Property NewEmployee As Employee
    
    public Employee NewEmployee { get; set; }
    
  8. 開啟 EmployeeRegistrationWindow.xaml。

  9. 將下列命名空間宣告加入至 EmployeeRegistrationWindow.xaml,即可在此視窗中使用 DataForm 控制項。

    xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
    
  10. 將下列 DataForm 控制項加入至 [取消] 按鈕正前方的 EmployeeRegistrationWindow.xaml。

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

  12. 加入下列程式碼來建立新的 Employee 執行個體,並處理新執行個體的認可或插入的取消。

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

  14. DataPagerDataForm 之間,加入下列 XAML 來建立名稱為 addNewEmployee 的按鈕。

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

  16. 加入下列程式碼來處理按鈕的 Click 事件,並顯示 EmployeeRegistrationWindow。

    Private Sub addNewEmployee_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim addEmp As New EmployeeRegistrationWindow()
        AddHandler addEmp.Closed, AddressOf addEmp_Closed
        addEmp.Show()
    End Sub
    
    private void addNewEmployee_Click(object sender, RoutedEventArgs e)
    {
        EmployeeRegistrationWindow addEmp = new EmployeeRegistrationWindow();
        addEmp.Closed += new EventHandler(addEmp_Closed);
        addEmp.Show();
    }
    
  17. 加入下列方法來處理 EmployeeRegistrationWindow 的 closed 事件。

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

  19. 加入下列程式碼來修改 InsertEmployee 方法。

    Public Sub InsertEmployee(ByVal employee As Employee)
        employee.HireDate = DateTime.Now
        employee.ModifiedDate = DateTime.Now
        employee.VacationHours = 0
        employee.SickLeaveHours = 0
        employee.rowguid = Guid.NewGuid()
        employee.ContactID = 1001
        employee.BirthDate = New DateTime(1967, 3, 18)
    
        If ((employee.EntityState = EntityState.Detached) _
                    = False) Then
            Me.ObjectContext.ObjectStateManager.ChangeObjectState(employee, EntityState.Added)
        Else
            Me.ObjectContext.Employees.AddObject(employee)
        End If
    End Sub
    
    public void InsertEmployee(Employee employee)
    {
        employee.HireDate = DateTime.Now;
        employee.ModifiedDate = DateTime.Now;
        employee.VacationHours = 0;
        employee.SickLeaveHours = 0;
        employee.rowguid = Guid.NewGuid();
        employee.ContactID = 1001;
        employee.BirthDate = new DateTime(1967, 3, 18);
    
        if ((employee.EntityState != EntityState.Detached))
        {
            this.ObjectContext.ObjectStateManager.ChangeObjectState(employee, EntityState.Added);
        }
        else
        {
            this.ObjectContext.Employees.AddObject(employee);
        }
    }
    
  20. 執行應用程式,然後按一下 [員工清單] 連結。

  21. 按一下 [加入員工] 按鈕。

    EmployeeRegistrationWindow 隨即開啟。

    RIA_Employee_Registration

  22. 加入視窗中的資料,然後選取 [支薪] 核取方塊。

  23. 按一下 [確定]。

  24. 重新整理頁面,並確認新的員工出現在 DataGrid 中。

驗證使用者

在本節中,您要將 ApproveSabbatical 方法的存取權限制為僅驗證的使用者。

若要加入驗證

  1. 開啟 OrganizationService.cs/vb。

  2. RequiresAuthentication 屬性加入至 ApproveSabbatical 方法。

    當您將 RequiresAuthentication 屬性套用至網域作業時,請確認只有經過驗證的使用者可以呼叫作業。如果匿名使用者按一下 [核准休假] 按鈕,就不會執行作業。

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

  4. 加入下列 usingImports 陳述式。

    Imports System.ServiceModel.DomainServices.Client.ApplicationServices
    Imports HRApp.LoginUI
    
    using System.ServiceModel.DomainServices.Client.ApplicationServices;
    using HRApp.LoginUI;
    
  5. 修改 approveSabbatical_Click 方法並加入 LoggedIn 處理常式來檢查使用者是否經過驗證。

    Private Sub approveSabbatical_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        If WebContext.Current.User IsNot Nothing AndAlso WebContext.Current.User.IsAuthenticated Then
            Dim luckyEmployee As Employee = dataGrid1.SelectedItem
            luckyEmployee.ApproveSabbatical()
            employeeDataSource.SubmitChanges()
        Else
            AddHandler WebContext.Current.Authentication.LoggedIn, AddressOf Current_LoginCompleted
            Dim newWindow As New LoginRegistrationWindow
            newWindow.Show()
        End If
    End Sub
    
    Private Sub Current_LoginCompleted(ByVal sender As Object, ByVal e As AuthenticationEventArgs)
        Dim luckyEmployee As Employee = dataGrid1.SelectedItem
        luckyEmployee.ApproveSabbatical()
        employeeDataSource.SubmitChanges()
        RemoveHandler WebContext.Current.Authentication.LoggedIn, AddressOf Current_LoginCompleted
    End Sub
    
    private void approveSabbatical_Click(object sender, RoutedEventArgs e)
    {
        if (WebContext.Current.User.IsAuthenticated)
        {
            Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
            luckyEmployee.ApproveSabbatical();
            employeeDataSource.SubmitChanges();
        }
        else
        {
            WebContext.Current.Authentication.LoggedIn += Authentication_LoggedIn;
            new LoginRegistrationWindow().Show();
        }
    }
    
    private void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
    {
        Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
        luckyEmployee.ApproveSabbatical();
        employeeDataSource.SubmitChanges();
    
        WebContext.Current.Authentication.LoggedIn -= Authentication_LoggedIn;
    }
    
  6. 執行應用程式,然後按一下 [員工清單] 連結。

  7. 選取員工記錄,然後按一下 [核准休假] 按鈕。

    您會被重新導向至登入視窗。

  8. 按一下 [立即註冊] 連結。

  9. 請完成所有必要欄位以便建立新帳戶。

  10. 按一下 [確定]。

    您會使用該帳戶登入,而且您的名稱會出現在導覽連結下方的列中。

顯示相關的資料

您可以使用 RIA Services ,輕鬆地處理關聯資料表中的資料。在本節中,您要加入新的 Silverlight 頁面,並顯示 PurchaseOrderHeader 和 PurchaseOrderDetail 資料表中的資料。您也可以自訂資料修改作業,以便同時修改相關的資料。如需透過網域作業修改關聯資料表中資料的範例,請參閱複合階層

若要從關聯資料表顯示資料

  1. 以滑鼠右鍵按一下 HRApp 專案中的 Views 資料夾,並按一下 [加入],然後按一下 [新增項目]。

  2. 加入名稱為 PurchaseOrders.xaml 的新 Silverlight 頁面。

  3. 開啟 PurchaseOrders.xaml。

  4. <Grid> 標記之間加入下列 XAML。

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

  6. 在 EmployeeList 連結後面,加入下列 XAML 以包含指向 PurchaseOrders 頁面的連結。

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

  8. IncludeComposition 屬性 (Attribute) 加入至 PurchaseOrderHeaderMetadata 類別中的 PurchaseOrderDetails 屬性 (Property)。

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

  10. 變更 GetPurchaseOrderHeaders 方法,以便 PurchaseOrderDetails 中的相關記錄也與查詢一起擷取。

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

  12. 按一下 [資料] 功能表上的 [顯示資料來源],以開啟 [資料來源] 視窗。

  13. 將 [PurchaseOrderHeader] 節點拖曳至 PurchaseOrders.xaml 的設計介面。

    RIA_Order_Header

    DataGrid 會與 PurchaseOrderHeader 資料表中的資料行一起出現。

  14. 展開 [資料來源] 視窗中的 [PurchaseOrderHeader] 節點。

  15. 將 [PurchaseOrderHeader] 節點內部的 [PurchaseOrderDetails] 節點拖曳至 PurchaseOrderHeader 之 DataGrid 正下方的設計介面。

    RIA_Order_Details

    DataGrid 會與 PurchaseOrderDetails 資料表中的資料行一起出現。

  16. 在 XAML 檢視中,尋找 PurchaseOrderHeaderPurchaseOrderDetailsDataGrid 控制項。

  17. 從每個 DataGrid 移除 Width=”400” 屬性,讓它填入可用的寬度。

  18. 在 PurchaseOrderHeader DataGrid 前面,加入下列 TextBlock 控制項來標示資料。

    <TextBlock Text="Order Headers"></TextBlock>
    
  19. 在 PurchaseOrderDetails DataGrid 前面,加入下列 TextBlock 控制項來標示資料。

    <TextBlock Text="Order Details"></TextBlock>
    
  20. 若要限制擷取之記錄的數目,將下列篩選描述元加入至 DomainDataSource 控制項。

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

    以下顯示 PurchaseOrders.xaml 的完整 XAML。

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

  22. 選取 PurchaseOrderHeader DataGrid 中的不同記錄。

    請注意,相關的 PurchaseOrderDetail 記錄會自動顯示出來。

    RIA_Details_and_Header

後續步驟

本逐步解說已經提供您 RIA Services 中許多功能的導覽。若要了解特定區域的詳細資料,請參閱本文件中的其他逐步解說。

另請參閱

工作

逐步解說:顯示 Silverlight 商務應用程式中的資料
逐步解說:搭配 Silverlight 商務應用程式使用驗證服務