Contrôles d’éléments XAML ; liaison à une collection C++/WinRTXAML items controls; bind to a C++/WinRT collection

Une collection qui peut être efficacement liée à un contrôle d’éléments XAML est appelée collection observable.A collection that can be effectively bound to a XAML items control is known as an observable collection. Ce concept est basé sur le modèle de conception logicielle appelé modèle observateur.This idea is based on the software design pattern known as the observer pattern. Cette rubrique montre comment implémenter des collections observables en C++/WinRT et y lier des contrôles d’éléments XAML (pour des informations de référence, consultez Liaison de données.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).

Si vous souhaitez suivre cette rubrique, nous vous recommandons de tout d’abord créer le projet décrit dans la section Contrôles XAML ; liaison à une propriété C++/WinRT.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. Cette rubrique ajoute plus de code à ce projet et complète les concepts abordés.This topic adds more code to that project, and it adds to the concepts explained in that topic.

Important

Pour obtenir les principaux concepts et termes facilitant votre compréhension pour utiliser et créer des classes runtime avec C++/WinRT, voir Utiliser des API avec C++/WinRT et Créer des API avec 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.

Que signifie « observable » pour une collection ?What does observable mean for a collection?

Si une classe runtime qui représente une collection choisit de déclencher l’événement IObservableVector<T>: : VectorChanged chaque fois qu’un élément lui est ajouté ou retiré, alors la classe runtime est une collection observable.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. Un contrôle d’éléments XAML peut lier et gérer ces événements en récupérant la collection mise à jour et en se mettant à jour lui-même pour afficher les éléments actuels.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.

Notes

Pour plus d’informations sur l’installation et l’utilisation de l’extension VSIX (Visual Studio Extension) C++/WinRT et du package NuGet (qui fournissent ensemble la prise en charge des modèles et des builds de projet), consultez Prise en charge de Visual Studio pour 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.

Ajouter une collection BookSkus à BookstoreViewModelAdd a BookSkus collection to BookstoreViewModel

Dans Contrôles XAML ; liaison à une propriété C++/WinRT, nous avons ajouté une propriété de type BookSku à notre modèle d’affichage principal.In XAML controls; bind to a C++/WinRT property, we added a property of type BookSku to our main view model. Dans cette étape, nous allons utiliser le modèle de fonction d’usine winrt::single_threaded_observable_vector pour implémenter une collection observable de BookSku sur le même modèle d’affichage.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.

Déclarez une nouvelle propriété dans BookstoreViewModel.idl.Declare a new property in BookstoreViewModel.idl.

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

Notes

Dans le listing MIDL 3.0 ci-dessus, notez que le type de la propriété BookSkus est IObservableVector de BookSku.In the MIDL 3.0 listing above, note that the type of the BookSkus property is IObservableVector of BookSku. Dans la section suivante de cette rubrique, nous allons lier la source des éléments d’un ListBox à BookSkus.In the next section of this topic, we'll be binding the items source of a ListBox to BookSkus. Une zone de liste est un contrôle d’éléments. Pour définir correctement la propriété ItemsControl.ItemsSource, vous devez lui affecter une valeur de type IObservableVector ou IVector, ou d’un type d’interopérabilité tel que 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.

Avertissement

Le code présenté dans cette rubrique s’applique à C++/WinRT version 2.0.190530.8 et versions ultérieures.The code shown in this topic applies to C++/WinRT version 2.0.190530.8 and higher. Si vous utilisez une version antérieure, vous devez légèrement adapter le code affiché.If you're using an earlier version, then you'll need to make some minor tweaks to the code shown. Dans le listing MIDL 3.0 ci-dessus, remplacez la propriété BookSkus par le type IObservableVector de IInspectable.In the MIDL 3.0 listing above, change the BookSkus property to IObservableVector of IInspectable. Ensuite, utilisez également IInspectable (à la place de BookSku) dans votre implémentation.And then use IInspectable (instead of BookSku) in your implementation, too.

Enregistrez et lancez la génération.Save and build. Copiez les stubs accesseur de BookstoreViewModel.h et BookstoreViewModel.cpp dans le dossier \Bookstore\Bookstore\Generated Files\sources (pour plus d’informations, consultez la rubrique précédente, Contrôles XAML ; liaison à une propriété C++/WinRT).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). Implémentez ces stubs accesseur comme suit.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;
}
...

Lier un élément ListBox à la propriété BookSkusBind a ListBox to the BookSkus property

Ouvrez MainPage.xaml, qui contient le balisage XAML pour notre page d’interface utilisateur principale.Open MainPage.xaml, which contains the XAML markup for our main UI page. Ajoutez le balisage suivant dans le même StackPanel que 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>

Dans MainPage.cpp, ajoutez une ligne de code au gestionnaire d’événements Click pour ajouter un livre à la collection.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"));
}
...

Lancez à présent le processus de génération et exécutez le projet.Now build and run the project. Cliquez sur le bouton pour exécuter le gestionnaire d’événements Click.Click the button to execute the Click event handler. Nous avons vu que l’implémentation de Append déclenche un événement pour informer l’interface utilisateur que la collection a changé ; l’élément ListBox interroge de nouveau la collection pour mettre à jour sa propre valeur Items.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. Exactement comme précédemment, le titre de l’un des livres change ; et ce changement de titre est reflété à la fois sur le bouton et dans la zone de liste.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.

API importantesImportant APIs