Dela via


XAML-objektkontroller; binda till en C++/WinRT-samling

En samling som effektivt kan bindas till en XAML-objektkontroll kallas för en observerbar samling. Den här idén baseras på det programvarudesignmönster som kallas observatörsmönster. Det här avsnittet visar hur du implementerar observerbara samlingar i C++/WinRT-och hur du binder XAML-objektkontroller till dem (för bakgrundsinformation finns Databindning).

Om du vill följa med i det här avsnittet rekommenderar vi att du först skapar projektet som beskrivs i XAML-kontroller. binda till en C++/WinRT-egenskap. Det här avsnittet lägger till mer kod i projektet och lägger till begreppen som beskrivs i det ämnet.

Viktigt!

Viktiga begrepp och termer som stöder din förståelse av hur du använder och författar körningsklasser med C++/WinRT kan du läsa om i Använda API:er med C++/WinRT och Skapa API:er med C++/WinRT.

Vad betyder observerbar för en samling?

Om en körningsklass som representerar en samling väljer att utlösa IObservableVector<T>::VectorChanged-händelsen när ett element läggs till samlingen eller tas bort från samlingen, är körningsklassen en observerbar kollektion. En XAML-objektkontroll kan binda till och hantera dessa händelser genom att hämta den uppdaterade samlingen och sedan uppdatera sig själv för att visa de aktuella elementen.

Anmärkning

Information om hur du installerar och använder C++/WinRT Visual Studio-tillägget (VSIX) och NuGet-paketet (som tillsammans tillhandahåller projektmall och byggstöd) finns i Visual Studio-stöd för C++/WinRT-.

Lägg till en BookSkus-samling i BookstoreViewModel

I XAML-kontroller; binda till en C++/WinRT-egenskaphar vi lagt till en egenskap av typen BookSku till vår huvudvymodell. I det här steget använder vi funktionsmallen winrt::single_threaded_observable_vector factory för att hjälpa oss att implementera en observerbar samling BookSku- på samma vymodell.

Deklarera en ny egenskap i BookstoreViewModel.idl.

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

Viktigt!

Bindning till en samling med C++/WinRT är lite mer nyanserad än med C#. Observera i listningen för MIDL 3.0 ovan att typen av egenskapen BookSkus är IObservableVector av BookSku. I nästa del av det här avsnittet ska vi binda källan till objekten för en ListBox till BookSkus. En listruta är en objektkontroll och om du vill ange egenskapen ItemsControl.ItemsSource måste du ange den till ett värde av typen IObservableVectoreller IVectoreller av en samverkanstyp som IBindableObservableVector. Annars {x:Bind} genererar E_INVALIDARG och {Binding} misslyckas tyst.

Varning

Koden som visas i det här avsnittet gäller för C++/WinRT version 2.0.190530.8 eller senare. Om du använder en tidigare version måste du göra några mindre justeringar av koden som visas. I MIDL 3.0-listan ovan ändrar du egenskapen BookSkus till IObservableVector för IInspectable. Och använd sedan IInspectable (i stället för BookSku) i implementeringen också.

Spara och skapa. Kopiera accessor stubs från BookstoreViewModel.h och BookstoreViewModel.cpp i mappen \Bookstore\Bookstore\Generated Files\sources (mer information finns i föregående avsnitt, XAML-kontroller; binda till en C++/WinRT-egenskap). Implementera dessa åtkomststubbar så här.

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

Binda en ListBox till egenskapen BookSkus

Öppna MainPage.xaml, som innehåller XAML-markering för vår huvudsida för användargränssnittet. Lägg till följande markering i samma StackPanel som 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>

I MainPage.cpplägger du till en kodrad i Klicka på händelsehanterare för att lägga till en bok i samlingen.

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

Skapa och kör nu projektet. Klicka på knappen för att köra händelsehanteraren Klick. Vi såg att implementeringen av Append skapar en händelse för att låta användargränssnittet veta att samlingen har ändrats; och ListBox frågar om samlingen för att uppdatera sitt eget Items-värde. Precis som tidigare ändras titeln på en av böckerna; och att rubrikändringen återspeglas både på knappen och i listrutan.

Viktiga API:er