Альтернатива VirtualizingStackPanel.CacheSize в.Net 4.0

Какие факторы учитывает virtualizingstackpanel, когда решает визуализировать элементы вокруг видимого элемента?

Пример: при просмотре списка 7 при просмотре элемента 7 также будут отображаться элементы 6 и 8, хотя они не видны.

Как можно ограничить визуализируемые элементы, чтобы визуализировать ТОЛЬКО видимый элемент?

2 ответа

Решение

Я решил проблему, переопределив MeasureOverride мы уже купили книгу, о которой Шеридан упомянул в своем ответе, в зависимости от главы о виртуализации, вот что я сделал с моим классом, который расширяет VirtualizingStackPanel: и это сработало!

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);
                }
            }
        }

Виртуализация - довольно сложный предмет, но у меня есть книга, которая хорошо ее описывает. Кроме того, в этой книге также показано, как реализовать настраиваемую виртуализацию, которая может потребоваться для достижения вашей цели. К счастью для вас, я обнаружил, что кто-то разместил PDF книгу в Интернете, и вы можете найти ее, нажав на эту ссылку.

Раздел виртуализации начинается на стр. 129, но стоит прочесть и остальную его часть, так как в ней есть некоторые очень интересные вещи.

Другие вопросы по тегам