Поделиться через


Элементы управления XAML; привязка к коллекции C++/WinRT

Коллекция, которая может быть эффективно привязана к элементу управления элементами XAML, называется наблюдаемой коллекцией. Эта идея основана на шаблоне проектирования программного обеспечения, известном как шаблон наблюдателя . В этом разделе показано, как реализовать наблюдаемые коллекции в C++/WinRTи как привязать элементы управления элементами XAML к ним (для справочной информации см. Привязка данных).

Если вы хотите следовать этой теме, мы рекомендуем сначала создать проект, описанный в элементах управления XAML, и привязать к свойству C++/WinRT. В этом разделе добавляется дополнительный код в этот проект, и он добавляется к концепциям, описанным в этом разделе.

Это важно

Основные понятия и термины, которые поддерживают ваше понимание использования и разработки классов среды выполнения с помощью C++/WinRT, см. в разделе Использование API с помощью C++/WinRT и Создание API с помощью C++/WinRT.

Что означает наблюдаемые для коллекции?

Если класс среды выполнения, представляющий коллекцию, выбирает вызов события IObservableVector<T>::VectorChanged всякий раз, когда элемент добавляется к нему или удаляется из него, то класс среды выполнения является наблюдаемой коллекцией. Элемент управления элементами XAML может привязываться к этим событиям и обрабатывать их, извлекая обновленную коллекцию, а затем обновляя элемент управления, чтобы отобразить текущие элементы.

Замечание

Для получения информации об установке и использовании расширения Visual Studio C++/WinRT (VSIX) и пакета NuGet (которые вместе обеспечивают поддержку шаблона проекта и сборки), см. подраздел Поддержка Visual Studio для C++/WinRT.

Добавить коллекцию BookSkus в BookstoreViewModel

В элементах управления XAML : привязка к свойству C++/WinRT, мы добавили в основную модель представления свойство типа BookSku. На этом шаге мы будем использовать шаблон функции фабрики winrt::single_threaded_observable_vector, чтобы реализовать наблюдаемую коллекцию BookSku в той же модели представления.

Объявите новое свойство в BookstoreViewModel.idl.

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

Это важно

Привязка к коллекции с помощью C++/WinRT немного более нюансов, чем в C#. В приведенном выше списке MIDL 3.0 обратите внимание, что свойство BookSkus имеет тип IObservableVector из BookSku. В следующем разделе этой темы мы будем привязывать источник элементов ListBox к BookSkus. Поле списка — это элемент управления элементами, и для правильного задания свойства ItemsControl.ItemsSource необходимо задать для него значение типа IObservableVector или IVector или типа взаимодействия, например IBindableObservableVector. {x:Bind} В противном случае будет создано E_INVALIDARG и {Binding} завершится сбоем автоматически.

Предупреждение

Код, показанный в этом разделе, применяется к C++/WinRT версии 2.0.190530.8 или более поздней. Если вы используете более раннюю версию, вам потребуется внести некоторые незначительные изменения в показанный код. В приведенном выше списке MIDL 3.0 измените свойство BookSkus на IObservableVectorIInspectable. А затем используйте IInspectable (вместо BookSku) в реализации.

Сохранение и сборка. Скопируйте заглушки доступа из BookstoreViewModel.h и BookstoreViewModel.cpp в папке \Bookstore\Bookstore\Generated Files\sources (дополнительные сведения см. в предыдущем разделе элементах управления XAML; привязка к свойству C++/WinRT). Реализуйте эти заглушки доступа следующим образом.

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

Привязка listBox к свойству BookSkus

Откройте MainPage.xaml, которая содержит разметку XAML для главной страницы пользовательского интерфейса. Добавьте следующую разметку внутри той же StackPanel, что и кнопка .

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

Введите MainPage.cppстроку кода в обработчик событий Click , чтобы добавить книгу в коллекцию.

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

Теперь создайте и запустите проект. Нажмите кнопку, чтобы выполнить обработчик событий Click. Мы видели, что реализация Append вызывает событие, уведомляющее пользовательский интерфейс о том, что коллекция изменилась, и ListBox повторно запрашивает коллекцию для обновления значения Items. Как и раньше, название одной из книг изменяется; и это изменение заголовка отражается как на кнопке, так и в поле списка.

Важные API