我以前使用后面的代码手动添加项目到我的ListBox,但它非常缓慢。就性能而言,我听说通过XAML进行数据绑定是最好的选择。使用DataBinding的ListBox的极端缓慢人口
所以我设法让数据绑定工作(新绑定),但令我沮丧的是,性能没有我以前的非数据绑定方法更好。
这个想法是,我的ListBox包含一个名字在下面的图像。我做了一些基准测试,54个项目需要8秒才能显示。对于用户等待来说,这自然是太长了。
源图像处于最高:2100x1535px,范围从400kb> 4mb每个文件。
重现此问题所需的图像可以在这里找到:链接被删除,因为问题已被回答,我的服务器没有太多的带宽津贴。其他图像源在这里:https://imgur.com/a/jmbv6
我已经提出了一个可重现的例子,下面的问题。我做错了什么让这么慢?
谢谢。
的XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800" WindowState="Maximized">
<Grid>
<ListBox x:Name="listBoxItems" ItemsSource="{Binding ItemsCollection}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<VirtualizingStackPanel>
<Image Width="278" Height="178">
<Image.Source>
<BitmapImage DecodePixelWidth="278" UriSource="{Binding ImagePath}" CreateOptions="IgnoreColorProfile" />
</Image.Source>
</Image>
<TextBlock Text="{Binding Name}" FontSize="16" VerticalAlignment="Bottom" HorizontalAlignment="Center" />
</VirtualizingStackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
后面的代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
internal class Item : INotifyPropertyChanged
{
public Item(string name = null)
{
this.Name = name;
}
public string Name { get; set; }
public string ImagePath { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ObservableCollection<Item> ItemsCollection;
List<Item> data;
public MainWindow()
{
InitializeComponent();
this.data = new List<Item>();
this.ItemsCollection = new ObservableCollection<Item>();
this.listBoxItems.ItemsSource = this.ItemsCollection;
for (int i = 0; i < 49; i ++)
{
Item newItem = new Item
{
ImagePath = String.Format(@"Images/{0}.jpg", i + 1),
Name = "Item: " + i
};
this.data.Add(newItem);
}
foreach (var item in this.data.Select((value, i) => new { i, value }))
{
Dispatcher.Invoke(new Action(() =>
{
this.ItemsCollection.Add(item.value);
}), DispatcherPriority.Background);
}
}
}
}
刚刚用范围为300-900kb的50幅图像对其进行了测试,并且它几乎立即显示...但是,我不得不复制一些图像并重命名它们,没有足够的测试材料可用。 – grek40
小图像的确如此。这是一个庞大而详细的图像,让它爬行 – PersuitOfPerfection
@PeterDuniho阿哈,看起来像imgur正在压缩他们然后什么的。这里是链接全部下载:http://s.imgur.com/a/jmbv6/zip - 我还会将其添加到OP – PersuitOfPerfection