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.