I've got code like this: (loading Collection of custom objects into memory and into ListBox item)
public class Product : INotifyPropertyChanged
{
// these four doesn't matter, just Product's simple data
public string nDB_No { get; set; }
public string fdGrp_Cd { get; set; }
public string long_Desc { get; set; }
public int refuse { get; set; }
// I do not load this Collection right away, only after explicit call
public ObservableCollection<Ingredient> ingredients { get; set; }
public Product() {sets all null}
public static ObservableCollection<Product> LoadProductsFromList(List<string> productList) {gets products data from SQLServer DB}
// and other methods irrelevant here
}
private void buttonCreate_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<Product> productCollection = new ObservableCollection<Product>();
List<string> productList = getProductsNamesFromDB();
var watch = Stopwatch.StartNew();
productCollection = LoadProductsFromList(productList);
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds);
// At this point there is about 700-800ms - that's ok, there's over 8000 records in DB
watch = Stopwatch.StartNew();
listBox.ItemsSource = productCollection;
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds);
// At this point watch shows only about 500ms but it takes over 10 seconds
//to load the ListBox with data and to show the MessageBox.
}
The listBox item has very simple DataTemplate attached, just one Rectangle, few colours and one TextBlock. When I place BreakPoints after attaching listBox.ItemsSource it breaks right away. So it seems like there's another thread ListBox is creating and it's doing something. I can't make up any faster way.
I'm doing something wrong but I don't know what it is. Please help ;).
By default, ListBox uses VirtualizingStackPanel as ItemsPanel, which means, that ItemsSource can contain practically unlimited ammount of items without performance effect.
try this in a clean solution without listbox modifications. It shows million items without problem
<ListBox x:Name="listBox" />
listBox.ItemsSource = Enumerable.Range(0, 1000000).ToArray();
VirtualizingStackPanel instantiates DataTemplate only for those items, which are currently visible in scrollviewer. It is called virtualization
It seems, that you have somehow broken the virtualization. Reasons could be:
Are you using any wpf theme, or some implicit styles for listbox?
In case if ItemsControl, some work is required in order to make virtualization work: Virtualizing an ItemsControl?
Just to make sure, it is virtualization problem, try to replace your datatemplate with simplest possible - empty rectangle, or even delete it. Hope this helps.