WP8 LongListSelector中的自动高度图像

时间:2013-09-15 16:28:38

标签: c# xaml windows-phone-8

我正在使用LongListSelector在Windows Phone 8上的XAML和C#中进行无限滚动。要显示的项目从Web订阅源加载并使用数据绑定显示,每个项目的一个字段是也从Web加载的图像。

图像尺寸各不相同,但我没有在图像控制中设置宽度或高度,只是Margin="10",因此它填充了屏幕的宽度,并且是图像的正确高度。 / p>

DataTemplate中的图像控件如下所示:

<Image Source="{Binding Source.ImageUrl}" Margin="10" Stretch="UniformToFill" />

但是,我得到一个System.Windows.LayoutCycleException,上面写着:“检测到布局周期。布局无法完成​​。”。

这似乎是由于在下载图像之前将<Image>控件放入LongListSelector这一事实。然后,下载图像后,<Image>控件会调整大小,从而导致错误。如果我在Height="300"控件上设置了<Image>,我就不会得到例外。

我仍然希望在下载图像之前显示Feed,并且可能在Feed中有很多图像,因此需要在内存使用时高效。

这个问题有解决方案吗?

1 个答案:

答案 0 :(得分:1)

应该使用Uniform来填充宽度而不是UniformToFill(因为填充的均匀性将尝试填充“高度”,因为没有定义高度我可以看到它在物品被回收时导致问题)

也许您可以尝试限制同时加载的图像数量,例如,以下代码将使用atached属性一次加载一个(您可以适应加载多个)。对于AsyncLock,您可以使用here中的代码(或在线搜索)

public static readonly DependencyProperty LimitedImageProperty =             DependencyProperty.RegisterAttached(“LimitedImage”,typeof(string),typeof(LimitImageDownloadConverter),new PropertyMetadata(default(string),LimitedImagedChanged));

    public static void SetLimitedImage(UIElement element, string value)
    {
        element.SetValue(LimitedImageProperty, value);
    }

    public static string GetLimitedImage(UIElement element)
    {
        return (string) element.GetValue(LimitedImageProperty);
    }


    AsyncLock imageLock = new AsyncLock();

    private static async void LimitedImagedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Image currentImage = d as Image;
        object dataContext = currentImage.DataContext;
        string uri = e.NewValue as string;
        if (string.IsNullOrEmpty(uri))
        {
            return;
        }

            using (await imageLock.AcquireLock())
            {
                if (currentImage.DataContext != dataContext)
                {
                    //Item jhave been recycled
                    return;
                }
                await LoadImage(currentImage, uri);
            }
    }




    private static Task<bool> LoadImage(Image image, string uri)
    {
        TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
        BitmapImage bitmap = new BitmapImage(new Uri(uri));
        bitmap.ImageOpened += (send, arg) =>
        {

            tcs.SetResult(true);
        };
        bitmap.ImageFailed += (send, arg) =>
        {

            tcs.SetResult(false);
        };
        return tcs.Task;
    }

然后只需使用local:MyAttatchedProperty.LimitedImage在图片上设置图片来源,而不是直接使用ImageSource。