🍱

リストビュー的なコントロールの特徴まとめ(WinUI 3)

に公開

はじめに

WinUI 3 には項目を一覧表示するコントロールが色々あり、違いがよく分からなかったので、分かる範囲で整理してみました。

  • GridView
  • ItemsRepeater
  • ItemsView
  • ListBox
  • ListView

ListView

ListView の基本

ListView は項目群を縦一列に並べて表示するのに便利なコントロールです。

項目 1 つ分の表示方法は ItemTemplate DataTemplate で自由にカスタマイズできます。例えば、名簿で左側に名前、右側に年齢を表示するといったことが可能です。

<ListView ItemsSource="{x:Bind ViewModel.People}" >
	<!-- 項目 1 つ分の表示方法 -->
	<ListView.ItemTemplate >
		<DataTemplate x:DataType="m:Person" >
			<StackPanel Orientation="Horizontal" >
				<TextBlock Text="{x:Bind Name}" />
				<TextBlock Text="{x:Bind Age}" Foreground="Blue" Margin="20,0,0,0" />
			</StackPanel>
		</DataTemplate>
	</ListView.ItemTemplate>
</ListView>

DataTemplate では StackPanelGrid といったレイアウト系のコントロールも使えるので、自由度は高いです。

また、例えば姓の頭文字ごとにグルーピングしてヘッダーを表示することも可能です。詳しくは WinUI 3 Gallery とそのソースコードをご覧ください。

ListView の応用

ListView は実は、項目群を横一列に並べることも可能です。ItemsPanel でカスタマイズします。

<ListView ItemsSource="{x:Bind ViewModel.People}" >
	<!-- 項目群を横一列に表示する -->
	<ListView.ItemsPanel >
		<ItemsPanelTemplate >
			<ItemsStackPanel Orientation="Horizontal" />
		</ItemsPanelTemplate>
	</ListView.ItemsPanel>
</ListView>

また、複数列に並べることも可能です。

<ListView ItemsSource="{x:Bind ViewModel.People}" >
	<!-- 項目群を横 2 列ずつ表示する -->
	<ListView.ItemsPanel >
		<ItemsPanelTemplate >
			<ItemsWrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2" />
		</ItemsPanelTemplate>
	</ListView.ItemsPanel>
</ListView>

項目群の並べ方を ItemsPanel で、項目 1 つ分の並べ方を ItemTemplate でカスタマイズすることにより、全体としてとても自由度の高い表示が可能です。

ListBox

ListBox は項目群を縦一列に並べて表示するのに便利なコントロールです。

公式説明の通り過去のものなので、今後は使う必要はありません。

GridView

GridView は項目群を複数列に並べて表示するのに便利なコントロールです。

GridView と ListView の違いですが、公式説明では「ListView と GridView はどちらも ListViewBase クラスから派生しているため、機能は同じですが、データの表示方法は異なります。」と書かれており、機能は同じであることが明記されています。データの表示方法は異なるというのは、デフォルトで複数列表示となることを指しているものと思われます。

ListView と機能が同じであるなら、わざわざ GridView という別クラスとして用意する必要があったのでしょうか? 設計思想が不可解です。

ItemsView

ItemsView の基本

ItemsView は柔軟なレイアウトシステムを使用して項目群を表示できるコントロールです。

レイアウトは以下が用意されています。

使い方は ListView とほとんど同じです。DataTemplateItemContainer が必要な点には注意が必要です(忘れると例外になります)。

<ItemsView ItemsSource="{x:Bind ViewModel.People}" >
	<!-- 項目群を横 2 列ずつ表示する -->
	<ItemsView.Layout >
		<UniformGridLayout MaximumRowsOrColumns="2" />
	</ItemsView.Layout>
	<!-- 項目 1 つ分の表示方法 -->
	<ItemsView.ItemTemplate >
		<DataTemplate x:DataType="m:Person" >
			<ItemContainer >
				<StackPanel Orientation="Horizontal" >
					<TextBlock Text="{x:Bind Name}" />
					<TextBlock Text="{x:Bind Age}" Foreground="Green" Margin="20,0,0,0" />
				</StackPanel>
			</ItemContainer>
		</DataTemplate>
	</ItemsView.ItemTemplate>
</ItemsView>

ItemsView の利点

ItemsView は Windows App SDK 1.4 になってから導入された後発組で、

  • 項目 Invoking(ダブルクリックでイベント)
  • 実行中のレイアウト変更
  • より良いアニメーション

をサポートしています。

機能的には ListView の上位互換のようです。

ItemsView と ListView の違いは、派生元のクラスです。

  • Control → ItemsView
  • Control → ItemsControl → Selector → ListViewBase → ListView

ItemsView は Control から直接派生しており、Selector 系の機能を独自に実装しているようです。

なぜ ItemsView を ListViewBase から派生させなかったのでしょうか? というかそもそも ItemsView は作らずに ListView やその基底クラスの機能を強化すれば(主に仮想化関係?)、わざわざ別クラスに分けて複雑性を増すこともなかったのではないでしょうか? 設計思想が不可解です。仮想化は WPF の頃からサポートされていたので、Windows App SDK も当然それを見越した設計になっていなければなりません。

ItemsRepeater

ItemsRepeater は少し毛色が異なり、カスタマイズを前提としているクラスです。

基本機能がほぼ無い反面、ゴリゴリに作り込んで独自の表示を行うことができます。

なお、ItemsRepeater は Control よりさらに下の FrameworkElement から直接派生しています。

番外編:DataGrid

DataGrid は Excel のようにデータを行と列で一覧表示できるコントロールです。

ListView などが格子状に項目を配置する場合は同種の項目が縦にも横にも並びますが、DataGrid は 1 行が 1 項目(名簿なら佐藤さんや鈴木さん)、1 列は子項目(名簿なら年齢や住所)というように、行と列で意味が異なります。

Windows App SDK(WinUI 3)には残念ながら DataGrid はありません。

以前は準 Windows App SDK とでもいうべき Windows Community Toolkit に DataGrid がありましたが、最新バージョンでは消えてしまっています。

まとめ

機能的には

ItemsView > ListView = GridView > ListBox

となっているので、今後は ItemsView 一択でいいのではないでしょうか。

ネックになるのはクラス構造でしょうか。同じデータを異なるビューで表示するのはよくあるケースですが、例えば ItemsView と TableView で表示しようと思っても、ItemsView が Selector を挟んでいないので処理を共通化できません。そういうケースでは ListView にするという選択もありかと思います。

確認環境

項目 環境
OS Windows 11 Pro 25H2
Visual Studio 2026 18.0.2
.NET 10.0
Template Studio for WinUI 5.5
WinUIEx 2.9.0
Windows App SDK 1.8.251106002 (1.8.3)

参考リンク

Discussion