I want to verify that the items in my ListBox
are displayed correctly in the UI. I figured one way to do this is to go through all of the children of the
The Solution from Andy is a very good idea, but is incomplete. For example, the first 5 containers are created and in the panel. The list hast 300 > items. I request the last container, with this logic, ADD. Then I request the last index - 1 container, with this logis ADD! That's the problem. The order of the Children inside the panel is not valid.
A Solution for this:
private FrameworkElement GetContainerForIndex(int index)
{
if (ItemsControl == null)
{
return null;
}
var container = ItemsControl.ItemContainerGenerator.ContainerFromIndex(index -1);
if (container != null && container != DependencyProperty.UnsetValue)
{
return container as FrameworkElement;
}
else
{
var virtualizingPanel = FindVisualChild(ItemsControl);
if (virtualizingPanel == null)
{
// do something to load the (perhaps currently unloaded panel) once
}
virtualizingPanel = FindVisualChild(ItemsControl);
IItemContainerGenerator generator = ItemsControl.ItemContainerGenerator;
using (generator.StartAt(generator.GeneratorPositionFromIndex(index), GeneratorDirection.Forward))
{
bool isNewlyRealized = false;
container = generator.GenerateNext(out isNewlyRealized);
if (isNewlyRealized)
{
generator.PrepareItemContainer(container);
bool insert = false;
int pos = 0;
for (pos = virtualizingPanel.Children.Count - 1; pos >= 0; pos--)
{
var idx = ItemsControl.ItemContainerGenerator.IndexFromContainer(virtualizingPanel.Children[pos]);
if (!insert && idx < index)
{
////Add
virtualizingPanel.GetType().InvokeMember("AddInternalChild", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, Type.DefaultBinder, virtualizingPanel, new object[] { container });
break;
}
else
{
insert = true;
if (insert && idx < index)
{
break;
}
}
}
if (insert)
{
virtualizingPanel.GetType().InvokeMember("InsertInternalChild", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, Type.DefaultBinder, virtualizingPanel, new object[] { pos + 1, container });
}
}
return container as FrameworkElement;
}
}
}