在本演练中,您将创建一个包含数据绑定控件的 WPF 应用程序。这些控件将绑定到在 WCF 数据服务中封装的客户记录。您还将添加客户可用于查看和更新记录的按钮。
本演练阐释了以下任务:
- 创建一个利用 AdventureWorksLT 示例数据库中的数据生成的实体数据模型。 
- 创建一个向 WPF 应用程序公开实体数据模型中的数据的 WCF 数据服务。 
- 通过将项从**“数据源”**窗口拖到 WPF 设计器来创建一组数据绑定控件。 
- 创建用于向前/向后浏览客户记录的按钮。 
- 创建一个用于将控件中数据的更改保存到 WCF 数据服务和基础数据源中的按钮。 .gif) 说明 说明- 对于在以下说明中使用的某些 Visual Studio 用户界面元素,您的计算机可能会显示不同的名称或位置。这些元素取决于您所使用的 Visual Studio 版本和您所使用的设置。有关更多信息,请参见 Visual Studio 设置。 
系统必备
您需要以下组件来完成本演练:
- Visual Studio 
- 对附加了 AdventureWorksLT 示例数据库的 SQL Server 或 SQL Server Express 的正在运行的实例的访问权限。您可以从 CodePlex 网站下载 AdventureWorksLT 数据库。 
事先了解以下概念也很有用,但对于完成本演练并不是必需的:
- WCF 数据服务。有关更多信息,请参见 ADO.NET Data Services Framework Overview。 
- WCF 数据服务中的数据模型。 
- 实体数据模型和 ADO.NET Entity Framework。有关更多信息,请参见 Introducing the Entity Framework。 
- 使用 WPF 设计器。有关更多信息,请参见 WPF and Silverlight Designer 概述。 
- WPF 数据绑定。有关更多信息,请参见数据绑定概述。 
创建服务项目
从为 WCF 数据服务创建项目开始本演练:
创建服务项目
- 启动 Visual Studio。 
- 在**“文件”菜单上指向“新建”,再单击“项目”**。 
- 展开**“Visual C#”或“Visual Basic”,然后选择“Web”**。 
- 选择**“ASP.NET Web 应用程序”**项目模板。 
- 在**“名称”框中键入 AdventureWorksService,然后单击“确定”**。 - Visual Studio 将创建 AdventureWorksService 项目。 
- 在**“解决方案资源管理器”中右击“Default.aspx”,然后选择“删除”**。本演练中不需要此文件。 
为服务创建实体数据模型
若要通过使用 WCF 数据服务向应用程序公开数据,则必须为该服务定义一个数据模型。WCF 数据服务支持两种类型的数据模型:实体数据模型和自定义数据模型,这两种数据模型是通过使用实现 IQueryable<T> 接口的公共语言运行时 (CLR) 对象定义的。在本演练中,您将为该数据模型创建一个实体数据模型。
创建实体数据模型
- 在**“项目”菜单上,单击“添加新项”**。 
- 在“已安装的模板”列表中,单击**“数据”,然后选择“ADO.NET 实体数据模型”**项目项。 
- 将名称更改为 AdventureWorksModel.edmx,然后单击**“添加”**。 - **“实体数据模型向导”**将打开。 
- 在**“选择模型内容”页上,单击“从数据库生成”,然后单击“下一步”**。 
- 在**“选择您的数据连接”**页上,选择下列选项之一: - 如果下拉列表中包含到 AdventureWorksLT 示例数据库的数据连接,请选择该连接。 - - 或 - 
- 单击**“新建连接”**并创建到 AdventureWorksLT 数据库的连接。 
 
- 在**“选择您的数据连接”页上,确保选中了“将 App.Config 中的实体连接设置另存为”选项,然后单击“下一步”**。 
- 在**“选择数据库对象”页上,展开“表”,然后选择“SalesOrderHeader”**表。 
- 单击**“完成”**。 
创建服务
创建 WCF 数据服务,以向 WPF 应用程序公开实体数据模型中的数据。
创建服务
- 在**“项目”菜单上选择“添加新项”**。 
- 在“已安装的模板”列表中,单击**“Web”,然后选择“WCF 数据服务”**项目项。 
- 在**“名称”框中键入 AdventureWorksService.svc,然后单击“添加”**。 - Visual Studio 将 AdventureWorksService.svc 添加到项目中。 
配置服务
若要操作所创建的实体数据模型,您必须对服务进行配置。
配置服务
- 在 AdventureWorks.svc 代码文件中,用下面的代码替换 AdventureWorksService 类声明。 - Public Class AdventureWorksService Inherits DataService(Of AdventureWorksLTEntities) ' This method is called only once to initialize service-wide policies. Public Shared Sub InitializeService(ByVal config As IDataServiceConfiguration) config.SetEntitySetAccessRule("SalesOrderHeaders", EntitySetRights.All) config.UseVerboseErrors = True End Sub End Class- 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 实体的完全读/写访问权限。 
- 生成项目,并确认生成过程中未发生错误。 
创建 WPF 客户端应用程序
若要显示 WCF 数据服务中的数据,请使用基于该服务的数据源创建一个新的 WPF 应用程序。在本演练后面的部分中,您将向该应用程序中添加数据绑定控件。
创建 WPF 客户端应用程序
- 在**“解决方案资源管理器”中,右击解决方案节点,单击“添加”,然后选择“新建项目”**。 
- 在**“新建类型”对话框中,展开“Visual C#”或“Visual Basic”,然后选择“Windows”**。 
- 选择**“WPF 应用程序”**项目模板。 
- 在**“名称”框中键入 AdventureWorksSalesEditor,然后单击“确定”**。 - Visual Studio 将 AdventureWorksSalesEditor 项目添加到解决方案中。 
- 在**“数据”菜单上,单击“显示数据源”**。 - 将打开**“数据源”**窗口。 
- 在**“数据源”窗口中,单击“添加新数据源”**。 - **“数据源配置向导”**打开。 
- 在该向导的**“选择数据源类型”页上,选择“服务”,然后单击“下一步”**。 
- 在**“添加服务引用”对话框中,单击“发现”**。 - Visual Studio 将在当前解决方案中搜索可用服务,并将 AdventureWorksService.svc 添加到**“服务”**框中的可用服务列表中。 
- 在**“命名空间”**框中,键入 AdventureWorksService。 
- 在**“服务”框中,单击 AdventureWorksService.svc,再单击“确定”**。 - Visual Studio 将下载该服务信息,然后返回到**“数据源配置向导”**。 
- 在**“添加服务引用”页上,单击“完成”**。 - Visual Studio 将表示该服务返回的数据的节点添加到**“数据源”**窗口中。 
定义窗口的用户界面
通过在 WPF 设计器中修改 XAML,向窗口中添加若干按钮。在本演练后面的部分中,您将添加可让用户通过这些按钮来查看和更新销售记录的代码。
创建窗口布局
- 在**“解决方案资源管理器”**中,双击 MainWindow.xaml。 - 将在 WPF 设计器中打开相应的窗口。 
- 在设计器的 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>
- 生成项目。 
创建数据绑定控件
通过将 SalesOrderHeaders 节点从**“数据源”**窗口拖动到设计器中,创建显示客户记录的控件。
创建数据绑定控件
- 在**“数据源”窗口中,单击“SalesOrderHeaders”节点的下拉菜单,并选择“详细信息”**。 
- 展开**“SalesOrderHeaders”**节点。 
- 在本示例中,由于一些字段不会显示,因此单击以下节点旁边的下拉菜单并选择**“无”**: - CreditCardApprovalCode 
- ModifiedDate 
- OnlineOrderFlag 
- RevisionNumber 
- rowguid 
 - 此操作将阻止 Visual Studio 在下一步中为这些节点创建数据绑定控件。对于本演练,假定最终用户不需要查看此数据。 
- 从**“数据源”窗口中,将“SalesOrderHeaders”**节点拖动到包含按钮的行的下方的网格行。 - Visual Studio 将生成一些 XAML 和代码,它们将创建一组绑定到**“Product”**表中的数据的控件。有关生成的 XAML 和代码的更多信息,请参见在 Visual Studio 中将 WPF 控件绑定到数据。 
- 在设计器中,单击**“Customer ID”(客户 ID)**标签旁边的文本框。 
- 在**“属性”窗口中,选中“IsReadOnly”**属性旁边的复选框。 
- 设置以下每个文本框的**“IsReadOnly”**属性: - “Purchase Order Number”(采购订单号) 
- “Sales Order ID”(销售订单 ID) 
- “Sales Order Number”(销售订单号) 
 
从服务中加载数据
使用服务代理对象从服务中加载销售数据,然后将返回的数据分配给 WPF 窗口中 CollectionViewSource 的数据源。
从服务中加载数据
- 在设计器中,双击文本**“MainWindow”**来创建 Window_Loaded 事件处理程序。 
- 用下面的代码替换该事件处理程序。确保用您的开发计算机上的本地主机地址替换此代码中的 localhost 地址。 - Private DataServiceClient As AdventureWorksService.AdventureWorksLTEntities Private SalesQuery As System.Data.Services.Client.DataServiceQuery(Of AdventureWorksService.SalesOrderHeader) Private OrdersViewSource As CollectionViewSource Private Sub Window_Loaded(ByVal Sender As Object, ByVal e As RoutedEventArgs) Handles MyBase.Loaded ' TODO: Modify the port number in the following URI as required. DataServiceClient = New AdventureWorksService.AdventureWorksLTEntities( _ New Uri("https://localhost:32415/AdventureWorksService.svc")) SalesQuery = DataServiceClient.SalesOrderHeaders OrdersViewSource = CType(Me.FindResource("SalesOrderHeadersViewSource"), CollectionViewSource) OrdersViewSource.Source = SalesQuery.Execute() OrdersViewSource.View.MoveCurrentToFirst() End Sub- 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("https://localhost:45899/AdventureWorksService.svc")); salesQuery = dataServiceClient.SalesOrderHeaders; ordersViewSource = ((CollectionViewSource)(this.FindResource("salesOrderHeadersViewSource"))); ordersViewSource.Source = salesQuery.Execute(); ordersViewSource.View.MoveCurrentToFirst(); }
导航销售记录
添加可让客户通过**“<”和“>”**按钮来浏览销售记录的代码。
使用户能够导航销售记录
- 在设计器中,双击窗口图面上的**“<”**按钮。 - Visual Studio 将打开代码隐藏文件,并为 Click 事件创建新的 backButton_Click 事件处理程序。 
- 将下面的代码添加到生成的 backButton_Click 事件处理程序中: - If OrdersViewSource.View.CurrentPosition > 0 Then OrdersViewSource.View.MoveCurrentToPrevious() End If- if (ordersViewSource.View.CurrentPosition > 0) ordersViewSource.View.MoveCurrentToPrevious();
- 返回到设计器,并双击 > 按钮。 - Visual Studio 将打开代码隐藏文件,并为 Click 事件创建新的 nextButton_Click 事件处理程序。 
- 将下面的代码添加到生成的 nextButton_Click 事件处理程序中: - If OrdersViewSource.View.CurrentPosition < CType(OrdersViewSource.View, CollectionView).Count - 1 Then OrdersViewSource.View.MoveCurrentToNext() End If- if (ordersViewSource.View.CurrentPosition < ((CollectionView)ordersViewSource.View).Count - 1) { ordersViewSource.View.MoveCurrentToNext(); }
保存对销售记录所做的更改
添加可让用户通过**“Save changes”(保存更改)**按钮来查看和保存对销售记录所做的更改的代码。
添加保存对销售记录所做更改的功能
- 在设计器中双击**“Save changes”(保存更改)**按钮。 - Visual Studio 将打开代码隐藏文件,并为 Click 事件创建新的 saveButton_Click 事件处理程序。 
- 将下面的代码添加到 saveButton_Click 事件处理程序中。 - Dim CurrentOrder As AdventureWorksService.SalesOrderHeader = CType(OrdersViewSource.View.CurrentItem, AdventureWorksService.SalesOrderHeader) DataServiceClient.UpdateObject(CurrentOrder) DataServiceClient.SaveChanges()- AdventureWorksService.SalesOrderHeader currentOrder = (AdventureWorksService.SalesOrderHeader)ordersViewSource.View.CurrentItem; dataServiceClient.UpdateObject(currentOrder); dataServiceClient.SaveChanges();
测试应用程序
生成并运行应用程序,以确认您能够查看和更新客户记录。
测试应用程序
- 在**“生成”菜单上,单击“生成解决方案”**。验证解决方案已生成且未发生错误。 
- 按 Ctrl+F5。 - Visual Studio 将启动 AdventureWorksService 项目,但不对其进行调试。 
- 在**“解决方案资源管理器”中,右击“AdventureWorksSalesEditor”**项目。 
- 在上下文菜单上的**“调试”下,单击“启动新实例”**。 - 将运行应用程序。确认以下事项: - 文本框显示的是销售订单 ID 为**“71774”**的第一条销售记录中的数据的不同字段。 
- 可以单击**“>”或“<”**按钮来浏览其他销售记录。 
 
- 在某条销售记录中,在**“Comment”(注释)框中键入一些文本,再单击“Save changes”(保存更改)**。 
- 关闭应用程序,然后从 Visual Studio 再次启动应用程序。 
- 导航到所更改的销售记录,确认相关更改在您关闭并重新打开应用程序后得以保留。 
- 关闭应用程序。 
后续步骤
完成本演练后,您可以执行以下相关任务:
- 了解如何使用 Visual Studio 中的**“数据源”**窗口将 WPF 控件绑定到其他类型的数据源。有关更多信息,请参见演练:将 WPF 控件绑定到实体数据模型和演练:将 WPF 控件绑定到数据集。 
- 了解如何使用 Visual Studio 中的**“数据源”**窗口来显示 WPF 控件中的相关数据(即具有父子关系的数据)。有关更多信息,请参见演练:在 WPF 应用程序中显示相关数据。 
请参见
任务
如何:在 Visual Studio 中将 WPF 控件绑定到数据
概念
在 Visual Studio 中将 WPF 控件绑定到数据
WPF and Silverlight Designer 概述