WinUI 3で一覧画面を作るとき、最初に思い浮かぶのはListViewかもしれません。選択、キーボード操作、スクロールなどが最初から用意されており、多くの業務アプリでは十分です。一方で、カードを自由に並べたい、独自のコレクションUIを作りたい、表示要素を必要な分だけ生成して大量データを扱いたい、といった場面ではItemsRepeaterが有力な選択肢になります。
今回はItemsRepeaterを「ListViewより新しい一覧コントロール」として紹介するのではなく、両者の役割の違い、UI仮想化の考え方、ObservableCollection<T>を使った更新、StackLayoutとUniformGridLayoutの使い分け、仮想化環境でのライフサイクルまで整理します。
ItemsRepeaterは「完成したリスト」ではなく、データ駆動のパネル
Microsoft Learnでは、ItemsRepeaterはListViewのような完成されたエンドユーザー向けコントロールではなく、カスタムなコレクション体験を作るためのビルディングブロックとして説明されています。標準の選択機能、フォーカス制御、キーボード操作などのポリシーを持ちません。
この違いは重要です。メール一覧のように「行を選択する」ことが中心ならListViewが自然です。逆に、ダッシュボードのカード一覧、検索結果の独自レイアウト、タグやサムネイルを並べる画面など、選択よりも「どう並べて見せるか」を細かく設計したい場合はItemsRepeaterが扱いやすくなります。
さらにItemsRepeaterは仮想化レイアウトを利用できます。画面外を含むすべてのデータについて重いUI要素を常時作るのではなく、表示に必要な範囲を中心にUI要素を実体化し、再利用します。大量データで重要なのは、データ件数だけでなく「同時に存在するUI要素を増やしすぎない」ことです。
まずは縦方向の一覧を作る
次は商品一覧を想定した最小構成です。ItemsRepeater自身にはスクロール機能がないため、ScrollViewerで囲みます。
<ScrollViewer>
<ItemsRepeater ItemsSource="{x:Bind Items, Mode=OneWay}">
<ItemsRepeater.Layout>
<StackLayout Spacing="8" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="local:ProductItem">
<Border Padding="12"
CornerRadius="8"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Spacing="4">
<TextBlock Text="{x:Bind Name}"
FontWeight="SemiBold" />
<TextBlock Text="{x:Bind Category}"
Opacity="0.7" />
</StackPanel>
<TextBlock Grid.Column="1"
Text="{x:Bind PriceText}"
VerticalAlignment="Center" />
</Grid>
</Border>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</ScrollViewer>
C#側では、変更通知を持つコレクションを公開します。
using System.Collections.ObjectModel;
public sealed partial class MainWindow : Window
{
public ObservableCollection<ProductItem> Items { get; } = new();
public MainWindow()
{
InitializeComponent();
Items.Add(new ProductItem("キーボード", "周辺機器", "¥12,800"));
Items.Add(new ProductItem("マウス", "周辺機器", "¥6,980"));
Items.Add(new ProductItem("モニター", "ディスプレイ", "¥39,800"));
}
}
public record ProductItem(
string Name,
string Category,
string PriceText);
コードのポイントを分解する
ItemsSourceには表示対象のコレクションを渡します。Microsoft Learnでは最低限IEnumerableを利用できますが、コレクションの追加・削除をUIへ反映したい場合はINotifyCollectionChangedの利用が推奨されています。.NETのObservableCollection<T>はこの通知を実装しているため、WinUI 3の動的な一覧で扱いやすい選択肢です。
DataTemplateにはx:DataTypeを指定しています。前回扱ったx:Bindと同じく、テンプレート内で型付きのバインディングを利用でき、プロパティ名の誤りをコンパイル時に発見しやすくなります。
StackLayoutは項目を一方向へ並べるレイアウトです。この例では既定の縦方向へ並べ、Spacingで項目間隔を設定しています。ItemsRepeaterはListViewと違って、DataTemplateから作られた要素を既定のListViewItemで包みません。そのため、余白、背景、選択表現など必要な見た目はテンプレート側で明示します。
カード一覧ならUniformGridLayoutへ差し替える
ItemsRepeaterの強みは、データやテンプレートを大きく変えずにレイアウトを交換できることです。カードを折り返して表示したい場合はUniformGridLayoutを利用できます。
<ItemsRepeater.Layout>
<UniformGridLayout
MinItemWidth="240"
MinColumnSpacing="12"
MinRowSpacing="12"
ItemsStretch="Fill" />
</ItemsRepeater.Layout>
MinItemWidthは項目幅の基準、MinColumnSpacingとMinRowSpacingは列・行の最小間隔です。ItemsStretch="Fill"を指定すると、行に残ったスペースを項目幅へ配分できます。ウィンドウ幅に応じてカード数が変わる画面を作るときに便利です。
ここでGridへ大量の要素を自前で追加する方式との違いが出ます。ItemsRepeaterと対応するLayoutはUI仮想化を前提に設計されており、コレクション表示のための仕組みを利用できます。Microsoft Learnでも、ItemsControlには仮想化レイアウトのサポートがないため、カスタムなコレクション表示ではItemsRepeaterを推奨しています。
仮想化ではLoaded / Unloadedだけを頼りにしない
大量データ対応で初心者が見落としやすいのが、UI要素が再利用されることです。画面外へ出た項目の要素が破棄され、次の項目用として新しく作られるとは限りません。リサイクルキューへ送られ、別のデータを表示するために再利用される場合があります。
そのためMicrosoftは、ItemsRepeaterの仮想化環境ではLoadedとUnloadedだけに依存せず、ElementPrepared、ElementClearing、ElementIndexChangedを利用するよう案内しています。
たとえば項目が表示されたときに画像読み込みや監視処理を開始し、表示対象から外れたときに解除したい場合は、ElementPreparedとElementClearingの組み合わせを検討します。UI要素に「この要素はずっと同じ商品を表す」という前提で状態を持たせると、再利用時に以前の状態が残る原因になります。
ListViewとItemsRepeater、どちらを選ぶべきか
判断基準はパフォーマンスだけではありません。ListViewには選択、フォーカス、キーボード操作、項目コンテナーなど、一般的なリストに必要な機能が用意されています。通常の設定一覧、検索結果、メッセージ一覧などは、まずListViewを検討する方が実装量を抑えられます。
ItemsRepeaterは、そうした標準ポリシーを外してレイアウトと表示を自分で組み立てたいときに向いています。自由度と引き換えに、選択やアクセシビリティ、キーボード操作が必要なら開発者側で設計する責任が増えます。「軽そうだから全部ItemsRepeater」ではなく、必要なユーザー体験から選ぶことが大切です。
実務での使いどころ
たとえば管理アプリのホーム画面で、サーバーやジョブの状態をカードとして数百件表示する場合があります。選択操作が主役ではなく、ウィンドウ幅に応じてカードを折り返したいならItemsRepeaterとUniformGridLayoutの組み合わせが候補になります。
一方、顧客一覧から1件を選んで編集画面へ進むようなUIならListViewの方が自然です。さらに表形式で複数列を見せたい場合は、ListViewを無理に表へ寄せるのではなくDataGridなど別の選択肢を検討します。コントロール選択では「データが一覧だから」ではなく、「ユーザーが一覧で何をするのか」を先に考えると設計がぶれにくくなります。
注意点・制約
ItemsRepeater単体にはスクロールがありません。必要ならScrollViewerで囲みます。また、選択機能や既定の選択表示もありません。ListViewItemをDataTemplateへ入れれば見た目を似せることはできますが、それだけでListViewの選択機能が自動的に付くわけではありません。
データソースにも注意が必要です。通常のList<T>をItemsSourceへ設定した後で要素を追加しても、INotifyCollectionChangedがなければ変更はUIへ通知されません。動的な一覧ではObservableCollectionなど、変更通知を持つコレクションを使います。
この記事のコードはWinUI 3 / Windows App SDKのItemsRepeaterを前提に、Microsoft Learnの2026年7月更新内容を確認して構成しています。なお、2026年10月2日時点ではWindows App SDKのリリース系列が複数存在するため、導入時はプロジェクトが参照するWindows App SDKのリリースノートも確認してください。
まとめ
ItemsRepeaterは「ListViewの軽量版」ではなく、仮想化と柔軟なレイアウトを使って独自のコレクションUIを組み立てるための部品です。標準的な選択付き一覧ならListView、独自レイアウトを細かく作りたいならItemsRepeater、と役割から選ぶと分かりやすくなります。
特に覚えておきたいのは、ItemsRepeaterにはスクロールや選択のポリシーがないこと、動的なデータには変更通知が必要なこと、仮想化された要素は再利用されることです。この3点を理解しておけば、大量データの表示でも「とりあえず全部UIに並べる」設計から一歩進めます。
参考資料
- Microsoft Learn – ItemsRepeater
- Microsoft Learn – ListView and GridView
- GitHub – Microsoft Windows App SDK Releases
コメント