0
votes

I need to iterate through the VirtualizingStackPanel of a ListBox control to get at the ListBoxItem.RenderSize values. In C# of VB.NET code, how might that be done?

Background:

I'm working with a third party control library in WPF which apparently has bugs (or "features") related to its Measure() algorithms. Instead, it does a very non-standard attached Dependency Property to size one of its frames.

To get around that I'm overriding Measure and supplying my own values to the attached property, but the values are being eaten by intervening values in the visual tree. However, the Items property of my ListBox returns viewmodels, which don't contain sizing info. Neither does the template for the viewmodel, which must auto-size.

1
You may access the container of an item (i.e. the ListBoxItem) by calling the ContainerFromItem method of the ListBox's ItemContainerGenerator - Clemens
Calling that function on the ViewModel in the ListBox.Items collection returns Nothing - Rob Perkins
Well, then you're somehow doing it wrong. ContainerFromItem will give you the ListBoxItem that holds an item, provided that the item is contained in the ListBox's Items collection, and that the corresponding ListBoxItem has already been created. Maybe the ListBoxItem has not yet been created due to virtualization. - Clemens
Of course I'm doing it wrong; it's what has prompted the question in the first place. And of course virtualization is in play, it's a default-templated ListBox. - Rob Perkins
As far as I can read your question, you haven't explicitly asked about ItemContainerGenerator. Anyway, you may post some here. - Clemens

1 Answers

0
votes

If container is not created (i.e., it is out of viewport bounds), you have to get the ScrollViewer which is the ListBox template child and then call the ScrollToHorisontalOffset method to create containers for items. After that you should also call the UpdateLayout to force container generation - here you can acces newly created container. Note that in has no correct value for RenderSize, but you can measure element and get its DesiredSize.

Note that ContainerFromItem can return null if your listbox is collapsed or container generation is not started (or not finished) - check the ItemContainerGenerator.Status property.