XAML-Elementsteuerelemente: Binden an eine C++/WinRT-SammlungXAML items controls; bind to a C++/WinRT collection

Eine Sammlung, die effektiv an ein XAML-Elementsteuerelement gebunden werden kann, wird als Observable-Sammlung bezeichnet.A collection that can be effectively bound to a XAML items control is known as an observable collection. Dieses Konzept basiert auf dem Softwareentwurfsmuster, das als Beobachter-Muster bekannt ist.This idea is based on the software design pattern known as the observer pattern. In diesem Thema erfährst du, wie du beobachtbare Sammlungen in C++/WinRT implementierst und Steuerelemente für XAML-Elemente an sie bindest (Hintergrundinformationen findest Du unter Datenbindung).This topic shows how to implement observable collections in C++/WinRT, and how to bind XAML items controls to them (for background info, see Data binding).

Zur besseren Nachvollziehbarkeit dieses Themas empfiehlt es sich, zuerst das unter XAML-Steuerelemente: Binden an eine C++/WinRT-Eigenschaft beschriebene Projekt zu erstellen.If you want to follow along with this topic, then we recommend that you first create the project that's described in XAML controls; bind to a C++/WinRT property. In diesem Thema wird dem Projekt weiterer Code hinzugefügt, und es werden weitere Konzepte erläutert.This topic adds more code to that project, and it adds to the concepts explained in that topic.

Wichtig

Wichtige Konzepte und Begriffe im Zusammenhang mit der Nutzung und Erstellung von Laufzeitklassen mit C++/WinRT findest du unter Verwenden von APIs mit C++/WinRT sowie unter Erstellen von APIs mit C++/WinRT.For essential concepts and terms that support your understanding of how to consume and author runtime classes with C++/WinRT, see Consume APIs with C++/WinRT and Author APIs with C++/WinRT.

Was bedeutet beobachtbar für eine Sammlung?What does observable mean for a collection?

Wenn eine Laufzeitklasse, die eine Sammlung darstellt, das Ereignis IObservableVector<T>::VectorChanged auslöst, sobald ihr ein Element hinzugefügt oder ein Element daraus entfernt wird, ist die Laufzeitklasse eine beobachtbare Sammlung.If a runtime class that represents a collection chooses to raise the IObservableVector<T>::VectorChanged event whenever an element is added to it or removed from it, then the runtime class is an observable collection. Ein XAML-Elementsteuerelement kann an diese Ereignisse gebunden werden und sie behandeln, indem es die aktualisierte Sammlung abruft und sich anschließend selbst aktualisiert, um die aktuellen Elemente anzuzeigen.A XAML items control can bind to, and handle, these events by retrieving the updated collection and then updating itself to show the current elements.

Hinweis

Informationen zum Installieren und Verwenden der C++/WinRT Visual Studio-Erweiterung (VSIX) und des NuGet-Pakets (die zusammen die Projektvorlage und Buildunterstützung bereitstellen) findest du unter Visual Studio-Unterstützung für C++/WinRT.For info about installing and using the C++/WinRT Visual Studio Extension (VSIX) and the NuGet package (which together provide project template and build support), see Visual Studio support for C++/WinRT.

Hinzufügen einer Sammlung vom Typ BookSkus zu BookstoreViewModelAdd a BookSkus collection to BookstoreViewModel

In XAML-Steuerelemente: Binden an eine C++/WinRT-Eigenschaft haben wir unserem Hauptansichtsmodell eine Eigenschaft vom Typ BookSku hinzugefügt.In XAML controls; bind to a C++/WinRT property, we added a property of type BookSku to our main view model. In diesem Schritt verwenden wir die Factoryfunktionsvorlage winrt::single_threaded_observable_vector, um auf der Grundlage des gleichen Ansichtsmodells eine beobachtbare Sammlung von BookSku zu implementieren.In this step, we'll use the winrt::single_threaded_observable_vector factory function template to help us implement an observable collection of BookSku on the same view model.

Deklariere eine neue Eigenschaft in BookstoreViewModel.idl.Declare a new property in BookstoreViewModel.idl.

// BookstoreViewModel.idl
...
runtimeclass BookstoreViewModel
{
    BookSku BookSku{ get; };
    Windows.Foundation.Collections.IObservableVector<BookSku> BookSkus{ get; };
}
...

Hinweis

Wie in der obigen MIDL 3.0-Auflistung zu sehen, handelt es sich beim Typ der Eigenschaft BookSkus um IObservableVector von BookSku.In the MIDL 3.0 listing above, note that the type of the BookSkus property is IObservableVector of BookSku. Im nächsten Abschnitt dieses Themas binden wir die Elementquelle eines Listenfelds (ListBox an BookSkus.In the next section of this topic, we'll be binding the items source of a ListBox to BookSkus. Ein Listenfeld ist ein Elementsteuerelement. Die Eigenschaft ItemsControl.ItemsSource muss daher auf einen Wert vom Typ IObservableVector oder IVector festgelegt werden – oder auf einen Interoperabilitätstyp wie IBindableObservableVector.A list box is an items control, and to correctly set the ItemsControl.ItemsSource property, you need to set it to a value of type IObservableVector, or IVector, or of an interoperability type such as IBindableObservableVector.

Warnung

Der in diesem Thema gezeigt Code gilt für C++/WinRT, Version 2.0.190530.8 und höher.The code shown in this topic applies to C++/WinRT version 2.0.190530.8 and higher. Wenn Sie eine frühere Version verwenden, müssen einige geringe Anpassungen am dargestellten Code vornehmen.If you're using an earlier version, then you'll need to make some minor tweaks to the code shown. Ändern Sie in der obigen MIDL 3.0-Auflistung die Eigenschaft BookSkus in IObservableVector von IInspectable.In the MIDL 3.0 listing above, change the BookSkus property to IObservableVector of IInspectable. Verwenden Sie dann IInspectable (anstelle von BookSku) auch in Ihrer Implementierung.And then use IInspectable (instead of BookSku) in your implementation, too.

Speichere, und führe den Buildvorgang aus.Save and build. Kopiere die Accessor-Stubs aus BookstoreViewModel.h und BookstoreViewModel.cpp in den Ordner \Bookstore\Bookstore\Generated Files\sources. (Ausführlichere Informationen findest du im vorherigen Thema XAML-Steuerelemente: Binden an eine C++/WinRT-Eigenschaft.)Copy the accessor stubs from BookstoreViewModel.h and BookstoreViewModel.cpp in the \Bookstore\Bookstore\Generated Files\sources folder (for more details, see the previous topic, XAML controls; bind to a C++/WinRT property). Implementiere diese Accessor-Stubs wie folgt:Implement those accessor stubs like this.

// BookstoreViewModel.h
...
struct BookstoreViewModel : BookstoreViewModelT<BookstoreViewModel>
{
    BookstoreViewModel();

    Bookstore::BookSku BookSku();

    Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> BookSkus();

private:
    Bookstore::BookSku m_bookSku{ nullptr };
    Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> m_bookSkus;
};
...
// BookstoreViewModel.cpp
...
BookstoreViewModel::BookstoreViewModel()
{
    m_bookSku = winrt::make<Bookstore::implementation::BookSku>(L"Atticus");
    m_bookSkus = winrt::single_threaded_observable_vector<Bookstore::BookSku>();
    m_bookSkus.Append(m_bookSku);
}

Bookstore::BookSku BookstoreViewModel::BookSku()
{
    return m_bookSku;
}

Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> BookstoreViewModel::BookSkus()
{
    return m_bookSkus;
}
...

Binden eines Listenfelds an die Eigenschaft BookSkusBind a ListBox to the BookSkus property

Öffne MainPage.xaml. Darin befindet sich das XAML-Markup für unsere UI-Hauptseite.Open MainPage.xaml, which contains the XAML markup for our main UI page. Füge das folgende Markup innerhalb des gleichen StackPanel-Elements hinzu wie die Schaltfläche (Button).Add the following markup inside the same StackPanel as the Button.

<ListBox ItemsSource="{x:Bind MainViewModel.BookSkus}">
    <ItemsControl.ItemTemplate>
        <DataTemplate x:DataType="local:BookSku">
            <TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ListBox>

Füge in MainPage.cpp dem Ereignishandler für Click eine Codezeile hinzu, um am Ende der Sammlung ein Buch hinzuzufügen.In MainPage.cpp, add a line of code to the Click event handler to append a book to the collection.

// MainPage.cpp
...
void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    MainViewModel().BookSku().Title(L"To Kill a Mockingbird");
    MainViewModel().BookSkus().Append(winrt::make<Bookstore::implementation::BookSku>(L"Moby Dick"));
}
...

Erstelle nun das Projekt, und führe es aus.Now build and run the project. Klicke auf die Schaltfläche, um den Ereignishandler für Click auszuführen.Click the button to execute the Click event handler. Wir haben gesehen, dass die Implementierung von Append ein Ereignis auslöst, um die Benutzeroberfläche darauf hinzuweisen, dass sich die Sammlung geändert hat, und dass das Listenfeld (ListBox) die Sammlung erneut abfragt, um ihren eigenen Wert vom Typ Items zu aktualisieren.We saw that the implementation of Append raises an event to let the UI know that the collection has changed; and the ListBox re-queries the collection to update its own Items value. Genau wie zuvor ändert sich der Titel eines der Bücher, und diese Titeländerung wird sowohl auf der Schaltfläche als auch im Listenfeld angezeigt.Just as before, the title of one of the books changes; and that title change is reflected both on the button and in the list box.

Wichtige APIsImportant APIs