wpflistviewscrollviewervirtualizingstackpanel

Alternative of VirtualizingStackPanel.CacheSize in .Net 4.0


What are the factors that virtualizingstackpanel consider when it decides visualizing items around the visible item?

Ex: Having a listview, when viewing item 7, item 6& 8 will be visualized too although they are not seen.

How can limit visualized items, so that ONLY visible item is visualized?


Solution

  • I have solved the problem by overriding MeasureOverride function, we already purchased the book Sheridan has mentioned in his answer, depending on virtualization chapter, here is what I did to my class that extends VirtualizingStackPanel : and it worked!

    private ItemsControl ItemsOwner { get; set; }
            private int StartIndex { get; set; }
            private int EndIndex { get; set; }
    
    
            protected override void OnInitialized(EventArgs e)
            {
                ItemsOwner = ItemsControl.GetItemsOwner(this) as ItemsControl;
            }
    
    
            protected override Size MeasureOverride(Size availableSize)
            {
                ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
    
                // we can set StartIndex& EndIndex to mimic 
                // VirtualizingStackPanel.CacheSize in .Net 4.5
                // for my problem, I just fixed them at the index of item to be shown 
                StartIndex = PagesView.Instance.SelectedIndex;
                EndIndex = StartIndex;
    
                // Virtualize items
                IItemContainerGenerator generator = ItemsOwner.ItemContainerGenerator;
    
                GeneratorPosition startPos = generator.GeneratorPositionFromIndex(StartIndex);
                int childIndex = startPos.Offset == 0 ? startPos.Index : startPos.Index + 1;
                using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
                {
                    for (int i = StartIndex; i <= EndIndex; i++, childIndex++)
                    {
                        bool isNewlyRealized;
                        UIElement child = generator.GenerateNext(out isNewlyRealized) as UIElement;
                        if (isNewlyRealized)
                        {
                            if (childIndex >= InternalChildren.Count)
                            {
                                AddInternalChild(child);
                            }
                            else
                            {
                                InsertInternalChild(childIndex, child);
                            }
                            generator.PrepareItemContainer(child);
                        }
                    }
                }
    
    
    
                //DumpGeneratorContent();
    
    
                // Measure
                foreach (UIElement child in InternalChildren)
                {
                    child.Measure(availableSize);
                }
    
                // Clean up
                CleanupItems();
    
                return availableSize;
            }
    
            private void CleanupItems()
            {
                IItemContainerGenerator generator = ItemsOwner.ItemContainerGenerator;
                for (int i = InternalChildren.Count - 1; i >= 0; i--)
                {
                    GeneratorPosition position = new GeneratorPosition(i, 0);
                    int itemIndex = generator.IndexFromGeneratorPosition(position);
                    if (itemIndex < StartIndex || itemIndex > EndIndex)
                    {
                        generator.Remove(position, 1);
                        RemoveInternalChildRange(i, 1);
                    }
                }
            }