Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Una colección que se puede enlazar eficazmente a un control de elementos XAML se conoce como una colección de observable. Esta idea se basa en el patrón de diseño de software conocido como patrón de observador. En este tema se muestra cómo implementar colecciones observables en C++/WinRT y cómo enlazar controles de elementos XAML a ellas (para obtener información en segundo plano, consulta Enlace de datos).
Si quieres seguir este tema, te recomendamos crear primero el proyecto que se describe en controles XAML; enlazar a una propiedad de C++/WinRT. En este tema se agrega más código a ese proyecto, y esto añade a los conceptos explicados en ese tema.
Importante
Para conocer los conceptos y términos esenciales que apoyan la comprensión de cómo consumir y desarrollar clases de tiempo de ejecución con C++/WinRT, consulte Consumir APIs con C++/WinRT y Desarrollar APIs con C++/WinRT.
¿Qué significa elemento observable para una colección?
Si una clase en tiempo de ejecución que representa una colección elige generar el evento IObservableVector<T>::VectorChanged cada vez que se agrega o quita un elemento de ella, la clase en tiempo de ejecución es una colección observable. Un control de elementos XAML puede enlazar y controlar estos eventos recuperando la colección actualizada y, a continuación, actualizándose para mostrar los elementos actuales.
Nota:
Para obtener información sobre cómo instalar y usar la extensión de Visual Studio (VSIX) de C++/WinRT y el paquete NuGet (que juntos proporcionan soporte para plantillas de proyecto y compilación), consulte compatibilidad de Visual Studio con C++/WinRT.
Agregue una colección BookSkus a BookstoreViewModel
En los controles XAML , al enlazar con una propiedad de C++/WinRT, hemos agregado una propiedad de tipo BookSku a nuestro modelo de vista principal. En este paso, usaremos la plantilla de función de fábrica winrt::single_threaded_observable_vector
Declara una nueva propiedad en BookstoreViewModel.idl.
// BookstoreViewModel.idl
...
runtimeclass BookstoreViewModel
{
BookSku BookSku{ get; };
Windows.Foundation.Collections.IObservableVector<BookSku> BookSkus{ get; };
}
...
Importante
Con C++/WinRT, enlazar a una colección es un poco más sutil que con C#. En la lista de MIDL 3.0 anterior, observe que el tipo de la propiedad BookSkus es IObservableVector de BookSku. En la siguiente sección de este tema, enlazaremos el origen de elementos de un ListBox a BookSkus. Un cuadro de lista es un control de elementos y para establecer correctamente la propiedad ItemsControl.ItemsSource , debe establecerlo en un valor de tipo IObservableVector o IVector, o de un tipo de interoperabilidad como IBindableObservableVector. De lo contrario, {x:Bind} generará E_INVALIDARG y {Binding} fallará silenciosamente.
Advertencia
El código que se muestra en este tema se aplica a C++/WinRT versión 2.0.190530.8 o posterior. Si usa una versión anterior, deberá realizar algunos ajustes menores en el código que se muestra. En la lista anterior de MIDL 3.0, cambie la propiedad BookSkus a IObservableVector de IInspectable. A continuación, use también IInspectable (en lugar de BookSku) en la implementación.
Guardar y compilar. Copie los stubs de acceso de BookstoreViewModel.h y BookstoreViewModel.cpp en la carpeta \Bookstore\Bookstore\Generated Files\sources (para obtener más detalles, consulte el tema anterior, controles XAML; vinculación a una propiedad C++/WinRT). Implemente esos códigos auxiliares de descriptor de acceso como este.
// 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;
}
...
Enlaza un ListBox a la propiedad BookSkus de
Abra MainPage.xaml, que contiene el marcado XAML para nuestra página principal de la interfaz de usuario. Agregue el siguiente marcado dentro del mismo StackPanel que el botón de .
<ListBox ItemsSource="{x:Bind MainViewModel.BookSkus}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:BookSku">
<TextBlock Text="{x:Bind Title, Mode=OneWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
En
// 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"));
}
...
Ahora compile y ejecute el proyecto. Haga clic en el botón para ejecutar el controlador de eventos Click. Hemos visto que la implementación de Append genera un evento para que la interfaz de usuario sepa que la colección ha cambiado; y el ListBox vuelve a consultar la colección para actualizar el valor de sus propios Items. Igual que antes, el título de uno de los libros cambia; y ese cambio de título se refleja en el botón y en el cuadro de lista.