I think you need to call BringIntoView in the elements container, and not in the ItemsControl element itself:
var container = DocumentElements.ItemContainerGenerator.ContainerFromItem(model) as FrameworkElement; if (container != null) container.BringIntoView();
EDIT: Actually this does not work, because at the moment the item container has not yet been generated ... Perhaps you could handle the StatusChanged event for ItemContainerGenerator . I tried the following code:
public static class ItemsControlExtensions { public static void BringItemIntoView(this ItemsControl itemsControl, object item) { var generator = itemsControl.ItemContainerGenerator; if (!TryBringContainerIntoView(generator, item)) { EventHandler handler = null; handler = (sender, e) => { switch (generator.Status) { case GeneratorStatus.ContainersGenerated: TryBringContainerIntoView(generator, item); break; case GeneratorStatus.Error: generator.StatusChanged -= handler; break; case GeneratorStatus.GeneratingContainers: return; case GeneratorStatus.NotStarted: return; default: break; } }; generator.StatusChanged += handler; } } private static bool TryBringContainerIntoView(ItemContainerGenerator generator, object item) { var container = generator.ContainerFromItem(item) as FrameworkElement; if (container != null) { container.BringIntoView(); return true; } return false; } }
However, it doesn’t work either ... for some reason, ContainerFromItem still returns null after changing state to ContainersGenerated , and I have no idea why: S
EDIT: OK, now I understand ... it was due to virtualization: containers are only generated when they should be displayed, so containers are not created for hidden elements. If you disable virtualization for ItemsControl ( VirtualizingStackPanel.IsVirtualizing="False" ), the solution above works fine.
Thomas levesque
source share