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 Visual Studio Settings.

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:

Creating the Service Project

Start this walkthrough by creating a project for a WCF Data Service.

To create the service project

  1. Start Visual Studio.

  2. On the File menu, point to New, and then click Project.

  3. Expand Visual C# or Visual Basic, and then select Web.

  4. Select the ASP.NET Web Application project template.

  5. In the Name box, type AdventureWorksService and click OK.

    Visual Studio creates the AdventureWorksService project.

  6. 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<T> interface. In this walkthrough, you create an Entity Data Model for the data model.

To create an Entity Data Model

  1. On the Project menu, click Add New Item.

  2. In the Installed Templates list, click Data, and then select the ADO.NET Entity Data Model project item.

  3. Change the name to AdventureWorksModel.edmx, and click Add.

    The Entity Data Model Wizard opens.

  4. On the Choose Model Contents page, click Generate from database, and click Next.

  5. 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.

  6. 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.

  7. On the Choose Your Database Objects page, expand Tables, and then select the SalesOrderHeader table.

  8. 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

  1. On the Project menu, select Add New Item.

  2. In the Installed Templates list, click Web, and then select the WCF Data Service project item.

  3. 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

  1. 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<T> 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.

  2. 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

  1. In Solution Explorer, right-click the solution node, click Add, and select New Project.

  2. In the New Project dialog, expand Visual C# or Visual Basic, and then select Windows.

  3. Select the WPF Application project template.

  4. In the Name box, type AdventureWorksSalesEditor and click OK.

    Visual Studio adds the AdventureWorksSalesEditor project to the solution.

  5. On the Data menu, click Show Data Sources.

    The Data Sources window opens.

  6. In the Data Sources window, click Add New Data Source.

    The Data Source Configuration Wizard opens.

  7. In the Choose a Data Source Type page of the wizard, select Service and then click Next.

  8. 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.

  9. In the Namespace box, type AdventureWorksService.

  10. 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.

  11. 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

  1. In Solution Explorer, double-click MainWindow.xaml.

    The window opens in the WPF designer.

  2. 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">&lt;</Button>
    <Button HorizontalAlignment="Left" Margin="116,20,0,24" Name="nextButton" Width="75">&gt;</Button>
    <Button HorizontalAlignment="Right" Margin="0,21,46,24" Name="saveButton" Width="110">Save changes</Button>
    
  3. 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

  1. In the Data Sources window, click the drop-down menu for the SalesOrderHeaders node and select Details.

  2. Expand the SalesOrderHeaders node.

  3. 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.

  4. 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.

  5. In the designer, click the text box next to the Customer ID label.

  6. In the Properties window, select the check box next to the IsReadOnly property.

  7. 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

  1. In the designer, double-click the text that reads: MainWindow to create the Window_Loaded event handler.

  2. 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();
    }
    

Add code that enables users to scroll through sales records by using the < and > buttons.

To enable users to navigate sales records

  1. 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.

  2. 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();
    
  3. 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.

  4. 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

  1. 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.

  2. 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

  1. On Build menu, click Build Solution. Verify that the solution builds without errors.

  2. Press CTRL+F5.

    Visual Studio starts the AdventureWorksService project without debugging it.

  3. In Solution Explorer, right-click the AdventureWorksSalesEditor project.

  4. 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.

  5. In one of the sales records, type some text in the Comment box, and then click Save changes.

  6. Close the application, and then start the application again from Visual Studio.

  7. Navigate to the sales record that you changed, and verify that the change persists after you close and reopen the application.

  8. Close the application.

Next Steps

After completing this walkthrough, you can perform the following related tasks:

See Also

Tasks

How to: Bind WPF Controls to Data in Visual Studio

Walkthrough: Binding WPF Controls to an Entity Data Model

Walkthrough: Binding WPF Controls to a Dataset

Concepts

Binding WPF Controls to Data in Visual Studio

WPF and Silverlight Designer Overview

Data Binding Overview

Other Resources

ADO.NET Data Services Framework Overview

Introducing the Entity Framework