我以前使用後面的代碼手動添加項目到我的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