Controles de itens XAML; associar a uma coleção C++/WinRT
Uma coleção que pode ser efetivamente vinculada a um controle de itens XAML é conhecida como uma coleção observável. Essa ideia baseia-se no padrão de design de software conhecido como o padrão do observador. Este tópico mostra como implementar coleções observáveis em C++/WinRT e como associar controles de itens XAML a elas (para obter informações em segundo plano, confira Vinculação de dados).
Se você deseja acompanhar este tópico, recomendamos que crie primeiro o projeto descrito em Controles XAML; associar a uma propriedade de C++/WinRT. Este tópico adiciona mais código e expande os conceitos explicados naquele tópico.
Importante
Para ver conceitos e termos essenciais que ajudam a entender como utilizar e criar classes de runtime com C++/WinRT, confira Utilizar APIs com C++/WinRT e Criar APIs com C++/WinRT.
O que significa observável para uma coleção?
Se uma classe de runtime que representa uma coleção escolhe acionar o evento IObservableVector<T>::VectorChanged sempre que um elemento é adicionado ou removido dele, então a classe de runtime é uma coleção observável. Um controle de itens XAML pode se associar e manipular esses eventos, recuperando a coleção atualizada e, em seguida, atualizando a si mesmo para mostrar os elementos atuais.
Observação
Para obter informações sobre como instalar e usar o C++/WinRT Visual Studio Extension (VSIX) e o pacote NuGet (que juntos fornecem um modelo de projeto e suporte ao build), confira as informações de suporte do Visual Studio para C++/WinRT.
Adicionar uma coleção BookSkus a BookstoreViewModel
Em Controles XAML; associar a uma propriedade de C++/WinRT, nós adicionamos um tipo de propriedade BookSku a nosso modelo de visualização principal. Nesta etapa, usaremos o modelo de função de fábrica winrt::single_threaded_observable_vector para ajudar a implementar uma coleção observável de BookSku no mesmo modelo de exibição.
Declare uma nova propriedade em BookstoreViewModel.idl
.
// BookstoreViewModel.idl
...
runtimeclass BookstoreViewModel
{
BookSku BookSku{ get; };
Windows.Foundation.Collections.IObservableVector<BookSku> BookSkus{ get; };
}
...
Observação
Na listagem MIDL 3.0 acima, observe que o tipo da propriedade BookSkus é IObservableVector de BookSku. Na próxima seção deste tópico, associaremos a fonte de itens de uma ListBox a BookSkus. Uma caixa de listagem é um controle de itens e, para definir corretamente a propriedade ItemsControl.ItemsSource, é necessário defini-la como um valor do tipo IObservableVector ou IVector, ou de um tipo de interoperabilidade como IBindableObservableVector.
Aviso
O código mostrado neste tópico se aplica ao C++/WinRT 2.0.190530.8 e superior. Se estiver usando uma versão anterior, você precisará fazer alguns pequenos ajustes no código mostrado. Na listagem MIDL 3.0 acima, altere a propriedade BookSkus para IObservableVector de IInspectable. E, em seguida, use IInspectable (em vez de BookSku) em sua implementação, também.
Salve e compile. Copie os stubs de acessador de BookstoreViewModel.h
e BookstoreViewModel.cpp
na pasta \Bookstore\Bookstore\Generated Files\sources
(para saber mais, confira o tópico anterior, Controles XAML; associar a uma propriedade de C++/WinRT). Implemente os stubs de acessador dessa forma.
// 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;
}
...
Associar uma ListBox à propriedade BookSkus
Abra MainPage.xaml
, que contém a marcação XAML para a página principal da interface do usuário. Adicione a seguinte marcação dentro do mesmo StackPanel que 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>
Em MainPage.cpp
, adicione uma linha de código ao manipulador de eventos Click para acrescentar um livro à coleção.
// 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"));
}
...
Agora compile e execute o projeto. Clique no botão para executar o manipulador de eventos Click. Vimos que a implementação de Append aciona um evento para informar à interface do usuário que a coleção foi alterada; a ListBox consulta novamente a coleção para atualizar seu próprio valor de Items. Exatamente como antes, o título de um dos livros muda e essa alteração de título é refletida no botão e na caixa de listagem.