【问题标题】:Auto height images in WP8 LongListSelectorWP8 LongListSelector 中的自动高度图像
【发布时间】:2013-09-15 16:28:38
【问题描述】:

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

图片大小不一,但我没有在图片控件上设置宽度或高度,只是Margin="10",这样它就可以填满屏幕的宽度,并且是图片的正确高度。

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

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

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

这似乎是因为&lt;Image&gt; 控件在图像下载之前被放置到 LongListSelector 中。然后,一旦下载了图像,&lt;Image&gt; 控件就会调整大小,从而导致错误。如果我在&lt;Image&gt; 控件上设置Height="300",则不会出现异常。

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

有没有办法解决这个问题?

【问题讨论】:

  • 也有这个问题!默认设置width属性解决了这个问题,但我也想知道我们如何使用未定义的图像!

标签: c# xaml windows-phone-8


【解决方案1】:

应该使用 Uniform 来填充宽度而不是 UniformToFill(因为要填充的 uniform 会尝试填充“高度”,并且由于没有定义高度,我可以看到它在回收项目时会导致问题)

也许您可以尝试限制同时加载的图像数量,例如以下代码将使用附加属性一次加载一个(您可以适应加载多个)。对于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。

【讨论】:

  • 我想这更有意义,但将其设置为 Uniform 仍然会给出相同的异常。
猜你喜欢
  • 2014-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
  • 2013-11-15
相关资源
最近更新 更多