locked
PivotItemのコンテンツのオンデマンド読み込みについて RRS feed

  • 質問

  • 現在、PivotページでPivotItemの変異時にそのページのコンテンツを読み込むプログラムの作成を行っています。

    また、コンテンツの読み込みはそのページが最初に変異したときのみに行いたいと思っています。

    最初はPivotItemごとにLoadedイベントを作成してみたのですがどうもこれだと思い通りにいきません。

    また、SelectedChangedイベントだとページ変異する度に読み込みが行われてしまうためこちらも思い通りの処理ではありません。

    どなたか助言かヒントなどを教えてください。

    何卒よろしくお願いします

    • 移動 Mike Wang (MSCS) 2012年10月2日 11:11 (移動元:Windows Phone 7 向けの開発)
    2012年9月13日 13:37

回答

  • >> また、コンテンツの読み込みはそのページが最初に変異したときのみに行いたいと思っています。

    多分『遷移』の事ですよね? その前提でお答えします。

    >> また、SelectedChangedイベントだとページ変異する度に読み込みが行われてしまうためこちらも思い通りの処理ではありません。

    各ページ(PivotItem)の初回遷移時のみコンテンツ格納を行いたい、ということであれば、SelectionChangedイベントで処理する方向で概ね正しいと思います。
    ViewModelの構成等にもよるのでどう実装すべきかは一概には言えないのですが、とりあえず
    ・PivotItemはXaml側に固定で記述
    ・各PivotItemの初回選択時のみContentに中身を格納
    という前提で組んだのか下記のコードです

    <phone:PhoneApplicationPage 
        x:Class="PivotApp1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 
        d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait"  Orientation="Portrait"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <controls:Pivot Title="マイ アプリケーション" SelectionChanged="Pivot_SelectionChanged">
                <controls:PivotItem Name="pivotItem1" Header="赤" />
                <controls:PivotItem Name="pivotItem2" Header="青" />
                <controls:PivotItem Name="pivotItem3" Header="緑" />
            </controls:Pivot>
        </Grid>
    </phone:PhoneApplicationPage>

        public partial class MainPage : PhoneApplicationPage
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (e.AddedItems.Count == 0) return;
    
                PivotItem item = (PivotItem)e.AddedItems[0];
                if (item.Content == null)
                {
                    switch (item.Name)
                    {
                        case "pivotItem1":
                            item.Content = new Border { Background = new SolidColorBrush(Colors.Red) };
                            break;
    
                        case "pivotItem2":
                            item.Content = new Border { Background = new SolidColorBrush(Colors.Blue) };
                            break;
    
                        case "pivotItem3":
                            item.Content = new Border { Background = new SolidColorBrush(Colors.Green) };
                            break;
                    }
                }
            }
        }
    

    SelectionChangedのEventArgsには、今回新たに選択されたItem(AddItems)が添付されているので、そのContentがまだNullの場合=初回選択時のみコンテンツ格納の処理を行っています。
    また、Pivot.ItemsSourceにViewModelのリストをBindingして、動的にページを生成している場合でも似たような感じで対応できるハズです。
    • 回答としてマーク S.KOSUKE 2012年9月17日 13:38
    2012年9月16日 8:08

すべての返信

  • >> また、コンテンツの読み込みはそのページが最初に変異したときのみに行いたいと思っています。

    多分『遷移』の事ですよね? その前提でお答えします。

    >> また、SelectedChangedイベントだとページ変異する度に読み込みが行われてしまうためこちらも思い通りの処理ではありません。

    各ページ(PivotItem)の初回遷移時のみコンテンツ格納を行いたい、ということであれば、SelectionChangedイベントで処理する方向で概ね正しいと思います。
    ViewModelの構成等にもよるのでどう実装すべきかは一概には言えないのですが、とりあえず
    ・PivotItemはXaml側に固定で記述
    ・各PivotItemの初回選択時のみContentに中身を格納
    という前提で組んだのか下記のコードです

    <phone:PhoneApplicationPage 
        x:Class="PivotApp1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 
        d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait"  Orientation="Portrait"
        shell:SystemTray.IsVisible="True">
    
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <controls:Pivot Title="マイ アプリケーション" SelectionChanged="Pivot_SelectionChanged">
                <controls:PivotItem Name="pivotItem1" Header="赤" />
                <controls:PivotItem Name="pivotItem2" Header="青" />
                <controls:PivotItem Name="pivotItem3" Header="緑" />
            </controls:Pivot>
        </Grid>
    </phone:PhoneApplicationPage>

        public partial class MainPage : PhoneApplicationPage
        {
            public MainPage()
            {
                InitializeComponent();
            }
    
            private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (e.AddedItems.Count == 0) return;
    
                PivotItem item = (PivotItem)e.AddedItems[0];
                if (item.Content == null)
                {
                    switch (item.Name)
                    {
                        case "pivotItem1":
                            item.Content = new Border { Background = new SolidColorBrush(Colors.Red) };
                            break;
    
                        case "pivotItem2":
                            item.Content = new Border { Background = new SolidColorBrush(Colors.Blue) };
                            break;
    
                        case "pivotItem3":
                            item.Content = new Border { Background = new SolidColorBrush(Colors.Green) };
                            break;
                    }
                }
            }
        }
    

    SelectionChangedのEventArgsには、今回新たに選択されたItem(AddItems)が添付されているので、そのContentがまだNullの場合=初回選択時のみコンテンツ格納の処理を行っています。
    また、Pivot.ItemsSourceにViewModelのリストをBindingして、動的にページを生成している場合でも似たような感じで対応できるハズです。
    • 回答としてマーク S.KOSUKE 2012年9月17日 13:38
    2012年9月16日 8:08
  • 回答していただきありがとうございました。

    載せたかった処理を実装することができました。

    2012年9月17日 13:39