Windows ランタイムアプリの特定のパネルには、画面に表示されている領域だけ UI 項目を生成したり使いまわしたりして、使用メモリの削減やスクロール動作を高速化する「仮想化」という仕組みが用意されています
次の GridView は ItemsPanel(ItemsContainer を並べていくパネル) に StackPanel を指定しています
<GridView x:Name="gridView" Grid.Row="1"> <GridView.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.ItemTemplate> <DataTemplate> <Image Margin="0,0,70,0" Source="Assets/cat_was_seen.jpg" /> </DataTemplate> </GridView.ItemTemplate> </GridView>
StackPanel には仮想化の仕組みがないため、ItemsSource に設定したデータの件数だけ、ItemsContainer (とその内部の Image コントロール)を生成しようとします
一方、次の GridView は ItemsPanel に ItemsStackPanel を指定しています
<GridView x:Name="gridView" Grid.Row="1"> <GridView.ItemsPanel> <ItemsPanelTemplate> <ItemsStackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.ItemTemplate> <DataTemplate> <Image Margin="0,0,70,0" Source="Assets/cat_was_seen.jpg" /> </DataTemplate> </GridView.ItemTemplate> </GridView>
この場合 ItemsContainer (とその内部の Image コントロール)を画面表示に必要な最小限しか生成せず、使いまわしが行われます
※ ただし、グループ化されたデータを表示する場合、ItemsContainer がグループ内のアイテムを含むため、グループ単位で仮想化されます
仮想化の仕組みが ItemsContainer の削減であるため、
続・Windows ストアアプリで画面遷移前のスクロール位置を記憶するための Behavior を作る - しっぽを追いかけて
で紹介したように、以前は仮想化を利用すると任意のスクロール位置に移動する場合にピクセル数ではなく、アイテムのインデックスを指定しなければなりませんでした
しかし Windows 8.1 になって追加された ItemsStackPanel や ItemsWrapGrid を利用すると仮想化による恩恵を受けながらスクロール位置の指定にピクセル単位での指定ができるようになります
これは使わない手はありませんね!
仕組みだけわかっても効果を実感しづらいので実験してみました
次の動画は 5,000 個の画像を TOSHIBA のタブレット端末で GridView に表示させた場合の動作比較です
StackPanel と ItemsStackPanel の動作比較 - YouTube
仮想化した場合の動作の軽さは明らかですね