Export (0) Print
Expand All

How to: Create an Asynchronous Windows Presentation Framework Application (WCF Data Services)

With WCF Data Services, you can bind data obtained from a data service to UI element of a Windows Presentation Framework (WPF) application. For more information, see Binding Data to Controls (WCF Data Services).You can also execute operations against the data service in an asynchronous manner, which enables the application to continue to respond while waiting for a response to a data service request. Applications for Silverlight are required to access the data service asynchronously. For more information, see Asynchronous Operations (WCF Data Services).

This topic shows how to access a data service asynchronously and bind the results to elements of a WPF application. The examples in this topic use the Northwind sample data service and autogenerated client data service classes. This service and the client data classes are created when you complete the WCF Data Services quickstart.

The following XAML defines the window of the WPF application.

    <Window x:Class="CustomerOrdersAsync"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Height="423" Width="679" Loaded="Window_Loaded" >
    <Grid Name="LayoutRoot">
        <StackPanel Orientation="Vertical" Height="Auto" Width="Auto">
            <Label Content="Customer ID" Margin="20,0,0,0" />
            <ComboBox Name="customerIDComboBox" DisplayMemberPath="CustomerID" ItemsSource="{Binding}" 
                  IsSynchronizedWithCurrentItem="True" SelectedIndex="0" Height="23" Width="120" 
                  HorizontalAlignment="Left" Margin="20,0,0,0" VerticalAlignment="Center" />
            <ListView ItemsSource="{Binding Path=Orders}" Name="ordersDataGrid" Margin="34,46,34,50">
                <ListView.View>
                    <GridView AllowsColumnReorder="False" ColumnHeaderToolTip="Line Items">
                        <GridViewColumn DisplayMemberBinding="{Binding Path=OrderID, Mode=OneWay}" 
                        Header="Order ID" Width="50"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=OrderDate, Mode=TwoWay}" 
                        Header="Order Date" Width="50"/>
                        <GridViewColumn DisplayMemberBinding="{Binding Path=Freight, Mode=TwoWay}" 
                        Header="Freight Cost" Width="50"/>
                    </GridView>
                </ListView.View>
            </ListView>
            <Button Name="saveChangesButton" Content="Save Changes" Click="saveChangesButton_Click" 
                Width="80" Height="30" Margin="450,0,0,0"/>
        </StackPanel>
    </Grid>
</Window>

The following code-behind page for the XAML file executes an asynchronous query by using the data service and binds the results to elements in the WPF window.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NorthwindClient.Northwind;
using System.Data.Services.Client;
using System.Windows.Threading;

namespace NorthwindClient
{
    /// <summary> 
    /// Interaction logic for OrderItems.xaml 
    /// </summary> 
    public partial class CustomerOrdersAsync : Window
    {
        private NorthwindEntities context;
        private DataServiceCollection<Customer> customerBinding;
        private const string customerCountry = "Germany";

        // Change this URI to the service URI for your implementation. 
        private const string svcUri = "http://localhost:12345/Northwind.svc/";

        // Delegate that returns void for the query result callback. 
        private delegate void OperationResultCallback();

        public CustomerOrdersAsync()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Initialize the context.
            context = new NorthwindEntities(new Uri(svcUri));

            // Define a query that returns customers and orders for a specific country.
            DataServiceQuery<Customer> query = context.Customers.Expand("Orders")
                .AddQueryOption("filter", "Country eq '" + customerCountry + "'");

            try
            {
                // Begin asynchronously saving changes using the  
                // specified handler and query object state.
                query.BeginExecute(OnQueryCompleted, query);
            }
            catch (DataServiceClientException ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void OnQueryCompleted(IAsyncResult result)
        {
            // Get the original query object from the state cache.
            DataServiceQuery<Customer> query =
                   (DataServiceQuery<Customer>)result.AsyncState;


            // Use the Dispatcher to ensure that the query returns in the UI thread. 
            this.Dispatcher.BeginInvoke(new OperationResultCallback(delegate
            {
                try
                {
                    // Instantiate the binding collection using the  
                    // results of the query execution.
                    customerBinding = new DataServiceCollection<Customer>(
                        query.EndExecute(result));

                    // Bind the collection to the root element of the UI. 
                    this.LayoutRoot.DataContext = customerBinding;
                }
                catch (DataServiceRequestException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }),null);
        }
        private void saveChangesButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Start the asynchronous call to save changes.
                context.BeginSaveChanges(OnSaveChangesCompleted, null);
            }
            catch (DataServiceClientException ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private void OnSaveChangesCompleted(IAsyncResult result)
        {
            // Use the Dispatcher to ensure that the operation returns in the UI thread. 
            this.Dispatcher.BeginInvoke(new OperationResultCallback(delegate
            {
                try
                {
                    // Complete the save changes operation.
                    context.EndSaveChanges(result);
                }
                catch (DataServiceRequestException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }), null);
        }
    }
}
Show:
© 2014 Microsoft