Datenbindung mit WPFDatabinding with WPF

Wichtig

Dieses Dokument gilt nur für WPF auf dem .NET FrameworkThis document is valid for WPF on the .NET Framework only

In diesem Dokument wird das Datenbindung für WPF auf dem .NET Framework beschrieben.This document describes databinding for WPF on the .NET Framework. Für neue .net Core-Projekte empfiehlt es sich, anstelle von Entity Framework 6 EF Core zu verwenden.For new .NET Core projects, we recommend you use EF Core instead of Entity Framework 6. Die Dokumentation für Datenbindung in EF Core finden Sie hier: " Getting Started with WPF".The documentation for databinding in EF Core is here: Getting Started with WPF.

In dieser schrittweisen exemplarischen Vorgehensweise wird gezeigt, wie poco-Typen an WPF-Steuerelemente in einem Master-Detail-Formular gebunden werden.This step-by-step walkthrough shows how to bind POCO types to WPF controls in a “master-detail" form. Die Anwendung verwendet die Entity Framework-APIs zum Auffüllen von Objekten mit Daten aus der Datenbank, zum Nachverfolgen von Änderungen und zum persistenten Speichern von Daten in der Datenbank.The application uses the Entity Framework APIs to populate objects with data from the database, track changes, and persist data to the database.

Das Modell definiert zwei Typen, die an einer 1: n-Beziehung beteiligt sind: Kategorie (Prinzipal \ Master) und Produkt (abhängige \ Details).The model defines two types that participate in one-to-many relationship: Category (principal\master) and Product (dependent\detail). Anschließend werden die Visual Studio-Tools verwendet, um die im Modell definierten Typen an die WPF-Steuerelemente zu binden.Then, the Visual Studio tools are used to bind the types defined in the model to the WPF controls. Das WPF-Datenbindungsframework ermöglicht die Navigation zwischen verbundenen Objekten: durch Auswählen von Zeilen in der Masteransicht wird die Detailansicht mit den entsprechenden untergeordneten Daten aktualisiert.The WPF data-binding framework enables navigation between related objects: selecting rows in the master view causes the detail view to update with the corresponding child data.

Die Screenshots und Code Auflistungen in dieser exemplarischen Vorgehensweise werden aus Visual Studio 2013 erstellt, aber Sie können diese exemplarische Vorgehensweise mit Visual Studio 2012 oder Visual Studio 2010 durcharbeiten.The screen shots and code listings in this walkthrough are taken from Visual Studio 2013 but you can complete this walkthrough with Visual Studio 2012 or Visual Studio 2010.

Verwenden Sie die Option "Object" zum Erstellen von WPF-Datenquellen.Use the 'Object' Option for Creating WPF Data Sources

Mit der vorherigen Version von Entity Framework wir die Verwendung der Daten Bank Option empfohlen, wenn eine neue Datenquelle basierend auf einem Modell erstellt wird, das mit dem EF-Designer erstellt wurde.With previous version of Entity Framework we used to recommend using the Database option when creating a new Data Source based on a model created with the EF Designer. Der Grund hierfür ist, dass der Designer einen Kontext generieren würde, der von ObjectContext-und Entitäts Klassen abgeleitet wurde, die von EntityObject abgeleitet wurden.This was because the designer would generate a context that derived from ObjectContext and entity classes that derived from EntityObject. Wenn Sie die-Datenbankoption verwenden, können Sie den besten Code für die Interaktion mit dieser API-Oberfläche schreiben.Using the Database option would help you write the best code for interacting with this API surface.

Die EF-Designer für Visual Studio 2012 und Visual Studio 2013 generieren einen Kontext, der von dbcontext zusammen mit einfachen poco-Entitäts Klassen abgeleitet wird.The EF Designers for Visual Studio 2012 and Visual Studio 2013 generate a context that derives from DbContext together with simple POCO entity classes. In Visual Studio 2010 empfiehlt es sich, auf eine Code Generierungs Vorlage zu wechseln, die dbcontext verwendet, wie weiter unten in dieser exemplarischen Vorgehensweise beschrieben.With Visual Studio 2010 we recommend swapping to a code generation template that uses DbContext as described later in this walkthrough.

Wenn Sie die dbcontext-API-Oberfläche verwenden, sollten Sie beim Erstellen einer neuen Datenquelle die- Objekt Option verwenden, wie in dieser exemplarischen Vorgehensweise dargestellt.When using the DbContext API surface you should use the Object option when creating a new Data Source, as shown in this walkthrough.

Bei Bedarf können Sie die auf ObjectContext basierende Codegenerierung für Modelle zurücksetzen, die mit dem EF-Designer erstellt wurden.If needed, you can revert to ObjectContext based code generation for models created with the EF Designer.

VoraussetzungenPre-Requisites

Zum Durchführen dieser exemplarischen Vorgehensweise muss Visual Studio 2013, Visual Studio 2012 oder Visual Studio 2010 installiert sein.You need to have Visual Studio 2013, Visual Studio 2012 or Visual Studio 2010 installed to complete this walkthrough.

Wenn Sie Visual Studio 2010 verwenden, müssen Sie auch nuget installieren.If you are using Visual Studio 2010, you also have to install NuGet. Weitere Informationen finden Sie unter Installieren von nuget.For more information, see Installing NuGet.  

Erstellen der AnwendungCreate the Application

  • Öffnen Sie Visual Studio.Open Visual Studio
  • Datei- > New- > Project...File -> New -> Project….
  • Klicken WindowsSie   im linken Bereich auf Fenster und im rechten Bereich auf wpfapplikation .Select Windows in the left pane and WPFApplication in the right pane
  • Geben Sie wpfwiamsample   als Name ein.Enter WPFwithEFSample as the name
  •  OK auswählenSelect OK

Installieren des Entity Framework nuget-PaketsInstall the Entity Framework NuGet package

  • Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf das winformswideratsample -Projekt.In Solution Explorer, right-click on the WinFormswithEFSample project
  • Wählen Sie nuget-Pakete verwalten... aus.Select Manage NuGet Packages…
  • Wählen Sie im Dialogfeld nuget-Pakete verwalten die Registerkarte Online aus, und wählen Sie das Paket EntityFramework aus.In the Manage NuGet Packages dialog, Select the Online tab and choose the EntityFramework package
  • Klicken Sie auf Install (Installieren).Click Install

    Hinweis

    Zusätzlich zur EntityFramework-Assembly wird auch ein Verweis auf "System. ComponentModel. DataAnnotations" hinzugefügt.In addition to the EntityFramework assembly a reference to System.ComponentModel.DataAnnotations is also added. Wenn das Projekt einen Verweis auf System. Data. Entity enthält, wird es entfernt, wenn das EntityFramework-Paket installiert wird.If the project has a reference to System.Data.Entity, then it will be removed when the EntityFramework package is installed. Die System. Data. Entity-Assembly wird für Entity Framework 6-Anwendungen nicht mehr verwendet.The System.Data.Entity assembly is no longer used for Entity Framework 6 applications.

Definieren eines ModellsDefine a Model

In dieser exemplarischen Vorgehensweise können Sie ein Modell mithilfe von Code First oder dem EF-Designer implementieren.In this walkthrough you can chose to implement a model using Code First or the EF Designer. Führen Sie einen der beiden folgenden Abschnitte aus.Complete one of the two following sections.

Option 1: Definieren eines Modells mit Code FirstOption 1: Define a Model using Code First

In diesem Abschnitt wird gezeigt, wie ein Modell und die zugehörige Datenbank mithilfe Code First erstellt werden.This section shows how to create a model and its associated database using Code First. Fahren Sie mit dem nächsten Abschnitt fort (Option 2: Definieren eines Modells mithilfe Database First) , wenn Sie stattdessen Database First verwenden möchten, um das Modell aus einer Datenbank mit dem EF-Designer umzukehren.Skip to the next section (Option 2: Define a model using Database First) if you would rather use Database First to reverse engineer your model from a database using the EF designer

Wenn Sie Code First Entwicklung verwenden, schreiben Sie in der Regel .NET Framework Klassen, die ihr konzeptionelles (Domänen-) Modell definieren.When using Code First development you usually begin by writing .NET Framework classes that define your conceptual (domain) model.

  • Fügen Sie der wpfwiderfsample -Klasse eine neue Klasse hinzu:Add a new class to the WPFwithEFSample:
    • Klicken Sie mit der rechten Maustaste auf den Projektnamen.Right-click on the project name
    • Wählen Sie Hinzufügenund dann Neues Element aus.Select Add, then New Item
    • Wählen Sie Klasse aus, und geben Sie Productals   Klassennamen ein.Select Class and enter Product for the class name
  • Ersetzen Sie die Product   Class-Definition durch den folgenden Code:Replace the Product class definition with the following code:
    namespace WPFwithEFSample
    {
        public class Product
        {
            public int ProductId { get; set; }
            public string Name { get; set; }

            public int CategoryId { get; set; }
            public virtual Category Category { get; set; }
        }
    }

- Add a **Category** class with the following definition:

    using System.Collections.ObjectModel;

    namespace WPFwithEFSample
    {
        public class Category
        {
            public Category()
            {
                this.Products = new ObservableCollection<Product>();
            }

            public int CategoryId { get; set; }
            public string Name { get; set; }

            public virtual ObservableCollection<Product> Products { get; private set; }
        }
    }

Die Products-Eigenschaft für die Category-Klasse und die Category-Eigenschaft für die Product-Klasse sind Navigationseigenschaften.The Products property on the Category class and Category property on the Product class are navigation properties. Im Entity Framework bieten Navigationseigenschaften eine Möglichkeit, in einer Beziehung zwischen zwei Entitätstypen zu navigieren.In Entity Framework, navigation properties provide a way to navigate a relationship between two entity types.

Zusätzlich zur Definition von Entitäten müssen Sie eine Klasse definieren, die von DbContext abgeleitet ist und DbSet<TEntity>-Eigenschaften bereitstellt.In addition to defining entities, you need to define a class that derives from DbContext and exposes DbSet<TEntity> properties. Die DbSet<TEntity>-Eigenschaften informieren den Kontext darüber, welche Typen Sie in das Modell einbeziehen möchten.The DbSet<TEntity> properties let the context know which types you want to include in the model.

Eine Instanz des von DbContext abgeleiteten Typs verwaltet die Entitätsobjekte während der Laufzeit, was das Auffüllen der Objekte mit Daten aus einer Datenbank, die Änderungsnachverfolgung und das persistente Speichern von Daten in der Datenbank umfasst.An instance of the DbContext derived type manages the entity objects during run time, which includes populating objects with data from a database, change tracking, and persisting data to the database.

  • Fügen Sie dem Projekt eine neue productcontext -Klasse mit der folgenden Definition hinzu:Add a new ProductContext class to the project with the following definition:
    using System.Data.Entity;

    namespace WPFwithEFSample
    {
        public class ProductContext : DbContext
        {
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
        }
    }

Kompilieren Sie das Projekt.Compile the project.

Option 2: Definieren eines Modells mit Database FirstOption 2: Define a model using Database First

In diesem Abschnitt wird gezeigt, wie Sie mit Database First das Modell aus einer Datenbank mit dem EF-Designer rückgängig machen.This section shows how to use Database First to reverse engineer your model from a database using the EF designer. Wenn Sie den vorherigen Abschnitt (Option 1: Definieren eines Modells mit Code First) abgeschlossen haben, überspringen Sie diesen Abschnitt, und wechseln Sie direkt zum Abschnitt Lazy Load .If you completed the previous section (Option 1: Define a model using Code First), then skip this section and go straight to the Lazy Loading section.

Erstellen einer vorhandenen DatenbankCreate an Existing Database

Wenn Sie eine vorhandene Datenbank als Ziel haben, wird Sie in der Regel bereits erstellt, aber in dieser exemplarischen Vorgehensweise müssen wir eine Datenbank erstellen, auf die zugegriffen werden kann.Typically when you are targeting an existing database it will already be created, but for this walkthrough we need to create a database to access.

Der Datenbankserver, der mit Visual Studio installiert wird, unterscheidet sich abhängig von der installierten Version von Visual Studio:The database server that is installed with Visual Studio is different depending on the version of Visual Studio you have installed:

  • Wenn Sie Visual Studio 2010 verwenden, erstellen Sie eine SQL Express-Datenbank.If you are using Visual Studio 2010 you'll be creating a SQL Express database.
  • Wenn Sie Visual Studio 2012 verwenden, erstellen Sie eine localdb -Datenbank.If you are using Visual Studio 2012 then you'll be creating a LocalDB database.

Nun generieren wir die Datenbank.Let's go ahead and generate the database.

  • Ansicht- > Server-ExplorerView -> Server Explorer

  • Klicken Sie mit der rechten Maustaste auf Datenverbindungen- > Verbindung hinzufügen...Right click on Data Connections -> Add Connection…

  • Wenn Sie über Server-Explorer keine Verbindung mit einer Datenbank hergestellt haben, müssen Sie Microsoft SQL Server als Datenquelle auswählen.If you haven’t connected to a database from Server Explorer before you’ll need to select Microsoft SQL Server as the data source

    Datenquelle ändern

  • Stellen Sie abhängig von der installierten Verbindung entweder localdb oder SQL Express her, und geben Sie Produkte als Datenbanknamen ein.Connect to either LocalDB or SQL Express, depending on which one you have installed, and enter Products as the database name

    Verbindung localdb hinzufügen

    Verbindung hinzufügen Express

  • Wählen Sie OK aus, und Sie werden gefragt, ob Sie eine neue Datenbank erstellen möchten, und wählen Sie Ja aus.Select OK and you will be asked if you want to create a new database, select Yes

    Erstellen einer Datenbank

  • Die neue Datenbank wird nun in Server-Explorer angezeigt, klicken Sie mit der rechten Maustaste darauf, und wählen Sie neue Abfrage aus.The new database will now appear in Server Explorer, right-click on it and select New Query

  • Kopieren Sie den folgenden SQL-Befehl in die neue Abfrage, klicken Sie mit der rechten Maustaste auf die Abfrage, und wählen Sie Ausführen .Copy the following SQL into the new query, then right-click on the query and select Execute

    CREATE TABLE [dbo].[Categories] (
        [CategoryId] [int] NOT NULL IDENTITY,
        [Name] [nvarchar](max),
        CONSTRAINT [PK_dbo.Categories] PRIMARY KEY ([CategoryId])
    )

    CREATE TABLE [dbo].[Products] (
        [ProductId] [int] NOT NULL IDENTITY,
        [Name] [nvarchar](max),
        [CategoryId] [int] NOT NULL,
        CONSTRAINT [PK_dbo.Products] PRIMARY KEY ([ProductId])
    )

    CREATE INDEX [IX_CategoryId] ON [dbo].[Products]([CategoryId])

    ALTER TABLE [dbo].[Products] ADD CONSTRAINT [FK_dbo.Products_dbo.Categories_CategoryId] FOREIGN KEY ([CategoryId]) REFERENCES [dbo].[Categories] ([CategoryId]) ON DELETE CASCADE

Reverse Engineering-ModellReverse Engineer Model

Wir verwenden Entity Framework Designer, die als Teil von Visual Studio enthalten ist, um das Modell zu erstellen.We’re going to make use of Entity Framework Designer, which is included as part of Visual Studio, to create our model.

  • Project- > Neues Element hinzufügen...Project -> Add New Item…

  • Wählen Sie im linken Menü Daten aus, und klicken Sie dann auf ADO.NET Entity Data ModelSelect Data from the left menu and then ADO.NET Entity Data Model

  • Geben Sie ProductModel als Name ein, und klicken Sie auf OK .Enter ProductModel as the name and click OK

  • Dadurch wird der Entity Data Model-Assistent gestartet.This launches the Entity Data Model Wizard

  • Wählen Sie aus Datenbank generieren aus , und klicken Sie auf weiterSelect Generate from Database and click Next

    Auswählen von Modellinhalten

  • Wählen Sie die Verbindung mit der Datenbank, die Sie im ersten Abschnitt erstellt haben, geben Sie productcontext als Namen der Verbindungs Zeichenfolge ein, und klicken Sie auf weiter .Select the connection to the database you created in the first section, enter ProductContext as the name of the connection string and click Next

    Verbindung auswählen

  • Aktivieren Sie das Kontrollkästchen neben "Tables", um alle Tabellen zu importieren, und klicken Sie auf "Fertigstellen"Click the checkbox next to ‘Tables’ to import all tables and click ‘Finish’

    Objekte auswählen

Sobald der Reverse-Engineering-Prozess abgeschlossen ist, wird das neue Modell dem Projekt hinzugefügt und geöffnet, damit Sie es im Entity Framework Designer anzeigen können.Once the reverse engineer process completes the new model is added to your project and opened up for you to view in the Entity Framework Designer. Außerdem wurde dem Projekt eine App.config Datei mit den Verbindungsdetails für die Datenbank hinzugefügt.An App.config file has also been added to your project with the connection details for the database.

Weitere Schritte in Visual Studio 2010Additional Steps in Visual Studio 2010

Wenn Sie in Visual Studio 2010 arbeiten, müssen Sie den EF-Designer aktualisieren, damit die EF6-Codegenerierung verwendet werden kann.If you are working in Visual Studio 2010 then you will need to update the EF designer to use EF6 code generation.

  • Klicken Sie mit der rechten Maustaste auf eine leere Stelle des Modells im EF-Designer, und wählen Sie Code Generierungs Element hinzufügen... aus.Right-click on an empty spot of your model in the EF Designer and select Add Code Generation Item…
  • Wählen Sie im linken Menü Online Vorlagen aus, und suchen Sie nach dbcontext .Select Online Templates from the left menu and search for DbContext
  • Wählen Sie den EF 6. x dbcontext Generator für C aus # , geben Sie ProductModel als Name ein, und klicken Sie auf hinzufügen.Select the EF 6.x DbContext Generator for C#, enter ProductsModel as the name and click Add

Aktualisieren der Codegenerierung für die DatenbindungUpdating code generation for data binding

EF generiert Code aus dem Modell mithilfe von T4-Vorlagen.EF generates code from your model using T4 templates. Die Vorlagen, die in Visual Studio enthalten sind oder aus der Visual Studio Gallery heruntergeladen wurden, sind für die allgemeine Verwendung vorgesehen.The templates shipped with Visual Studio or downloaded from the Visual Studio gallery are intended for general purpose use. Dies bedeutet, dass die von diesen Vorlagen generierten Entitäten einfache ICollection < T- > Eigenschaften haben.This means that the entities generated from these templates have simple ICollection<T> properties. Wenn Sie jedoch die Datenbindung mithilfe von WPF durchführen, ist es wünschenswert, ObservableCollection für Auflistungs Eigenschaften zu verwenden, damit WPF Änderungen an den Auflistungen nachverfolgen kann.However, when doing data binding using WPF it is desirable to use ObservableCollection for collection properties so that WPF can keep track of changes made to the collections. Zu diesem Zweck werden die Vorlagen für die Verwendung von ObservableCollection geändert.To this end we will to modify the templates to use ObservableCollection.

  • Öffnen Sie die Projektmappen-Explorer , und suchen Sie nach der Datei ProductModel. edmx.Open the Solution Explorer and find ProductModel.edmx file

  • Suchen Sie die ProductModel.tt -Datei, die unter der Datei "ProductModel. edmx" eingefügt wird.Find the ProductModel.tt file which will be nested under the ProductModel.edmx file

    WPF-Produktmodell Vorlage

  • Doppelklicken Sie auf die Datei ProductModel.tt, um Sie im Visual Studio-Editor zu öffnen.Double-click on the ProductModel.tt file to open it in the Visual Studio editor

  • Suchen und ersetzen Sie die beiden Vorkommen von "ICollection" durch "ObservableCollection".Find and replace the two occurrences of “ICollection” with “ObservableCollection”. Diese befinden sich ungefähr in den Zeilen 296 und 484.These are located approximately at lines 296 and 484.

  • Suchen und ersetzen Sie das erste Vorkommen von "HashSet" durch "ObservableCollection".Find and replace the first occurrence of “HashSet” with “ObservableCollection”. Dieses Vorkommen befindet sich ungefähr in Zeile 50.This occurrence is located approximately at line 50. Ersetzen Sie nicht das zweite Vorkommen des Hashsets, das später im Code gefunden wurde.Do not replace the second occurrence of HashSet found later in the code.

  • Suchen und ersetzen Sie das einzige Vorkommen von "System. Collections. Generic" durch "System. Collections. ObjectModel".Find and replace the only occurrence of “System.Collections.Generic” with “System.Collections.ObjectModel”. Dies befindet sich ungefähr in Zeile 424.This is located approximately at line 424.

  • Speichern Sie die Datei ProductModel.tt.Save the ProductModel.tt file. Dies sollte bewirken, dass der Code für Entitäten erneut generiert wird.This should cause the code for entities to be regenerated. Wenn der Code nicht automatisch neu generiert wird, klicken Sie mit der rechten Maustaste auf ProductModel.tt, und wählen Sie "benutzerdefiniertes Tool ausführen".If the code does not regenerate automatically, then right click on ProductModel.tt and choose “Run Custom Tool”.

Wenn Sie nun die Category.cs-Datei öffnen (die unter ProductModel.tt geschachtelte ist), sollten Sie sehen, dass die Products-Sammlung den Typ **ObservableCollection- < Produkt > **aufweist.If you now open the Category.cs file (which is nested under ProductModel.tt) then you should see that the Products collection has the type ObservableCollection<Product>.

Kompilieren Sie das Projekt.Compile the project.

Lazy LoadingLazy Loading

Die Products-Eigenschaft für die Category-Klasse und die Category-Eigenschaft für die Product-Klasse sind Navigationseigenschaften.The Products property on the Category class and Category property on the Product class are navigation properties. Im Entity Framework bieten Navigationseigenschaften eine Möglichkeit, in einer Beziehung zwischen zwei Entitätstypen zu navigieren.In Entity Framework, navigation properties provide a way to navigate a relationship between two entity types.

EF bietet Ihnen die Möglichkeit, Verwandte Entitäten aus der Datenbank automatisch zu laden, wenn Sie zum ersten Mal auf die Navigations Eigenschaft zugreifen.EF gives you an option of loading related entities from the database automatically the first time you access the navigation property. Beachten Sie bei dieser Art von Laden (das als „Lazy Loading“ bezeichnet wird), dass beim ersten Zugriff auf jede Navigationseigenschaft eine separate Abfrage für die Datenbank ausgeführt wird, wenn sich die Inhalte nicht bereits im Kontext befinden.With this type of loading (called lazy loading), be aware that the first time you access each navigation property a separate query will be executed against the database if the contents are not already in the context.

Wenn poco-Entitäts Typen verwendet werden, erreicht EF Lazy Loading durch Erstellen von Instanzen abgeleiteter Proxy Typen während der Laufzeit und das anschließende Überschreiben virtueller Eigenschaften in den Klassen, um den Lade Hook hinzuzufügen.When using POCO entity types, EF achieves lazy loading by creating instances of derived proxy types during runtime and then overriding virtual properties in your classes to add the loading hook. Wenn Sie Lazy Loading verknüpfter Objekte abrufen möchten, müssen Sie die Navigations Eigenschaften Getter als Public und Virtual (Overridable in Visual Basic) deklarieren, und die Klasse darf nicht versiegelt sein (nodeverridable in Visual Basic).To get lazy loading of related objects, you must declare navigation property getters as public and virtual (Overridable in Visual Basic), and you class must not be sealed (NotOverridable in Visual Basic). Bei Verwendung Database First Navigations Eigenschaften automatisch als virtuell fest, um Lazy Loading zu aktivieren.When using Database First navigation properties are automatically made virtual to enable lazy loading. Im Code First Abschnitt haben wir entschieden, die Navigations Eigenschaften aus demselben Grund virtuell zu machen.In the Code First section we chose to make the navigation properties virtual for the same reason

Binden von Objekten an SteuerelementeBind Object to Controls

Fügen Sie die Klassen, die im Modell definiert sind, als Datenquellen für diese WPF-Anwendung hinzu.Add the classes that are defined in the model as data sources for this WPF application.

  • Doppelklicken Sie im Projektmappen-Explorer auf MainWindow.xaml, um das Hauptformular zu öffnen.Double-click MainWindow.xaml in Solution Explorer to open the main form

  • Wählen Sie im Hauptmenü Projekt- > neue Datenquelle hinzufügen... aus.From the main menu, select Project -> Add New Data Source … (in Visual Studio 2010 müssen Sie Daten- > neue Datenquelle hinzufügen...)(in Visual Studio 2010, you need to select Data -> Add New Data Source…)

  • Wählen Sie im Fenster Datenquelle auswählen die Option Objekt aus, und klicken Sie auf weiter .In the Choose a Data Source Typewindow, select Object and click Next

  • Erweitern Sie im Dialogfeld Wählen Sie die Datenobjekte aus das wpfwiderf-Beispiel   zweimal, und wählen Sie Category aus.In the Select the Data Objects dialog, unfold the WPFwithEFSample two times and select Category
    Die Produkt Datenquelle muss nicht ausgewählt werden, da wir Sie über die ProduktEigenschaft der Kategorie Datenquelle erhalten.There is no need to select the Product data source, because we will get to it through the Product’s property on the Category data source

    Datenobjekte auswählen

  • Klicken Sie auf Fertig stellen.Click Finish.

  • Das Fenster Datenquellen wird neben dem Fenster MainWindow. XAML geöffnet *, wenn das Fenster Datenquellen nicht angezeigt wird, wählen Sie Ansicht- > Weitere Windows- > Datenquellen * aus.The Data Sources window is opened next to the MainWindow.xaml window If the Data Sources window is not showing up, select View -> Other Windows-> Data Sources

  • Klicken Sie auf das anheft Symbol, damit das Fenster Datenquellen nicht automatisch ausgeblendet wird.Press the pin icon, so the Data Sources window does not auto hide. Sie müssen möglicherweise auf die Schaltfläche "Aktualisieren" klicken, wenn das Fenster bereits sichtbar war.You may need to hit the refresh button if the window was already visible.

    Datenquellen

  • Wählen Sie die kategoriedatenquelle aus, und ziehen Sie Sie auf das Formular.Select the Category data source and drag it on the form.

Folgendes ist aufgetreten, als wir diese Quelle gezogen haben:The following happened when we dragged this source:

  • Die categoryviewsource -Ressource und das categorydatagrid- Steuerelement wurden zu XAML hinzugefügt.The categoryViewSource resource and the categoryDataGrid control were added to XAML
  • Die DataContext-Eigenschaft des übergeordneten Grid-Elements wurde auf "{statikresource categoryviewsource }" festgelegt.The DataContext property on the parent Grid element was set to "{StaticResource categoryViewSource }".Die categoryviewsource -Ressource dient als Bindungs Quelle für das äußere über \ geordnete Raster Element. The categoryViewSource resource serves as a binding source for the outer\parent Grid element. Die inneren Raster Elemente erben dann den DataContext-Wert vom übergeordneten Raster (die ItemsSource-Eigenschaft von categorydatagrid ist auf "{Binding}" festgelegt).The inner Grid elements then inherit the DataContext value from the parent Grid (the categoryDataGrid’s ItemsSource property is set to "{Binding}")
    <Window.Resources>
        <CollectionViewSource x:Key="categoryViewSource"
                                d:DesignSource="{d:DesignInstance {x:Type local:Category}, CreateList=True}"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource categoryViewSource}">
        <DataGrid x:Name="categoryDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True"
                    ItemsSource="{Binding}" Margin="13,13,43,191"
                    RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="categoryIdColumn" Binding="{Binding CategoryId}"
                                    Header="Category Id" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="nameColumn" Binding="{Binding Name}"
                                    Header="Name" Width="SizeToHeader"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

Hinzufügen eines DetailrastersAdding a Details Grid

Nachdem wir nun über ein Raster zum Anzeigen von Kategorien verfügen, können wir ein Detail Raster hinzufügen, um die zugeordneten Produkte anzuzeigen.Now that we have a grid to display Categories let's add a details grid to display the associated Products.

  • Wählen Sie unter der Kategorie Datenquelle die Eigenschaft Produkte aus, und ziehen Sie Sie auf das Formular.Select the Products property from under the Category data source and drag it on the form.
    • Die categoryproductviewsource -Ressource und das productdatagrid- Raster werden XAML hinzugefügt.The categoryProductsViewSource resource and productDataGrid grid are added to XAML
    • Der Bindungs Pfad für diese Ressource ist auf Products festgelegt.The binding path for this resource is set to Products
    • WPF-Daten Bindungs Framework stellt sicher, dass nur Produkte im Zusammenhang mit der ausgewählten Kategorie in productdatagrid angezeigt werden.WPF data-binding framework ensures that only Products related to the selected Category show up in productDataGrid
  • Ziehen Sie die Schaltfläche aus der Toolbox auf das Formular.From the Toolbox, drag Button on to the form. Legen Sie die Name -Eigenschaft auf ButtonSave und die Content -Eigenschaft auf Savefest.Set the Name property to buttonSave and the Content property to Save.

Das Formular sollte in etwa wie folgt aussehen:The form should look similar to this:

Designer Formular

Hinzufügen von Code, der die Dateninteraktion verarbeitetAdd Code that Handles Data Interaction

Es ist an der Zeit, dem Hauptfenster einige Ereignishandler hinzuzufügen.It's time to add some event handlers to the main window.

  • Klicken Sie im XAML-Fenster auf das ** < Fenster** Element, sodass das Hauptfenster ausgewählt wird.In the XAML window, click on the <Window element, this selects the main window

  • Wählen Sie im Eigenschaften Fenster oben rechts Ereignisse aus, und doppelklicken Sie dann auf das Textfeld rechts neben der geladenen Bezeichnung.In the Properties window choose Events at the top right, then double-click the text box to right of the Loaded label

    Eigenschaften des Hauptfensters

  • Fügen Sie auch das Click-Ereignis für die Schaltfläche Speichern hinzu, indem Sie im Designer auf die Schaltfläche Speichern doppelklicken.Also add the Click event for the Save button by double-clicking the Save button in the designer.

Dadurch gelangen Sie zum Code Behind für das Formular. nun bearbeiten wir den Code so, dass der productcontext zum Ausführen von Datenzugriff verwendet wird.This brings you to the code behind for the form, we'll now edit the code to use the ProductContext to perform data access. Aktualisieren Sie den Code für das MainWindow, wie unten gezeigt.Update the code for the MainWindow as shown below.

Der Code deklariert eine Instanz von productcontextmit langer Laufzeit.The code declares a long-running instance of ProductContext. Das productcontext -Objekt wird verwendet, um Daten abzufragen und in der Datenbank zu speichern.The ProductContext object is used to query and save data to the database. Der Löschvorgang () auf der productcontext -Instanz wird dann von der überschriebenen OnClosing -Methode aufgerufen.The Dispose() on the ProductContext instance is then called from the overridden OnClosing method.Die Code Kommentare enthalten Details zum Funktionsumfang des Codes. The code comments provide details about what the code does.

    using System.Data.Entity;
    using System.Linq;
    using System.Windows;

    namespace WPFwithEFSample
    {
        public partial class MainWindow : Window
        {
            private ProductContext _context = new ProductContext();
            public MainWindow()
            {
                InitializeComponent();
            }

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                System.Windows.Data.CollectionViewSource categoryViewSource =
                    ((System.Windows.Data.CollectionViewSource)(this.FindResource("categoryViewSource")));

                // Load is an extension method on IQueryable,
                // defined in the System.Data.Entity namespace.
                // This method enumerates the results of the query,
                // similar to ToList but without creating a list.
                // When used with Linq to Entities this method
                // creates entity objects and adds them to the context.
                _context.Categories.Load();

                // After the data is loaded call the DbSet<T>.Local property
                // to use the DbSet<T> as a binding source.
                categoryViewSource.Source = _context.Categories.Local;
            }

            private void buttonSave_Click(object sender, RoutedEventArgs e)
            {
                // When you delete an object from the related entities collection
                // (in this case Products), the Entity Framework doesn’t mark
                // these child entities as deleted.
                // Instead, it removes the relationship between the parent and the child
                // by setting the parent reference to null.
                // So we manually have to delete the products
                // that have a Category reference set to null.

                // The following code uses LINQ to Objects
                // against the Local collection of Products.
                // The ToList call is required because otherwise the collection will be modified
                // by the Remove call while it is being enumerated.
                // In most other situations you can use LINQ to Objects directly
                // against the Local property without using ToList first.
                foreach (var product in _context.Products.Local.ToList())
                {
                    if (product.Category == null)
                    {
                        _context.Products.Remove(product);
                    }
                }

                _context.SaveChanges();
                // Refresh the grids so the database generated values show up.
                this.categoryDataGrid.Items.Refresh();
                this.productsDataGrid.Items.Refresh();
            }

            protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
            {
                base.OnClosing(e);
                this._context.Dispose();
            }
        }

    }

Testen der WPF-AnwendungTest the WPF Application

  • Kompilieren Sie die Anwendung, und führen Sie sie aus.Compile and run the application. Wenn Sie Code First verwendet haben, werden Sie feststellen, dass eine wpfwitef Sample. productcontext -Datenbank für Sie erstellt wird.If you used Code First, then you will see that a WPFwithEFSample.ProductContext database is created for you.

  • Geben Sie einen Kategorienamen im oberen Raster ein, und die Produktnamen im unteren Raster geben in den ID-Spalten nichts ein, da der Primärschlüssel von der Datenbank generiert wird .Enter a category name in the top grid and product names in the bottom grid Do not enter anything in ID columns, because the primary key is generated by the database

    Hauptfenster mit neuen Kategorien und Produkten

  • Klicken Sie auf die Schaltfläche Speichern , um die Daten in der Datenbank zu speichernPress the Save button to save the data to the database

Nach dem Aufrufe von " SaveChanges ()" von dbcontext werden die IDs mit den von der Datenbank generierten Werten aufgefüllt.After the call to DbContext’s SaveChanges(), the IDs are populated with the database generated values. Da wir " Refresh () " nach " SaveChanges () " aufgerufen haben, werden die DataGrid- Steuerelemente ebenfalls mit den neuen Werten aktualisiert.Because we called Refresh() after SaveChanges() the DataGrid controls are updated with the new values as well.

Hauptfenster mit aufgefüllten IDs

Weitere RessourcenAdditional Resources

Weitere Informationen zur Datenbindung an Auflistungen mithilfe von WPF finden Sie in diesem Thema in der WPF-Dokumentation.To learn more about data binding to collections using WPF, see this topic in the WPF documentation.