Bind WPF controls to a WCF data service
Applies to: Visual Studio Visual Studio for Mac
Note
This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
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 this article. You may be using a different edition of Visual Studio or different environment settings. For more information, see Personalize the IDE.
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. To download the database, see AdventureWorks sample databases
Prior knowledge of the following concepts is also helpful, but not required to complete the walkthrough:
Data models in WCF Data Services.
Entity Data Models and the ADO.NET Entity Framework. For more information, see Entity Framework overview.
WPF data binding. For more information, see Data Binding overview.
Create the service project
Start this walkthrough by creating a C# or Visual Basic ASP.NET Web Application project. Name the project AdventureWorksService.
In Solution Explorer, right-click Default.aspx and select Delete. This file is not necessary for the walkthrough.
Create 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<T> interface. In this walkthrough, you create an Entity Data Model for the 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.
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.
Create the service
Create a WCF Data Service to expose the data in the Entity Data Model to a WPF application:
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.
Configure the service
You must configure the service to operate on the Entity Data Model that you created:
In the
AdventureWorks.svc
code file, replace the AdventureWorksService class declaration with the following code.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); } }
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
This code updates the AdventureWorksService class, so that it derives from a DataService<T> that operates on the
AdventureWorksLTEntities
object context class in your Entity Data Model. It also updates theInitializeService
method to allow clients of the service full read/write access to theSalesOrderHeader
entity.Build the project, and verify that it builds without errors.
Create 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.
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.
Define the user interface
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.
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.
Create the data-bound controls
Create controls that display customer records by dragging the SalesOrderHeaders
node from the Data Sources window to the designer.
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, assume 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 Bind 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. Then assign the returned data to the data source for the CollectionViewSource in the WPF window.
In the designer, to create the
Window_Loaded
event handler, double-click the text that reads: MainWindow.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 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(); }
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("http://localhost:32415/AdventureWorksService.svc")) SalesQuery = DataServiceClient.SalesOrderHeaders OrdersViewSource = CType(Me.FindResource("SalesOrderHeadersViewSource"), CollectionViewSource) OrdersViewSource.Source = SalesQuery.Execute() OrdersViewSource.View.MoveCurrentToFirst() End Sub
Navigate sales records
Add code that enables users to scroll through sales records by using the < and > buttons.
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) ordersViewSource.View.MoveCurrentToPrevious();
If OrdersViewSource.View.CurrentPosition > 0 Then OrdersViewSource.View.MoveCurrentToPrevious() End If
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 < ((CollectionView)ordersViewSource.View).Count - 1) { ordersViewSource.View.MoveCurrentToNext(); }
If OrdersViewSource.View.CurrentPosition < CType(OrdersViewSource.View, CollectionView).Count - 1 Then OrdersViewSource.View.MoveCurrentToNext() End If
Save changes to sales records
Add code that enables users to both view and save changes to sales records by using the Save changes button:
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.AdventureWorksService.SalesOrderHeader currentOrder = (AdventureWorksService.SalesOrderHeader)ordersViewSource.View.CurrentItem; dataServiceClient.UpdateObject(currentOrder); dataServiceClient.SaveChanges();
Dim CurrentOrder As AdventureWorksService.SalesOrderHeader = CType(OrdersViewSource.View.CurrentItem, AdventureWorksService.SalesOrderHeader) DataServiceClient.UpdateObject(CurrentOrder) DataServiceClient.SaveChanges()
Test the application
Build and run the application to verify that you can view and update customer records:
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 right-click menu (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 Bind 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.