Condividi tramite


Controlli elementi XAML; associazione a una raccolta C++/WinRT

Una raccolta che può essere efficacemente vincolata a un controllo di elementi XAML è conosciuta come una raccolta osservabile. Questa idea si basa sul modello di progettazione software noto come modello osservatore. Questo argomento illustra come implementare raccolte osservabili in C++/WinRT e come associare i controlli degli elementi XAML a tali raccolte (per informazioni generali, vedi Data binding).

Se vuoi seguire questo argomento, ti consigliamo prima di tutto di creare il progetto descritto in controlli XAML e di associare una proprietà C++/WinRT a. In questo argomento viene aggiunto più codice a quel progetto e si aggiunge ai concetti illustrati in quell'argomento.

Importante

Per i concetti e i termini essenziali che supportano la tua comprensione su come utilizzare e creare classi di runtime con C++/WinRT, vedi Usare le API con C++/WinRT e Creare le API con C++/WinRT.

Cosa significa l'osservabile per una raccolta?

Se una classe di runtime che rappresenta una raccolta sceglie di generare l'evento IObservableVector<T>::VectorChanged ogni volta che viene aggiunto o rimosso un elemento, la classe di runtime è una raccolta osservabile. Un controllo elementi XAML può associarsi e gestire questi eventi recuperando la raccolta aggiornata e quindi aggiornarsi per mostrare gli elementi correnti.

Annotazioni

Per informazioni sull'installazione e l'uso dell'estensione di Visual Studio C++/WinRT (VSIX) e del pacchetto NuGet (che insieme forniscono il modello di progetto e il supporto per la compilazione), vedere supporto di Visual Studio per C++/WinRT.

Aggiungere una collezione BookSkus a BookstoreViewModel

Nei controlli XAML, per collegare una proprietà C++/WinRT, abbiamo aggiunto una proprietà di tipo BookSku al nostro modello di visualizzazione principale. In questo passaggio si userà il modello di funzione winrt::single_threaded_observable_vector factory per implementare una raccolta osservabile di BookSku sullo stesso modello di visualizzazione.

Dichiarare una nuova proprietà in BookstoreViewModel.idl.

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

Importante

Il binding a una raccolta con C++/WinRT è leggermente più sfumato rispetto a C#. Nell'elenco MIDL 3.0 precedente, si noti che il tipo della proprietà BookSkus è IObservableVector di BookSku. Nella sezione successiva di questo argomento, collegheremo la fonte degli elementi di un ListBox alla BookSkus. Una casella di riepilogo è un controllo degli elementi e per impostare correttamente la proprietà ItemsControl.ItemsSource, è necessario impostarla su un valore di tipo IObservableVectoro IVectoroppure un tipo di interoperabilità, ad esempio IBindableObservableVector. In caso contrario, {x:Bind} genererà E_INVALIDARG e {Binding} avrà esito negativo in modo invisibile all'utente.

Avvertimento

Il codice illustrato in questo argomento si applica a C++/WinRT versione 2.0.190530.8 o successiva. Se si usa una versione precedente, sarà necessario apportare alcune piccole modifiche al codice illustrato. Nell'elenco MIDL 3.0 precedente, modificare la proprietà BookSkus in IObservableVector di IInspectable. E poi usare anche IInspectable (invece di BookSku) nell'implementazione.

Salvare e compilare. Copiare gli stub degli accessor da BookstoreViewModel.h e BookstoreViewModel.cpp nella cartella \Bookstore\Bookstore\Generated Files\sources (per ulteriori dettagli, vedere l'argomento precedente, controlli XAML ; associazione a una proprietà C++/WinRT). Implementare gli stub degli accessor in questo modo.

// 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;
}
...

Associare un controllo ListBox alla proprietà BookSkus

Aprire MainPage.xaml, che contiene il markup XAML per la pagina principale dell'interfaccia utente. Aggiungere il markup seguente all'interno dello stesso StackPanel del pulsante .

<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, aggiungere una riga di codice nel gestore dell'evento Click per aggiungere un libro alla collezione.

// 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"));
}
...

Compilare ed eseguire il progetto. Fare clic sul pulsante per eseguire il gestore eventi Click . Abbiamo visto che l'implementazione di Append genera un evento per informare l'interfaccia utente che la raccolta è stata modificata; e ListBox esegue nuovamente una query sulla raccolta per aggiornare il proprio valore items . Proprio come prima, il titolo di uno dei libri cambia; e tale modifica del titolo si riflette sia sul pulsante che nella casella di riepilogo.

API importanti