It sounds like you are not giving WPF enough time to render the <ListBoxItem> objects before calling your method.
A common way of accessing the ListBoxItems right after its Items property is set is to use the ItemContainerGenerator.StatusChanged event, like this:
void MyConstructor()
{
listBox.ItemsSource = someCollection;
listBox.ItemContainerGenerator.StatusChanged +=
ItemContainerGenerator_StatusChanged;
}
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
// If containers have been generated
if (listBox.ItemContainerGenerator.Status ==
System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
// Remove event
listBox.ItemContainerGenerator.StatusChanged -=
ItemContainerGenerator_StatusChanged;
// Do whatever here
foreach(var item in listBox.Items)
{
var item = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(item);
// do whatever you want with the item
}
}
}
WPF runs code at different DispatcherPriorities. Code run in the constructor or on load is run at Normal priority, while the generation of ListBoxItem objects doesn't occur until Render priority, which runs after all Normal priority items have finished running.
You could alternatively use the Dispatcher to run your code at a later dispatcher priority than Render as well.