Scroll a new item in a ItemsControl into view

后端 未结 1 1327
北荒
北荒 2021-01-12 05:41

I have an ItemsControl that is databound to a ObservableCollection. I have this method in the code behind which adds a new model to the list. I wou

相关标签:
1条回答
  • 2021-01-12 06:18

    I think you need to call BringIntoView on the item container, not the ItemsControl itself :

    var container = DocumentElements.ItemContainerGenerator.ContainerFromItem(model) as FrameworkElement;
    if (container != null)
        container.BringIntoView();
    

    EDIT: actually this doesn't work, because at this point, the item container hasn't been generated yet... You could probably handle the StatusChanged event of the 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 the status changes to ContainersGenerated, and I have no idea why :S


    EDIT : OK, I understand now... this was because of the virtualization : the containers are generated only when they need to be displayed, so no containers are generated for hidden items. If you switch virtualization off for the ItemsControl (VirtualizingStackPanel.IsVirtualizing="False"), the solution above works fine.

    0 讨论(0)
提交回复
热议问题