Walkthrough: Binding WPF Controls to a WCF Data Service
In this walkthrough, you will create a WPF application that contains data-bound controls. The controls are bound to customer records that are encapsulated in a WCF Data Service. You will also add buttons that customers can use to view and update records.
This walkthrough illustrates the following tasks:
Creating an Entity Data Model that is generated from data in the AdventureWorksLT sample database.
Creating a WCF Data Service that exposes the data in the Entity Data Model to a WPF application.
Creating a set of data-bound controls by dragging items from the Data Sources window to the WPF designer.
Creating buttons that navigate forward and backward through customer records.
Creating a button that saves changes to data in the controls to the WCF Data Service and the underlying data source.
Note
Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more information, see Customizing Development Settings in Visual Studio.
Prerequisites
You need the following components to complete this walkthrough:
Visual Studio
Access to a running instance of SQL Server or SQL Server Express that has the AdventureWorksLT sample database attached to it. You can download the AdventureWorksLT database from the CodePlex Web site.
Prior knowledge of the following concepts is also helpful, but not required to complete the walkthrough:
WCF Data Services. For more information, see ADO.NET Data Services Framework Overview.
Data models in WCF Data Services.
Entity Data Models and the ADO.NET Entity Framework. For more information, see Introducing the Entity Framework.
Working with the WPF designer. For more information, see WPF and Silverlight Designer Overview.
WPF data binding. For more information, see Data Binding Overview.
Creating the Service Project
Start this walkthrough by creating a project for a WCF Data Service.
To create the service project
Start Visual Studio.
On the File menu, point to New, and then click Project.
Expand Visual C# or Visual Basic, and then select Web.
Select the ASP.NET Web Application project template.
In the Name box, type AdventureWorksService and click OK.
Visual Studio creates the AdventureWorksService project.
In Solution Explorer, right-click Default.aspx and select Delete. This file is not necessary in this walkthrough.
Creating an Entity Data Model for the Service
To expose data to an application by using a WCF Data Service, you must define a data model for the service. The WCF Data Service supports two types of data models: Entity Data Models and custom data models that are defined by using common language runtime (CLR) objects that implement the IQueryable interface. In this walkthrough, you create an Entity Data Model for the data model.
To create an Entity Data Model
On the Project menu, click Add New Item.
In the Installed Templates list, click Data, and then select the ADO.NET Entity Data Model project item.
Change the name to AdventureWorksModel.edmx, and click Add.
The Entity Data Model Wizard opens.
On the Choose Model Contents page, click Generate from database, and click Next.
On the Choose Your Data Connection page, select one of the following options:
If a data connection to the AdventureWorksLT sample database is available in the drop-down list, select it.
-or-
Click New Connection and create a connection to the AdventureWorksLT database.
On the Choose Your Data Connection page, make sure that the Save entity connection settings in App.Config as option is selected and then click Next.
On the Choose Your Database Objects page, expand Tables, and then select the SalesOrderHeader table.
Click Finish.
Creating the Service
Create a WCF Data Service to expose the data in the Entity Data Model to a WPF application.
To create the service
On the Project menu, select Add New Item.
In the Installed Templates list, click Web, and then select the WCF Data Service project item.
In the Name box, type AdventureWorksService.svc and click Add.
Visual Studio adds the AdventureWorksService.svc to the project.
Configuring the Service
You must configure the service to operate on the Entity Data Model that you created.
To configure the service
In the AdventureWorks.svc code file, replace the AdventureWorksService class declaration with the following code.
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); } }
This code updates the AdventureWorksService class so that it derives from a DataService that operates on the AdventureWorksLTEntities object context class in your Entity Data Model. It also updates the InitializeService method to allow clients of the service full read/write access to the SalesOrderHeader entity.
Build the project, and verify that it builds without errors.
Creating the WPF Client Application
To display the data from the WCF Data Service, create a new WPF application with a data source that is based on the service. Later in this walkthrough, you will add data-bound controls to the application.
To create the WPF client application
In Solution Explorer, right-click the solution node, click Add, and select New Project.
In the New Project dialog, expand Visual C# or Visual Basic, and then select Windows.
Select the WPF Application project template.
In the Name box, type AdventureWorksSalesEditor and click OK.
Visual Studio adds the AdventureWorksSalesEditor project to the solution.
On the Data menu, click Show Data Sources.
The Data Sources window opens.
In the Data Sources window, click Add New Data Source.
The Data Source Configuration Wizard opens.
In the Choose a Data Source Type page of the wizard, select Service and then click Next.
In the Add Service Reference dialog box, click Discover.
Visual Studio searches the current solution for available services, and adds AdventureWorksService.svc to the list of available services in the Services box.
In the Namespace box, type AdventureWorksService.
In the Services box, click AdventureWorksService.svc and then click OK.
Visual Studio downloads the service information and then returns to the Data Source Configuration Wizard.
In the Add Service Reference page, click Finish.
Visual Studio adds nodes that represent the data returned by the service to the Data Sources window.
Defining the User Interface of the Window
Add several buttons to the window by modifying the XAML in the WPF designer. Later in this walkthrough, you will add code that enables users to view and update sales records by using these buttons.
To create the window layout
In Solution Explorer, double-click MainWindow.xaml.
The window opens in the WPF designer.
In the XAML view of the designer, add the following code between the <Grid> tags:
<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>
Build the project.
Creating the Data-bound Controls
Create controls that display customer records by dragging the SalesOrderHeaders node from the Data Sources window to the designer.
To create the data-bound controls
In the Data Sources window, click the drop-down menu for the SalesOrderHeaders node and select Details.
Expand the SalesOrderHeaders node.
For this example some fields will not be displayed so click the drop-down menu next to the following nodes and select None:
CreditCardApprovalCode
ModifiedDate
OnlineOrderFlag
RevisionNumber
rowguid
This action prevents Visual Studio from creating data-bound controls for these nodes in the next step. For this walkthrough, it is assumed that the end user does not need to see this data.
From the Data Sources window, drag the SalesOrderHeaders node to the grid row under the row that contains the buttons.
Visual Studio generates XAML and code that creates a set of controls that are bound to data in the Product table. For more information about the generated XAML and code, see Binding WPF Controls to Data in Visual Studio.
In the designer, click the text box next to the Customer ID label.
In the Properties window, select the check box next to the IsReadOnly property.
Set the IsReadOnly property for each of the following text boxes:
Purchase Order Number
Sales Order ID
Sales Order Number
Load the Data from the Service
Use the service proxy object to load sales data from the service, and then assign the returned data to the data source for the CollectionViewSource in the WPF window.
To load the data from the service
In the designer, double-click the text that reads: MainWindow to create the Window_Loaded event handler.
Replace the event handler with the following code. Make sure that you replace the localhost address in this code with the local host address on your development computer.
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(); }
Navigating Sales Records
Add code that enables users to scroll through sales records by using the < and > buttons.
To enable users to navigate sales records
In the designer, double-click the < button on the window surface.
Visual Studio opens the code-behind file and creates a new backButton_Click event handler for the Click event.
Add the following code to the generated backButton_Click event handler:
If OrdersViewSource.View.CurrentPosition > 0 Then OrdersViewSource.View.MoveCurrentToPrevious() End If
if (ordersViewSource.View.CurrentPosition > 0) ordersViewSource.View.MoveCurrentToPrevious();
Return to the designer, and double-click the > button.
Visual Studio opens the code-behind file and creates a new nextButton_Click event handler for the Click event.
Add the following code to the generated nextButton_Click event handler:
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(); }
Saving Changes to Sales Records
Add code that enables users to both view and save changes to sales records by using the Save changes button.
To add the ability to save changes to sales records
In the designer, double-click the Save Changes button.
Visual Studio opens the code-behind file and creates a new saveButton_Click event handler for the Click event.
Add the following code to the saveButton_Click event handler.
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();
Testing the Application
Build and run the application to verify that you can view and update customer records.
To test the application
On Build menu, click Build Solution. Verify that the solution builds without errors.
Press CTRL+F5.
Visual Studio starts the AdventureWorksService project without debugging it.
In Solution Explorer, right-click the AdventureWorksSalesEditor project.
On the context menu, under Debug, click Start new instance.
The application runs. Verify the following:
The text boxes display different fields of data from the first sales record, which has the sales order ID 71774.
You can click the > or < buttons to navigate through other sales records.
In one of the sales records, type some text in the Comment box, and then click Save changes.
Close the application, and then start the application again from Visual Studio.
Navigate to the sales record that you changed, and verify that the change persists after you close and reopen the application.
Close the application.
Next Steps
After completing this walkthrough, you can perform the following related tasks:
Learn how to use the Data Sources window in Visual Studio to bind WPF controls to other types of data sources. For more information, see Walkthrough: Binding WPF Controls to a Dataset.
Learn how to use the Data Sources window in Visual Studio to display related data (that is, data in a parent-child relationship) in WPF controls. For more information, see Walkthrough: Displaying Related Data in a WPF Application.
See Also
Tasks
How to: Bind WPF Controls to Data in Visual Studio
Walkthrough: Binding WPF Controls to a Dataset
Concepts
Binding WPF Controls to Data in Visual Studio
WPF and Silverlight Designer Overview