3

我正在创建一个带有缩略图的简单文件浏览器。我正在使用带有自定义 DataTemplate 的 ListBox 来显示 ObservableCollection 中的对象。

<DataTemplate>
   <StackPanel Margin="5">
      <Image Source="{Binding Path=ThumbnailPath}"/>
      <Label Background="White" Content="{Binding Path=FileName}"/>
   </StackPanel>
</DataTemplate>

(我的自定义类 File 的)对象只有这两个字符串属性:ThumbnailPath 和 FileName。当用户选择一个文件夹时,BackgroundWorker 会获取文件列表并创建 File 类的实例。使用 BW 的 ReportProgress 将这些实例分派到 UI 线程(以 10 个为一组)。在事件处理程序中,它们被添加到绑定到我的 ListBox 的 ObservableCollection 中。

问题是当至少 20-30 个文件要添加到我的收藏中时;在 ListBox 更新之前,UI 冻结了将近三秒钟。甚至不要问当一个文件夹包含数百个文件时会发生什么。一切都在后台做好了准备,所以我猜当 WPF 开始初始化和渲染空的 Image 元素时就会出现问题。当我从 DataTemplate 中注释掉 Image 时,眨眼间就可以更新集合及其视图。

有什么可以做的吗?我知道可以在后台线程中创建整个 View 对象(一个新的 StackPanel,添加子新标签和新图像,设置值),但是 DataBinding 和模板的重点应该是避免这样做的需要......所以如何在其 DataTemplate 中用图像填充 ListBox 而不会失去响应能力?

PS:实际的缩略图是由FFmpeg生成并保存到文件中的,但是这个过程只有在显示所有项目(带有空白图像对象)后才开始,所以在这个问题的上下文中它们是无关紧要的。

4

1 回答 1

0

尝试这个:

将 ThumbnailPath 更改为 BitmapImage 的类型;

设置属性使用时

BitmapImage bi1 = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block
bi1.BeginInit();
bi1.UriSource = new Uri(@"C:\filepath.jpg");
 To save significant application memory, set the DecodePixelWidth or   
// DecodePixelHeight of the BitmapImage value of the image source to the desired  
// height or width of the rendered image. If you don't do this, the application will  
// cache the image as though it were rendered as its normal size rather then just  
// the size that is displayed. 
// Note: In order to preserve aspect ratio, set DecodePixelWidth 
// or DecodePixelHeight but not both.
bi1.DecodePixelWidth = 200;
bi1.EndInit();
bi1.Freeze();

//if you do not Freeze, your app will leak memory.
于 2013-08-12T04:48:54.723 回答