XAML 項目コントロールに効果的にバインドできるコレクションは、監視可能な コレクションと呼ばれます。 このアイデアは、オブザーバーパターンと呼ばれるソフトウェア設計パターンに基づいています。 このトピックでは、C++/WinRTで監視可能なコレクションを実装する方法と、XAML 項目コントロールをそれらにバインドする方法について説明します (背景情報については、「データ バインディングのを参照してください)。
このトピックに従う場合は、最初に XAML コントロールで説明されているプロジェクト 作成することをお勧めします。C++/WinRT プロパティにバインドします。 このトピックでは、そのプロジェクトにさらにコードを追加し、そのトピックで説明する概念を追加します。
Von Bedeutung
C++/WinRT を使用してランタイム クラスを使用および作成する方法の理解をサポートする基本的な概念と用語については、「C++/WinRT で API を使用する
コレクションにおける オブザーバブルな とはどういう意味ですか?
コレクションを表すランタイム クラスが、要素が追加または削除されるたびに、IObservableVector<T>::VectorChanged イベントを発生させる場合、ランタイム クラスは監視可能なコレクションです。 XAML 項目コントロールは、更新されたコレクションを取得し、現在の要素を表示するようにそれ自体を更新することで、これらのイベントにバインドして処理できます。
注
C++/WinRT Visual Studio 拡張機能 (VSIX) と NuGet パッケージ (プロジェクト テンプレートとビルド サポートを提供) のインストールと使用については、Visual Studio での C++/WinRTのサポート
BookstoreViewModel に BookSkus コレクション 追加する
BookstoreViewModel.idl
で新しいプロパティを宣言します。
// BookstoreViewModel.idl
...
runtimeclass BookstoreViewModel
{
BookSku BookSku{ get; };
Windows.Foundation.Collections.IObservableVector<BookSku> BookSkus{ get; };
}
...
Von Bedeutung
C++/WinRT を使用したコレクションへのバインドは、C# の場合よりも少し微妙です。 上記の MIDL 3.0 の一覧で、{x:Bind}
は E_INVALIDARGを生成し、 {Binding}
は警告なしに失敗します。
Warnung
このトピックで示すコードは、C++/WinRT バージョン 2.0.190530.8 以降に適用されます。 以前のバージョンを使用している場合は、表示されるコードを少し調整する必要があります。 上記の MIDL 3.0 の一覧で、BookSkus プロパティを IObservableVector の IInspectableに変更します。 次に、実装で 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 プロパティにバインドする
メイン UI ページの XAML マークアップを含む MainPage.xaml
を開きます。
Buttonと同じ 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 の実装では、コレクションが変更されたことを UI に通知するイベントが発生することがわかります。ListBox コレクションを再クエリして、独自の Items 値を更新します。 前と同じように、本のタイトルが変わります。ボタンとリスト ボックスの両方にタイトルの変更が反映されます。
重要な API
関連トピック
- C++/WinRT で API を消費する
- C++/WinRT を使用して API を作成する