3

我有一个枢轴视图,有 6 个枢轴项。每个数据透视项都包含一个电影列表。每部电影都有一个封面图片,旁边还有一个标题和一些其他元数据。显然,要按照我的意愿设置样式,必须使用一些网格/堆栈面板。另外,我有每个项目的上下文菜单。在我的列表框上方,我有一个性能进度条,可以在加载数据时显示(我从 Web API 获取所有内容)。我的问题是其中一个列表包含的电影比其他列表多得多,大约 100 部。加载此列表时,应用程序使用大约 150-160 mb 内存,超过了 90 mb 的限制。看起来所有图像和内容都已立即加载(我认为这会导致此问题)。

我想要的是这样的:

首先加载标题和元数据,然后仅加载列表中用户当前所在位置的图像,以便在用户向下滚动到列表之前加载列表中较长的图像。

我尝试使用 deferredloadlist、lazylist 和普通列表框,并尝试将虚拟化设置为标准和回收,但没有结果。我必须承认我不确定所有这些事情到底是做什么的。有谁知道我该如何解决这个问题?提前致谢。

PS。列表框的 xaml 代码有些笨拙,所以我决定不在这篇文章中包含它。让我知道您是否真的需要查看它以提供帮助。

更新:我已经能够通过使用虚拟化列表框来减少内存使用量,但它仍然在 100 mb 左右。我在某处读到设置 bitmapImage.ImageSource =null; 完成使用图像后,会将其从内存中清除。当它们在列表框中时,如何为每个图像执行此操作?

4

2 回答 2

4

ListBox 本身不使用太多内存。这是 ListBoxItems 的内容。虚拟化面板仅创建可见的 ListBoxItems(加上更多)并破坏屏幕外的 ListBoxItems。因此,请确保您的 ListBox 使用虚拟化面板,例如通过不设置 ListBox.ItemsPanel。

对于虚拟化,Panel 需要有一个受限制的大小 - 否则它将创建所有 ListBoxItems。通常,这是通过将 ListBox 放入 Grid 或通过设置 Width/Height 为 ListBox 提供一个受约束的大小来完成的。但是,如果您将 ListBox 放置在非约束容器(例如 ScrollViewer、StackPanel...)中,那么 ListBox 的大小是无限的,ItemsPanel 将随心所欲地增长,并且所有 ListBoxItems 都会被创建——即使它们'远离屏幕。

于 2012-07-27T13:25:40.513 回答
1

您是否尝试过延迟图像下载?:

public class ItemViewModel 
{
   private BitmapImage _image;
   public BitmapImage Image 
   {
      get{

      if(_image == null)
      {
         _image = new BitmapImage();
          StartDownloadImageAsync();
      }
       return _image;
      }
   }
}

下载图像后 - 将其设置为 _image 并调用 RaisePropertyChanged("Image"); 因此,在虚拟化列表框上,您将仅为可见项目下载图像。

如果你这样做了,你可以尝试对列表进行分页。

于 2012-07-27T12:12:05.520 回答