YouTube Data APIで取得したデータをWPFのリストで表示する その2

宣言通り、ItemsControlとListViewについて。

前回、ListBoxを使って動的に項目を並べることをやりましたが、ListBoxはあくまでListBoxなわけで並んだ項目はListBoxItemの中にあり、ListBoxItemが選択できます。別に選択する必要もなく、ただ単に画像を並べたいということもあると思います。そのやり方に少し悩みました。StackPanelのChildrenにコードで追加すればできるのですが、ListBoxに配列をBindしたようにスマートにやりたいものです。

ItemsControlでそれができると知りました。ListBoxやListViewの継承関係は下記のようになっています。

System.Object
System.Windows.Threading.DispatcherObject
System.Windows.DependencyObject
System.Windows.Media.Visual
System.Windows.UIElement
System.Windows.FrameworkElement
System.Windows.Controls.Control
System.Windows.Controls.ItemsControl
System.Windows.Controls.Primitives.Selector
System.Windows.Controls.ListBox
System.Windows.Controls.ListView

ItemsControlには項目の配列を並べることが選択機能なしにできるので単に項目を並べるときに使えました。ListBoxのXAMLを書いたときに値を変更したItemsSource、ItemTemplate, ItemsControl.ItemTemplateなどはまさにItemsControlのものなのでListBoxのXAMLをそのまま流用できます。(その逆もしかり)

<ItemsControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Source={StaticResource VideoItemCollection}}" ItemTemplate="{StaticResource VideoOnItemsControl}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" ItemHeight="100" ItemWidth="100"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>

またListViewでも同じようにXAMLが書けます。ListViewのReport形式の表示をGridViewつかって表示してみます。

<ListView Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Source={StaticResource VideoItemCollection}}" ItemTemplate="{StaticResource VideoOnItemsControl}">
<ListView.View>
<GridView ScrollViewer.VerticalScrollBarVisibility="Visible">
<GridViewColumn Header="Thumbnail">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Thumbnail}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Author">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Author}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>

こんな感じで、GridViewでもカラムの中でどういうコントロールで表示するかをGridViewColumn.CellTemplateを使って表現できます。

同じCollectoinデータをListBox, ItemsControl, ListViewに設定して並べて表示してみました。

WPFYouTube200805240.jpg

最終的なXAMLは以下の通りです。

このサンプルプログラム(VS2008)は
WPFYouTube.zipからダウンロードできます
<Window x:Class="WPFYouTube.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:me="clr-namespace:WPFYouTube"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<CollectionViewSource Source="{DynamicResource VideoItems}" x:Key="VideoItemCollection"/>
<DataTemplate x:Key="VideoOnItemsControl">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Title}"/>
<Image Source="{Binding Path=Thumbnail}"/>
<TextBlock Text="{Binding Path=Author}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="200"/>
<RowDefinition Height="200"/>
<RowDefinition Height="200"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" x:Name="tbxKeyword" Text="ドラゴンボール"/>
<Button Grid.Row="0" Grid.Column="1" Content="Search" Click="Button_Click"/>
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Source={StaticResource VideoItemCollection}}" ItemTemplate="{StaticResource VideoOnItemsControl}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" ScrollViewer.VerticalScrollBarVisibility="Visible"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>
<ItemsControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Source={StaticResource VideoItemCollection}}" ItemTemplate="{StaticResource VideoOnItemsControl}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" ItemHeight="100" ItemWidth="100"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<ListView Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Source={StaticResource VideoItemCollection}}" ItemTemplate="{StaticResource VideoOnItemsControl}">
<ListView.View>
<GridView ScrollViewer.VerticalScrollBarVisibility="Visible">
<GridViewColumn Header="Thumbnail">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Thumbnail}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Title}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Author">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Author}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>