2

ピボットの ItemsSource プロパティを 3 つの URL 文字列のリストに設定しました。

奇妙なことが起こります:

  • 以下のテンプレートでは、ImageOpened イベントが 3 回ではなく 6 回呼び出されます。
  • BitmapImage の CreateOptions を 'BackgroundCreation' に設定すると、ImageOpened イベントが明確な理由もなく何百回も呼び出される可能性があります。
  • ピボットを UserControl 内に配置し、BitmapImage に「BackgroundCreation」オプションを使用すると、ImageOpened イベントが呼び出されても (何百回も)、イメージはピボット内でまったくレンダリングされません。

WP7 と WP8 で同じ動作が発生します。下でピボットを使用している ImageGallery UserControl を作成したばかりで、BackgroundCreation オプションを使用してデコード作業をバックグラウンド スレッドにオフロードしたかったので、私は非常に驚いていますが、そのような症状ではまったく無意味に思えます :(.

1) ピボット

<phone:PhoneApplicationPage 
    x:Class="WP7.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: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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <Button Tap="UIElement_OnTap">press</Button>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <controls:Pivot x:Name="gallery">
                <controls:Pivot.ItemTemplate>
                    <DataTemplate>
                        <Image>
                            <Image.Source>
                                <BitmapImage ImageOpened="BitmapImage_OnImageOpened" ImageFailed="BitmapImage_OnImageFailed" UriSource="{Binding}" CreateOptions="DelayCreation"></BitmapImage>
                            </Image.Source>
                        </Image>
                    </DataTemplate>
                </controls:Pivot.ItemTemplate>
            </controls:Pivot>

        </Grid> 
    </Grid>

2) コードビハインド

 public partial class MainPage : PhoneApplicationPage
    {
        int c = 0;
        List<string> list = new List<string>()
                             {
                            "http://d24w6bsrhbeh9d.cloudfront.net/photo/6298284_460s.jpg", "http://d24w6bsrhbeh9d.cloudfront.net/photo/6291760_460s.jpg", "http://d24w6bsrhbeh9d.cloudfront.net/photo/6298282_460s.jpg",  
                             }; 
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        private void UIElement_OnTap(object sender, GestureEventArgs e)
        {
            c = 0;
            gallery.ItemsSource = list;

        }

        private void BitmapImage_OnImageOpened(object sender, RoutedEventArgs e)
        {
            c++;
            Debug.WriteLine("opened - {0}", c);
        }

        private void BitmapImage_OnImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            Debug.WriteLine("failed");
        }
    }
4

1 に答える 1

1

何が起こっているのかをよりよく理解するために、次のスニペットを確認できます。

private void BitmapImage_OnImageOpened(object sender, RoutedEventArgs e)
{
    BitmapImage image = (BitmapImage)sender;

    Debug.WriteLine("opened - {0}", image.UriSource.ToString());
}

最初にボタンを押すと、リストの最初の画像が 2 回読み込まれているように見えることに気付くでしょう。

ここに画像の説明を入力

DelayCreationこのフラグはデフォルトで設定されているため、フラグを削除しても同じ結果が得られます。

ここに画像の説明を入力

これを、アドホック ネットワークに接続された電話である WireShark で調べるとどうなるでしょうか。

ここに画像の説明を入力

(注:ここでは別の画像 URL を使用しています)

イメージは 1 回だけダウンロードされるので、余分なデータについて心配する必要はありません。2 回トリガーされる理由は、ソースに対して 1 回トリガーされ、画像に対してもう 1 回トリガーされるという事実のようです。

技術的には、これを行う場合と同じです:

List<BitmapImage> list = new List<BitmapImage>();

// Constructor
public MainPage()
{
    InitializeComponent();

    BitmapImage image = new BitmapImage();
    image.UriSource = new Uri("http://timenerdworld.files.wordpress.com/2012/08/new-microsoft-logo.jpg");
    image.ImageOpened += image_ImageOpened;

    list.Add(image);
}

void image_ImageOpened(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("opened image from bitmap");
}

private void UIElement_OnTap(object sender, GestureEventArgs e)
{
    gallery.ItemsSource = list;
}

private void BitmapImage_OnImageOpened(object sender, RoutedEventArgs e)
{
    Image image = (Image)sender;

    Debug.WriteLine("opened - {0}", ((BitmapImage)image.Source).UriSource.ToString());
}

いいえ、画像は 2 回ダウンロードされません

于 2013-01-11T20:03:02.040 に答える