Wednesday, May 02, 2007

This is not bug, this is feature

Try to do following. Create ListBox and bind it's items to big collection. Now set height property of the ListBox to some value. After everything binded and collection filled iterate it's items and request it's indexes. How to do it? Simple. iterate items of ListBox and ask about YouListBox.ItemContainerGenerator.ContainerFromIndex(yourIndex). Check results. What we got? All visible items (± some before and after) has right index, but for all invisible items you'll get null response for this method. What's the problem? Is it bug?

The answer is no - this is feature. ListBox (as well as most of other base controls) do not actually draw invisible items. This is great performance advantage. But what to do if you need indexes of hidden items? Put your control inside ScrollViewer. This way your control will think, that it's fully drawn, but actual output will be partially with scroll bar. But if you doing this, know, that it's not really good idea to draw all items, even when they are invisible.

1 comment:

Scott said...

I have implemented a large list of items in a scrollviewer and I still don't receive a valid value back from the ItemContainerGenerator.ContainerFromIndex method calls when I scroll to the bottom of the list and select a item. I sometimes receive null. Seems to me for large lists there is a timing issue. If I set the listview ItemsPanel to a StackPanel instead of the default VirtualizingStackpanel the problem goes away. This makes sense since all items are considered visible when I set the itemspanel to a stackpanel. The disadvantage of coarse is the performance penalty. Any idea's on why when I have a ListView withing a ScrollViewer and I scroll to the bottom of a large list, select and item and then try to retrieve that data using the ContainerFromIndex method I receive null? Thanks