I have a class called Book;
class Book
{
public string Name { get; set; }
public string Author { get; set; }
public int PagesCount { get; set; }
public int Category { get; set; }
}
The ListBox displays a list of Books and the ItemTemplate has been modified so as to visually represent the Book. The text shows the book's Name, author and the number of pages. The category, however is represented by a certain color (for example, history is blue, romance is red etc.) Now, the text has an OuterGlowBitmap Effect and a value converter from the Category (int) to the appropriate Color. Everything is bound in DataTemplate for ListBoxItem. Technically, everything works fine.
The problem, however, is performance. It seems that the outerGlow bitmap effect is heavy on processor, so when I have a list of about 500 books, it takes about 500ms to retreive the data from the database but around 10 seconds to actually load the items into the ListBox. And even when the loading is done, scrolling is very laggy. I've tried to set the VirtualizingStackPanel.IsVirtualizing to True, but to no avail. (The maximum number of books that can be in the database at any given time is about 30000.)
However, even when there is more than 100 items in the listbox, human mind can't process that much quickly, so I don't aim to load and list to the user all the books that are searched for. That is why I have created a wrapper navigation class BookNavigator that actually binds the listbox to its ObservableCollection object. All the books are loaded into this BookNavigator, but only X of them are displayed in the listbox (by adding them to the observableCollection).
The problem with this is that I want that number of displayed books to be small enough for listbox not to display the scrollbar, so i can implement my own methods of scrolling (First, Previous, Next, Last, or simply my own scrollbar, doesn't matter).
How can I calculate how many items to display so the scrollbar is not shown?
Two problems that pop up: - Resizing the application can change the listbox's size - Not all the listbox items are of the same height (depending on the number of authors).
Is there any way to achieve what I am trying to do?
EDIT (as a reply to Martin Harris)
The problem with the code Martin Harris suggested is that the foreach loop uses FrameworkElement, but the listbox is filled with objects of type Book which does not inherit from FrameworkElement, nor it has any other mean of calculating its height. The ListBoxItem's root element is a grid, so maybe it would be possible to retreive this grid, but I don't know how to do that?
Is there any way at all to get the actual UI elements that are created to represent the listbox item?
EDIT
I found this Q/A which seems to be what I need.. ItemContainerGenerator