Gewusst wie: Binden von Daten an Windows Presentation Foundation-Elemente (WCF Data Services)

Mit WCF Data Services können Sie WPF (Windows Presentation Foundation)-Elemente wie ein ListBox -Steuerelement oder ein ComboBox-Steuerelement an eine Instanz von DataServiceCollection<T> binden, die die von den Steuerelementen ausgelösten Ereignisse behandelt, damit der DataServiceContext-Kontext mit an Daten in den Steuerelementen vorgenommenen Änderungen synchron bleibt. Weitere Informationen finden Sie unter Binden von Daten an Steuerelemente (WCF Data Services).

Im Beispiel in diesem Thema werden der Northwind-Beispieldatendienst und automatisch generierte Clientdatendienstklassen verwendet. Dieser Dienst und die Clientdatenklassen werden erstellt, wenn Sie den WCF Data Services-Schnellstart ausführen.

Beispiel

Das folgende Beispiel stammt aus der Code-Behind-Seite für eine XAML (Extensible Application Markup Language)-Seite, die das Fenster SalesOrders in WPF definiert. Wenn das Fenster geladen wird, wird eine DataServiceCollection<T> basierend auf dem Ergebnis einer Abfrage erstellt, die Kunden nach Land gefiltert zurückgibt. Alle Seiten dieses ausgelagerten Ergebnisses werden zusammen mit den verknüpften Bestellungen geladen und an die DataContext-Eigenschaft des StackPanel gebunden, der das Stammlayoutsteuerelement für das WPF-Fenster ist. Weitere Informationen finden Sie unter Laden von verzögertem Inhalt (WCF Data Services).

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

Partial Public Class CustomerOrdersWpf3
    Inherits Window

    Private context As NorthwindEntities
    Private trackedCustomers As DataServiceCollection(Of Customer)
    Private Const customerCountry As String = "Germany"
    Private Const svcUri As String = "https://localhost:12345/Northwind.svc/"

    Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Try
            ' Initialize the context for the data service.
            context = New NorthwindEntities(New Uri(svcUri))

            ' Create a LINQ query that returns customers with related orders.
            Dim customerQuery = From cust In context.Customers _
                                    Where cust.Country = customerCountry _
                                    Select cust

                ' Create a new collection for binding based on the LINQ query.
            trackedCustomers = New DataServiceCollection(Of Customer)(customerQuery)

                ' Load all pages of the response at once.
            While trackedCustomers.Continuation IsNot Nothing
                trackedCustomers.Load( _
                        context.Execute(Of Customer)(trackedCustomers.Continuation.NextLinkUri))
            End While

            ' Bind the root StackPanel element to the collection
            ' related object binding paths are defined in the XAML.
            Me.LayoutRoot.DataContext = trackedCustomers
        Catch ex As DataServiceQueryException
            MessageBox.Show("The query could not be completed:\n" + ex.ToString())
        Catch ex As InvalidOperationException
            MessageBox.Show("The following error occurred:\n" + ex.ToString())
        End Try
    End Sub
    Private Sub customerIDComboBox_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
        Dim selectedCustomer As Customer = _
            CType(Me.customerIDComboBox.SelectedItem, Customer)
        Try
            If selectedCustomer.Orders.Count = 0 Then
                ' Load the first page of related orders for the selected customer.
                context.LoadProperty(selectedCustomer, "Orders")
            End If

            ' Load all remaining pages.
            While selectedCustomer.Orders.Continuation IsNot Nothing
                selectedCustomer.Orders.Load( _
                        context.Execute(Of Order)(selectedCustomer.Orders.Continuation.NextLinkUri))
            End While
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        End Try
    End Sub
    Private Sub saveChangesButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Try
            ' Save changes to the data service.
            context.SaveChanges()
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        End Try
    End Sub
End Class
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 System.Data.Services.Client;
using NorthwindClient.Northwind;

namespace NorthwindClient
{
    public partial class CustomerOrdersWpf3 : Window
    {
        private NorthwindEntities context;
        private DataServiceCollection<Customer> trackedCustomers;
        private const string customerCountry = "Germany";
        private const string svcUri = "https://localhost:12345/Northwind.svc/";

        public CustomerOrdersWpf3()
        {
            InitializeComponent();
        }

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

                // Create a LINQ query that returns customers with related orders.
                var customerQuery = from cust in context.Customers
                                    where cust.Country == customerCountry
                                    select cust;

                // Create a new collection for binding based on the LINQ query.
                trackedCustomers = new DataServiceCollection<Customer>(customerQuery);

                // Load all pages of the response at once.
                while (trackedCustomers.Continuation != null)
                {
                    trackedCustomers.Load(
                        context.Execute<Customer>(trackedCustomers.Continuation.NextLinkUri));
                }

                // Bind the root StackPanel element to the collection;
                // related object binding paths are defined in the XAML.
                LayoutRoot.DataContext = trackedCustomers;
            }
            catch (DataServiceQueryException ex)
            {
                MessageBox.Show("The query could not be completed:\n" + ex.ToString());
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show("The following error occurred:\n" + ex.ToString());
            }
        }

        private void customerIDComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Customer selectedCustomer = 
                this.customerIDComboBox.SelectedItem as Customer;

            try
            {
                // Load the first page of related orders for the selected customer.
                context.LoadProperty(selectedCustomer, "Orders");

                // Load all remaining pages.
                while (selectedCustomer.Orders.Continuation != null)
                {
                    selectedCustomer.Orders.Load(
                        context.Execute<Order>(selectedCustomer.Orders.Continuation.NextLinkUri));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void saveChangesButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Save changes to the data service.
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

Der folgende XAML-Code definiert das Fenster SalesOrders in WPF für das vorherige Beispiel.

    <Window x:Class="CustomerOrdersWpf3"
             xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
             Height="423" Width="679" Loaded="Window_Loaded">
    <StackPanel Orientation="Vertical" Height="Auto" Name="LayoutRoot" Width="Auto">
        <Label Content="Customer ID" Margin="20,0,0,0" />
        <ComboBox Name="customerIDComboBox" DisplayMemberPath="CustomerID" ItemsSource="{Binding}" 
                  SelectionChanged="customerIDComboBox_SelectionChanged"
                  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>
</Window>

Das folgende Beispiel ist aus der Code-Behind-Seite für eine XAML (Extensible Application Markup Language)-Seite, die das Fenster SalesOrders in WPF definiert. Wenn das Fenster geladen wird, wird eine DataServiceCollection<T> basierend auf dem Ergebnis einer Abfrage erstellt, die Kunden mit verknüpften Objekten nach Land gefiltert zurückgibt. Dieses Ergebnis wird an die DataContext-Eigenschaft des StackPanel gebunden, der das Stammlayoutsteuerelement für das WPF-Fenster ist.

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

Partial Public Class CustomerOrdersWpf
    Inherits Window

    Private context As NorthwindEntities
    Private trackedCustomers As DataServiceCollection(Of Customer)
    Private Const customerCountry As String = "Germany"
    Private Const svcUri As String = "https://localhost:12345/Northwind.svc/"
    Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Try
            ' Initialize the context for the data service.
            context = New NorthwindEntities(New Uri(svcUri))

            ' Create a LINQ query that returns customers with related orders.
            Dim customerQuery = From cust In context.Customers.Expand("Orders") _
                                    Where cust.Country = customerCountry _
                                    Select cust

                ' Create a new collection for binding based on the LINQ query.
            trackedCustomers = New DataServiceCollection(Of Customer)(customerQuery)

                ' Bind the root StackPanel element to the collection
                ' related object binding paths are defined in the XAML.
            Me.LayoutRoot.DataContext = trackedCustomers
        Catch ex As DataServiceQueryException
            MessageBox.Show("The query could not be completed:\n" + ex.ToString())
        Catch ex As InvalidOperationException
            MessageBox.Show("The following error occurred:\n" + ex.ToString())
        End Try
    End Sub
    Private Sub saveChangesButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Save changes to the data service.
        context.SaveChanges()
    End Sub
End Class
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 System.Data.Services.Client;
using NorthwindClient.Northwind;

namespace NorthwindClient
{
    public partial class CustomerOrdersWpf : Window
    {
        private NorthwindEntities context;
        private DataServiceCollection<Customer> trackedCustomers;
        private const string customerCountry = "Germany";
        private const string svcUri = "https://localhost:12345/Northwind.svc/";

        public CustomerOrdersWpf()
        {
            InitializeComponent();
        }

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

                // Create a LINQ query that returns customers with related orders.
                var customerQuery = from cust in context.Customers.Expand("Orders")
                                    where cust.Country == customerCountry
                                    select cust;

                // Create a new collection for binding based on the LINQ query.
                trackedCustomers = new DataServiceCollection<Customer>(customerQuery);

                // Bind the root StackPanel element to the collection;
                // related object binding paths are defined in the XAML.
                LayoutRoot.DataContext = trackedCustomers;
            }
            catch (DataServiceQueryException ex)
            {
                MessageBox.Show("The query could not be completed:\n" + ex.ToString());
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show("The following error occurred:\n" + ex.ToString());
            }
        }
        private void saveChangesButton_Click(object sender, RoutedEventArgs e)
        {
            // Save changes to the data service.
            context.SaveChanges();
        }
    }
}

Der folgende XAML-Code definiert das Fenster SalesOrders in WPF für das vorherige Beispiel.

    <Window x:Class="CustomerOrdersWpf"
             xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
             Height="423" Width="679" Loaded="Window_Loaded">
    <StackPanel Orientation="Vertical" Height="Auto" Name="LayoutRoot" 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>
</Window>