将 WPF 控件绑定到 WCF 数据服务

在本演练中,你将创建一个包含数据绑定控件的 WPF 应用程序。 这些控件将绑定到在 WCF 数据服务中封装的客户记录。 你还将添加客户可用于查看和更新记录的按钮。

本演练演示以下任务:

  • 创建一个利用 AdventureWorksLT 示例数据库中的数据生成的实体数据模型。

  • 创建一个向 WPF 应用程序公开实体数据模型中的数据的 WCF 数据服务。

  • 通过将项从“数据源”窗口拖到 WPF 设计器来创建一组数据绑定控件

  • 创建用于向前/向后导航客户记录的按钮。

  • 创建一个用于将控件中数据的更改保存到 WCF 数据服务和基础数据源中的按钮。

注意

本文中的某些 Visual Studio 用户界面元素在计算机上出现的名称或位置可能会不同。 你可能正在使用其他版本的 Visual Studio 或其他环境设置。 有关详细信息,请参阅个性化设置 IDE

先决条件

您需要满足以下条件才能完成本演练:

  • Visual Studio

  • 对附加了 AdventureWorksLT 示例数据库的 SQL Server 或 SQL Server Express 的正在运行的实例的访问权限。 若要下载数据库,请参阅 AdventureWorks 示例数据库

事先了解以下概念也很有用,但对于完成本演练并不是必需的:

创建服务项目

  1. 通过创建 C# 或 Visual Basic ASP.NET Web 应用程序项目开始此演练。 将项目命名为 AdventureWorksService。

  2. 在“解决方案资源管理器”中,右键单击“Default.aspx”,然后选择“删除”。 本演练不需要此文件。

为服务创建实体数据模型

若要通过使用 WCF 数据服务向应用程序公开数据,则必须为该服务定义一个数据模型。 WCF 数据服务支持两种类型的数据模型:实体数据模型和自定义数据模型,这两种数据模型是通过使用实现 IQueryable<T> 接口的公共语言运行时 (CLR) 对象定义的。 在本演练中,你将为该数据模型创建一个实体数据模型。

  1. “项目” 菜单上,单击 “添加新项”

  2. 在“已安装的模板”列表中,单击“数据”,然后选择“ADO.NET 实体数据模型”项目项

  3. 将名称更改为 AdventureWorksModel.edmx,然后单击“添加”。

    “实体数据模型”向导随即打开

  4. 在“选择模型内容”页面上,单击“从数据库生成”,然后单击“下一步”

  5. 在“选择你的数据连接”页面上,选择以下选项之一

    • 如果下拉列表中包含到 AdventureWorksLT 示例数据库的数据连接,请选择该连接。

    • 单击“新建连接”,然后创建到 AdventureWorksLT 数据库的连接

  6. 选择数据连接页面上,确保选中了将 App.Config 中的实体连接设置另存为选项,然后选择下一步

  7. 在“选择数据库对象”页面上,展开“表”,然后选择“SalesOrderHeader”表

  8. 单击“完成” 。

创建服务

创建 WCF 数据服务,以向 WPF 应用程序公开实体数据模型中的数据:

  1. 在“项目”菜单上,选择“添加新项”。

  2. 在“已安装的模板”列表中,单击“Web”,然后选择“WCF Data Service”项目项

  3. 在“名称”框中,键入 AdventureWorksService.svc,然后单击“添加”。

    Visual Studio 将向项目添加 AdventureWorksService.svc

配置服务

必须配置该服务,才能操作所创建的实体数据模型:

  1. AdventureWorks.svc 代码文件中,将 AdventureWorksService 类声明替换为以下代码。

    public class AdventureWorksService : DataService<AdventureWorksLTEntities>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(IDataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("SalesOrderHeaders", EntitySetRights.All);
        }
    }
    

    此代码将更新 AdventureWorksService 类,以使其派生自在实体数据模型中的 AdventureWorksLTEntities 对象上下文类上操作的 DataService<T>。 此代码还将更新 InitializeService 方法,以使服务的客户端具有对 SalesOrderHeader 实体的完全读/写访问权限。

  2. 生成项目,并确认生成过程中未发生错误。

创建 WPF 客户端应用程序

若要显示 WCF 数据服务中的数据,请使用基于该服务的数据源创建一个新的 WPF 应用程序。 在本演练后面的部分中,你将向该应用程序中添加数据绑定控件。

  1. 在“解决方案资源管理器”中,右键单击解决方案节点、单击“添加”,然后选择“新建项目”

  2. 在“新建项目”对话框中,展开“Visual C#”或“Visual Basic”,然后选择“Windows”

  3. 选择“WPF 应用程序”项目模板

  4. 在“名称”框中,键入 AdventureWorksSalesEditor,然后单击“确定”。

    Visual Studio 将 AdventureWorksSalesEditor 项目添加到解决方案中。

  5. “数据” 菜单上,单击 “显示数据源”

    “数据源”窗口随即打开

  6. “数据源” 窗口中,单击 “添加新数据源”

    “数据源配置”向导随即打开。

  7. 在该向导的选择数据源类型页面上,选择服务,然后选择下一步

  8. “添加服务引用”对话框中,单击“发现”

    Visual Studio 将在当前解决方案中搜索可用服务,并将 AdventureWorksService.svc 添加到“服务”框中的可用服务列表中。

  9. 在“命名空间”框中,键入“AdventureWorksService”

  10. 服务框中,单击 AdventureWorksService.svc,然后选择确定

    Visual Studio 下载该服务信息,然后返回到“数据源配置”向导

  11. 在“添加服务引用”页面上,单击“完成”

    Visual Studio 会将表示该服务返回的数据的节点添加到“数据源”窗口中

定义用户界面

通过在 WPF 设计器中修改 XAML,将多个按钮添加到该窗口中。 在本演练后面的部分中,你将添加可让用户通过使用这些按钮来查看和更新销售记录的代码。

  1. 在“解决方案资源管理器”中,双击“MainWindow.xaml” 。

    将在 WPF 设计器中打开相应的窗口。

  2. 在设计器的 XAML 视图中,在 <Grid> 标记之间添加以下代码:

    <Grid.RowDefinitions>
        <RowDefinition Height="75" />
        <RowDefinition Height="525" />
    </Grid.RowDefinitions>
    <Button HorizontalAlignment="Left" Margin="22,20,0,24" Name="backButton" Width="75"><</Button>
    <Button HorizontalAlignment="Left" Margin="116,20,0,24" Name="nextButton" Width="75">></Button>
    <Button HorizontalAlignment="Right" Margin="0,21,46,24" Name="saveButton" Width="110">Save changes</Button>
    
  3. 生成项目。

创建数据绑定控件

通过将 SalesOrderHeaders 节点从“数据源”窗口拖到设计器中,创建显示客户记录的控件。

  1. 在“数据源”窗口中,单击“SalesOrderHeaders”节点的下拉列表菜单,然后选择“详细信息”

  2. 展开“SalesOrderHeaders”节点

  3. 在本示例中,某些字段不会显示,因此只需单击下列节点旁边的下拉列表菜单,然后选择“无”

    • CreditCardApprovalCode

    • ModifiedDate

    • OnlineOrderFlag

    • RevisionNumber

    • rowguid

    此操作将阻止 Visual Studio 在下一步中为这些节点创建数据绑定控件。 对于本演练,假定最终用户不需要查看此数据。

  4. 从“数据源”窗口中,将“SalesOrderHeaders”节点拖到包含按钮的行的下方的网格行

    Visual Studio 将生成 XAML 和代码,它们将创建一组绑定到“Product”表中的数据的控件。 有关生成的 XAML 和代码的详细信息,请参阅在 Visual Studio 中将 WPF 控件绑定到数据

  5. 在设计器中,单击“客户 ID”标签旁边的文本框

  6. 在“属性”窗口,选中“IsReadOnly”属性旁边的复选框

  7. 设置以下每个文本框的“IsReadOnly”属性

    • 采购订单号

    • 销售订单 ID

    • Sales Order Number

从服务中加载数据

使用服务代理对象从服务加载销售数据。 然后,将返回的数据分配给 WPF 窗口中 CollectionViewSource 的数据源。

  1. 在设计器创建Window_Loaded事件处理程序中,双击读取的文本:MainWindow

  2. 将该事件处理程序替换为以下代码。 确保将此代码中的 localhost 地址替换为你的开发计算机上的本地主机地址。

    private AdventureWorksService.AdventureWorksLTEntities dataServiceClient;
    private System.Data.Services.Client.DataServiceQuery<AdventureWorksService.SalesOrderHeader> salesQuery;
    private CollectionViewSource ordersViewSource;
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // TODO: Modify the port number in the following URI as required.
        dataServiceClient = new AdventureWorksService.AdventureWorksLTEntities(
            new Uri("http://localhost:45899/AdventureWorksService.svc"));
        salesQuery = dataServiceClient.SalesOrderHeaders;
    
        ordersViewSource = ((CollectionViewSource)(this.FindResource("salesOrderHeadersViewSource")));
        ordersViewSource.Source = salesQuery.Execute();
        ordersViewSource.View.MoveCurrentToFirst();
    }
    

添加可让用户通过“”和“”按钮来滚动销售记录的代码<>

  1. 在设计器中,双击窗口窗面上的“<”按钮。

    Visual Studio 打开代码隐藏文件,并为 Click 事件创建新的 backButton_Click 事件处理程序。

  2. 将以下代码添加到生成的 backButton_Click 事件处理程序中:

    if (ordersViewSource.View.CurrentPosition > 0)
        ordersViewSource.View.MoveCurrentToPrevious();
    
  3. 返回到设计器,然后双击“>”按钮。

    Visual Studio 打开代码隐藏文件,并为 Click 事件创建新的 nextButton_Click 事件处理程序。

  4. 将以下代码添加到生成的 nextButton_Click 事件处理程序中:

    if (ordersViewSource.View.CurrentPosition < ((CollectionView)ordersViewSource.View).Count - 1)
    {
        ordersViewSource.View.MoveCurrentToNext();
    }
    

保存对销售记录所做的更改

添加可让用户通过使用“保存更改”按钮来查看和保存对销售记录所做的更改的代码

  1. 在设计器中,双击“保存更改”按钮。

    Visual Studio 打开代码隐藏文件,并为 Click 事件创建新的 saveButton_Click 事件处理程序。

  2. 将以下代码添加到 saveButton_Click 事件处理程序中。

    AdventureWorksService.SalesOrderHeader currentOrder = (AdventureWorksService.SalesOrderHeader)ordersViewSource.View.CurrentItem;
    dataServiceClient.UpdateObject(currentOrder);
    dataServiceClient.SaveChanges();
    

测试应用程序

生成并运行应用程序,以验证你是否可以查看和更新客户记录:

  1. 在“生成”菜单上,单击“生成解决方案”。 验证解决方案已生成且未发生错误。

  2. 按 Ctrl+F5 。

    Visual Studio 启动“AdventureWorksService”项目,但不对其进行调试

  3. 在“解决方案资源管理器”中,右键单击“AdventureWorksSalesEditor”项目

  4. 在右键菜单(上下文菜单)上的“调试”下,单击“启动新实例” 。

    将运行应用程序。 检查下列各项:

    • 文本框显示销售订单 ID 为“71774”的第一条销售记录中的数据的不同字段

    • 可以单击“>”或“<”按钮来浏览其他销售记录。

  5. 在某条销售记录中,在注释框中键入一些文本,然后选择保存更改

  6. 关闭应用程序,然后从 Visual Studio 中再次启动该应用程序。

  7. 导航到所更改的销售记录,然后验证相关更改是否在你关闭并重新打开应用程序后得以保留。

  8. 关闭该应用程序。

后续步骤

完成本演练后,你可以执行以下相关任务: