2

我将 Pivot 的 ItemsSource 属性设置为 3 个 URL 字符串的列表。

奇怪的事情发生:

  • 使用下面的模板,ImageOpened 事件被调用 6 次而不是 3 次。
  • 如果我将 BitmapImage 的 CreateOptions 设置为“BackgroundCreation”,则可以无缘无故地调用数百次 ImageOpened 事件
  • 如果我将 Pivot 放在 UserControl 中并为 BitmapImage 使用“BackgroundCreation”选项,那么尽管 ImageOpened 事件被调用(数百次),但图像根本不会在 Pivot 内呈现。

同样的行为发生在 WP7 和 WP8 上。我很惊讶,因为我刚刚创建了一个 ImageGallery UserControl,它在下面使用了一个 Pivot,我想利用 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());
}

一开始,当您按下按钮时,您会注意到列表中的第一个图像似乎被加载了两次:

在此处输入图像描述

即使您删除该DelayCreation标志,您仍然会得到相同的结果,因为该标志是默认设置的。

在此处输入图像描述

现在,如果我们使用连接到 ad-hoc 网络的电话 WireShark 检查它会发生什么:

在此处输入图像描述

注意:我在这里使用不同的图片 URL)

该图像仅下载一次,因此您本身无需担心额外的数据。您看到它触发两次的原因似乎是它为源触发一次,而另一个为图像触发。

从技术上讲,如果你这样做,也是一样的:

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());
}

所以不,图像没有下载两次

于 2013-01-11T20:03:02.040 回答