Controlli di elementi XAML, binding a una raccolta C++/WinRTXAML items controls; bind to a C++/WinRT collection

Una raccolta di cui è possibile eseguire in modo efficace il binding a un controllo di elementi XAML è nota come raccolta osservabile.A collection that can be effectively bound to a XAML items control is known as an observable collection. Questo concetto è basato sul modello di progettazione del software noto come modello osservatore.This idea is based on the software design pattern known as the observer pattern. Questo argomento illustra come implementare raccolte osservabili in C++/WinRT e come eseguire il binding a controlli di elementi XAML. Per informazioni generali, vedi Data binding.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).

Se si desidera proseguire con questo argomento, è consigliabile creare innanzitutto il progetto descritto in Controlli XAML; binding a una proprietà 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. Questo argomento aggiunge altro codice al progetto e completa i concetti illustrati in quell'argomento.This topic adds more code to that project, and it adds to the concepts explained in that topic.

Importante

Per i concetti essenziali e i termini che possono aiutarti a comprendere come usare e creare classi di runtime con C++/WinRT, vedi Usare API con C++/WinRT e Creare API con 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.

Cosa vuol dire osservabile in riferimento a una raccolta?What does observable mean for a collection?

Se una classe di runtime che rappresenta una raccolta prevede la generazione dell'evento IObservableVector<T>::VectorChanged ogni volta che viene eseguita l'aggiunta o la rimozione di un elemento, la classe di runtime è una raccolta osservabile.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. Si può eseguire il binding di un controllo di elementi XAML a tali eventi in modo che li gestisca recuperando la raccolta aggiornata e poi si aggiorni per mostrare gli elementi correnti.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.

Nota

Per informazioni sull'installazione e sull'uso dell'Estensione C++/WinRT per Visual Studio (VSIX) e del pacchetto NuGet, che insieme forniscono il modello di progetto e il supporto della compilazione, vedi Supporto di Visual Studio per 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.

Aggiungere una raccolta BookSkus a BookstoreViewModelAdd a BookSkus collection to BookstoreViewModel

Nella sezione Controlli XAML, binding a una proprietà C++/WinRT abbiamo aggiunto una proprietà di tipo BookSku al nostro modello di visualizzazione principale.In XAML controls; bind to a C++/WinRT property, we added a property of type BookSku to our main view model. In questo passaggio useremo la funzione factory winrt::single_threaded_observable_vector per implementare una raccolta osservabile di BookSku sullo stesso modello di visualizzazione.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.

Dichiara una nuova proprietà in BookstoreViewModel.idl.Declare a new property in BookstoreViewModel.idl.

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

Nota

Nel listato MIDL 3.0 precedente puoi notare che il tipo della proprietà BookSkus è IObservableVector di BookSku.In the MIDL 3.0 listing above, note that the type of the BookSkus property is IObservableVector of BookSku. Nella sezione successiva di questo argomento eseguiremo il binding dell'origine degli elementi di un ListBox a BookSkus.In the next section of this topic, we'll be binding the items source of a ListBox to BookSkus. Una casella di riepilogo è un controllo di elementi e per impostare correttamente la proprietà ItemsControl.ItemsSource devi impostarla su un valore di tipo IObservableVector o IVector o di un tipo di interoperabilità, ad esempio 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.

Avviso

Il codice illustrato in questo argomento si applica a C++/WinRT versione 2.0.190530.8 e successive.The code shown in this topic applies to C++/WinRT version 2.0.190530.8 and higher. Se usi una versione precedente, dovrai apportare alcune piccole modifiche al codice illustrato.If you're using an earlier version, then you'll need to make some minor tweaks to the code shown. Nel listato MIDL 3.0 precedente, modifica la proprietà BookSkus in IObservableVector di IInspectable.In the MIDL 3.0 listing above, change the BookSkus property to IObservableVector of IInspectable. Usa quindi IInspectable (anziché BookSku) anche nella tua implementazione.And then use IInspectable (instead of BookSku) in your implementation, too.

Salva ed esegui la compilazione.Save and build. Copia gli stub di funzioni di accesso da BookstoreViewModel.h e BookstoreViewModel.cpp nella cartella \Bookstore\Bookstore\Generated Files\sources; per altri dettagli, vedi l'argomento precedente, Controlli XAML, binding a una proprietà 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). Implementa tali stub di funzioni di accesso in questo modo.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;
}
...

Eseguire il binding di ListBox alla proprietà BookSkusBind a ListBox to the BookSkus property

Apri MainPage.xaml, che contiene il markup XAML per la nostra pagina dell'interfaccia utente principale.Open MainPage.xaml, which contains the XAML markup for our main UI page. Aggiungi il markup seguente nello stesso StackPanel di 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>

In MainPage.cpp aggiungi una riga di codice al gestore eventi Click per aggiungere un libro alla raccolta.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"));
}
...

A questo punto compila ed esegui il progetto.Now build and run the project. Fai clic sul pulsante per eseguire il gestore eventi Click.Click the button to execute the Click event handler. Abbiamo visto che l'implementazione di Append genera un evento per segnalare all'interfaccia utente che la raccolta è stata modificata. ListBox esegue di nuovo una query sulla raccolta per aggiornare il proprio valore 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. Proprio come in precedenza, il titolo di uno dei libri cambia e tale modifica al titolo viene riflessa nel pulsante e nella casella di riepilogo.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 importantiImportant APIs