GridView と ListView の項目の段階的な更新 (XAML)

Applies to Windows and Windows Phone

ListView または GridView コントロールに多くの項目があり、ユーザーが項目をすばやくスクロールする場合、各項目のコンテンツを完全に表示すると、多くの UI リソースが使われます。そのため、いくらかぎくしゃくした UI エクスペリエンスになります。ユーザーのスクロール速度によっては、多くの新しい項目が一時的に空白または欠落した状態で表示されます。このようになると、ユーザーはまだ項目が残っているのかどうかがわからなくなります。残っている場合は、UI によって新しい項目が完全に表示されるまで待たなければなりません。Windows 8.1 では、プレースホルダー段階的なデータ テンプレート更新を使うことで、この項目表示のエクスペリエンスが向上しています。

プレースホルダー

Windows 8.1 では、多数の項目がある ListView または GridView コントロールをユーザーがすばやくスクロールするときに、UI が項目を完全に表示できるようになるまで、既定では次の項目の一時的なプレースホルダーが表示されます。こうすることで、まだ完全に表示されていない項目があるという視覚的なヒントをユーザーに与えます。こうしたプレースホルダーを使うと、ListView または GridView をユーザーにより速く表示することもできます。

プレースホルダーは、Windows 8.1 で実行される Windows ストア アプリでは、既定で有効になっています。ListView または GridView コントロールの ShowsScrollingPlaceholders プロパティを true に設定して、プレースホルダーを明示的に有効にすることもできます。プレースホルダーを明示的に無効にするには、ListView または GridView コントロールの ShowsScrollingPlaceholders プロパティを false に設定します。

段階的なデータ テンプレート更新

プレースホルダー以外でも、項目の一部を複数の段階で表示できます。たとえば、映画の一覧では、第 1 段階で映画のタイトルを表示できます。その後、第 2 段階で映画の年齢区分を表示できます。第 3 段階では各映画のポスター画像を表示するというようなことができます。各段階でユーザーは各映画の情報をよりすばやく知り、すべての映画の詳細が表示される前に、いずれかの映画を選ぶことができます。

Windows 8.1 は、既定では、項目のどの部分がアプリにとって最重要な最初に表示するべきものであり、どの部分が 2 番目に表示するべきものであるか、といったことを知ることはできません。この動作を設定するには、ListView または GridView コントロールの ContainerContentChanging イベントを使って、各段階で項目のどの部分を表示するかを決定します。段階的なデータ テンプレート更新は、Windows 8.1 をターゲットとしてコンパイルされ、ContainerContentChanging イベントを使うすべての Windows ストア アプリで利用できます。

この動作を確認するには、新しいアプリケーション (XAML) テンプレートに基づく新しい Microsoft Visual C# プロジェクトを作成し、次のコードとマークアップを追加します。

  1. 項目のシミュレートされたセットを表す MyItem という名前のクラスを追加します。

    
    namespace LotsOfItems
    {
        public class MyItem
        {
            public string Title { get; set; }
            public string Subtitle { get; set; }
            public string Description { get; set; }
    
            public MyItem (string title, string subtitle, string description)
            {
                Title = title;
                Subtitle = subtitle;
                Description = description;
            }
        }
    }
    
    
    
  2. グリッド ビューと項目表示テンプレートを表示するために、既定の MainPage.xaml ファイルに XAML (eXtensible Application Markup Language) マークアップを追加します。GridView コントロールの ContainerContentChanging イベントを設定します。項目表示テンプレート コントロールを、TitleSubtitleDescription など、シミュレートされた項目のプロパティにバインドします。

    
    <Page
            x:Class="LotsOfItems.MainPage"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="using:LotsOfItems"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d">
        <Grid>
            <GridView x:Name="myGridView"
                      ItemsSource="{Binding}"
                      Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
                      ContainerContentChanging="MyGridView_ContainerContentChanging">           
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Height="100" 
                                    Width="100" 
                                    Background="Blue">
                            <Rectangle x:Name="placeholderRectangle" 
                                       Fill="Red" 
                                       Opacity="0"/>
                            <TextBlock x:Name="titleTextBlock" 
                                       Text="{Binding Title}" 
                                       Foreground="Yellow"/>
                            <TextBlock x:Name="subtitleTextBlock" 
                                       Text="{Binding Subtitle}" 
                                       Foreground="Aqua"/>
                            <TextBlock x:Name="descriptionTextBlock" 
                                       Text="{Binding Description}" 
                                       Foreground="Gray"/>
                        </StackPanel>
                    </DataTemplate>
                </GridView.ItemTemplate>
            </GridView>
        </Grid>   
    </Page>
    
    
    
  3. 既定の MainPage.xaml.cs ファイルにコードを追加して、シミュレートされた項目のセットを作ります。GridView コントロールを項目の一覧に接続し、ユーザーがグリッド ビューですばやくスクロールしたときに GridView コントロールの ContainerContentChanging イベントに応答します。

    
    using System;
    using System.Collections.Generic;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Xaml.Shapes;
    
    namespace LotsOfItems
    {
        public sealed partial class MainPage : Page
        {
            List<MyItem> myItems = new List<MyItem>(); 
    
            public MainPage()
            {
                CreateTestItems();
                this.InitializeComponent();
            }
    
            // Create a simulated list of 150,000 items.
            void CreateTestItems()
            {
                for (int i = 1; i < 150000; i++)
                {
                    myItems.Add(new MyItem(
                        "Title:" + i.ToString(), // Title.
                        "Sub:" + i.ToString(), // Subtitle.
                        "Desc:" + i.ToString())); // Description.                            
                }
            }
    
            // Connect the grid view to the list of items.
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                myGridView.ItemsSource = myItems;            
            }
    
            // Display each item incrementally to improve performance.
            private void MyGridView_ContainerContentChanging(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                args.Handled = true;
    
                if (args.Phase != 0)
                {
                    throw new Exception("Not in phase 0.");
                }
    
                // First, show the items' placeholders.
                StackPanel templateRoot = 
                    (StackPanel)args.ItemContainer.ContentTemplateRoot;
                Rectangle placeholderRectangle = 
                    (Rectangle)templateRoot.FindName("placeholderRectangle");
                TextBlock titleTextBlock = 
                    (TextBlock)templateRoot.FindName("titleTextBlock");
                TextBlock subtitleTextBlock =
                    (TextBlock)templateRoot.FindName("subtitleTextBlock");
                TextBlock descriptionTextBlock =
                    (TextBlock)templateRoot.FindName("descriptionTextBlock");
    
                // Make the placeholder rectangle opaque.
                placeholderRectangle.Opacity = 1;
    
                // Make everything else invisible.
                titleTextBlock.Opacity = 0;
                subtitleTextBlock.Opacity = 0;
                descriptionTextBlock.Opacity = 0;
    
                // Show the items' titles in the next phase.
                args.RegisterUpdateCallback(ShowTitle);
            } 
           
            // Show the items' titles.
            private void ShowTitle(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                if (args.Phase != 1)
                {
                    throw new Exception("Not in phase 1.");
                }
    
                // Next, show the items' titles. Keep everything else invisible.
                MyItem myItem = (MyItem)args.Item;
                SelectorItem itemContainer = 
                    (SelectorItem)args.ItemContainer;
                StackPanel templateRoot = 
                    (StackPanel)itemContainer.ContentTemplateRoot;
                TextBlock titleTextBlock = 
                    (TextBlock)templateRoot.FindName("titleTextBlock");
    
                titleTextBlock.Text = myItem.Title;
                titleTextBlock.Opacity = 1;
                
                // Show the items' subtitles in the next phase.
                args.RegisterUpdateCallback(ShowSubtitle);
            }
    
            // Show the items' subtitles.
            private void ShowSubtitle(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                if (args.Phase != 2)
                {
                    throw new Exception("Not in phase 2.");
                }
    
                // Next, show the items' subtitles. Keep everything else invisible.
                MyItem myItem = (MyItem)args.Item;
                SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
    
                StackPanel templateRoot = 
                    (StackPanel)itemContainer.ContentTemplateRoot;
                TextBlock subtitleTextBlock = 
                    (TextBlock)templateRoot.FindName("subtitleTextBlock");
    
                subtitleTextBlock.Text = myItem.Subtitle;
                subtitleTextBlock.Opacity = 1;
    
                // Show the items' descriptions in the next phase.
                args.RegisterUpdateCallback(ShowDescription);
            }
    
            // Show the items' descriptions.
            private void ShowDescription(
                    ListViewBase sender, 
                    ContainerContentChangingEventArgs args)
            {
                if (args.Phase != 3)
                {
                    throw new Exception("Not in phase 3.");
                }
    
                // Finally, show the items' descriptions. 
                MyItem myItem = (MyItem)args.Item;
                SelectorItem itemContainer = (SelectorItem)args.ItemContainer;
    
                StackPanel templateRoot = 
                    (StackPanel)itemContainer.ContentTemplateRoot;
                Rectangle placeholderRectangle = 
                    (Rectangle)templateRoot.FindName("placeholderRectangle");
                TextBlock descriptionTextBlock =
                    (TextBlock)templateRoot.FindName("descriptionTextBlock");
    
                descriptionTextBlock.Text = myItem.Description;
                descriptionTextBlock.Opacity = 1;
    
                // Make the placeholder rectangle invisible.
                placeholderRectangle.Opacity = 0;
            }
        }
    }
    
    
    
  4. アプリを実行します。グリッド ビューですばやくスクロールします。新しい項目が画面に表示されるときに、最初に項目のタイトル、次にサブタイトル、次に説明が表示されることに注意してください。
  ContainerContentChanging イベントの呼び出し方を示すその他のコードについては、XAML ListViewGridView の基本項目のサンプルのページをご覧ください。

関連トピック

大きなデータ セットの効率的な読み込み、格納、表示
GridView と ListView コントロールがあるアプリの起動時間の短縮

 

 

表示:
© 2015 Microsoft