Sdílet prostřednictvím


XAML ovládací prvky pro položky; napojení na kolekci C++/WinRT

Kolekce, kterou lze efektivně vázat na ovládací prvek položek XAML, se označuje jako pozorovatelná kolekce. Tato myšlenka je založena na vzoru návrhu softwaru známém jako vzor pozorovatele . Toto téma ukazuje, jak implementovat pozorovatelné kolekce v C++/WinRTa jak s nimi svázat ovládací prvky položek XAML (informace o pozadí najdete v tématu Datové vazby).

Pokud chcete sledovat toto téma, doporučujeme nejprve vytvořit projekt, který je popsán v sekci ovládací prvky XAML; a navázat vazbu na vlastnost C++/WinRT. Toto téma přidá do tohoto projektu další kód a přidá se do konceptů vysvětlených v tomto tématu.

Důležité

Základní koncepty a termíny, které podporují pochopení toho, jak využívat a vytvářet třídy běhového prostředí pomocí C++/WinRT, najdete v tématu Využití rozhraní API pomocí C++/WinRT a Vytváření rozhraní API s C++/WinRT.

Co pozorovatelné znamená pro kolekci?

Pokud se třída modulu runtime, která představuje kolekci, rozhodne vyvolat událost IObservableVector<T>::VectorChanged pokaždé, když je prvek přidán nebo odebrán z této kolekce, pak je třída modulu runtime pozorovatelnou kolekcí. Ovládací prvek položek XAML může svázat a zpracovat tyto události načtením aktualizované kolekce a následnou aktualizací tak, aby zobrazoval aktuální prvky.

Poznámka:

Informace o instalaci a používání rozšíření C++/WinRT Visual Studio (VSIX) a balíčku NuGet (které společně poskytují podporu šablony projektu a sestavení), najdete v tématu podpora sady Visual Studio pro C++/WinRT.

Přidání kolekce BookSkus do BookstoreViewModel

V ovládacích prvcích XAML připojit k C++/WinRT vlastnostijsme přidali vlastnost typu BookSku k našemu modelu hlavního zobrazení. V tomto kroku použijeme šablonu funkce winrt::single_threaded_observable_vector factory, která nám pomůže implementovat pozorovatelnou kolekci BookSku ve stejném modelu zobrazení.

Deklarujte novou vlastnost v BookstoreViewModel.idl.

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

Důležité

Vazba na kolekci pomocí jazyka C++/WinRT je trochu nuaničtější než u jazyka C#. Ve výpisu MIDL 3.0 výše si všimněte, že vlastnosti BookSkus je typem IObservableVector z BookSku. V další části tohoto tématu budeme svazovat zdroj položek ListBox ke BookSkus. Seznamové pole je ovládací prvek pro položky, a abyste správně nastavili vlastnost ItemsControl.ItemsSource, je třeba ji nastavit na hodnotu typu IObservableVector, nebo IVector, nebo na typ interoperability, jako je IBindableObservableVector. {x:Bind} V opačném případě se vygeneruje E_INVALIDARG a {Binding} bezobslužně selže.

Výstraha

Kód uvedený v tomto tématu platí pro C++/WinRT verze 2.0.190530.8 nebo novější. Pokud používáte starší verzi, budete muset udělat několik dílčích úprav zobrazeného kódu. Ve výpisu MIDL 3.0 výše změňte vlastnost BookSkus na IObservableVector z IInspectable. A pak ve své implementaci použijte IInspectable (místo BookSku).

Uložte a sestavte. Zkopírujte zástupné procedury z BookstoreViewModel.h a BookstoreViewModel.cpp ve složce \Bookstore\Bookstore\Generated Files\sources (další podrobnosti najdete v předchozím tématu ovládacích prvků XAML; vazba na vlastnost C++/WinRT). Implementujte tyto zástupné metody přístupu takto.

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

Propojte ListBox s vlastností BookSkus

Otevřete MainPage.xaml, který obsahuje kód XAML pro naši hlavní stránku uživatelského rozhraní. Přidejte následující kód do stejného StackPanel jako tlačítko .

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

V MainPage.cpppřidejte řádek kódu do obslužné rutiny události Click a přidejte knihu do kolekce.

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

Nyní sestavte a spusťte projekt. Kliknutím na tlačítko spusťte obslužnou rutinu události Click. Viděli jsme, že implementace Append vyvolá událost, aby uživatelské rozhraní vědělo, že se kolekce změnila; a ListBox znovu dotazuje kolekci, aby aktualizovala vlastní hodnotu Items. Stejně jako předtím se název jedné knihy změní; a tato změna názvu se projeví jak na tlačítku, tak v seznamu.

Důležitá rozhraní API