How does a virtualizingstackpanel calculate the size of a child without instantiating the actual item?

I follow the tutorials presented here:

http://blogs.msdn.com/b/dancre/archive/tags/virtualizingtilepanel/

and in their implementation, they have a dependency property on the virtualizing panel, which tracks the size of the child. However, the virtualization library of the WPF library does not require me to set the size of the children as a property. However, I do not understand how the stack virtualization panel can calculate which elements on the panel are visible without creating elements.

I would think that they would need a pass to find out the sizes of the element containers, but how can they know that without the first instance of the elements?

My goal is to create a panel to host tree objects and virtualize them, but following the virtualizationtilepanel example, I allow virtualization of top-level elements.

I need to change the way I calculate which elements are visible, but I don’t see how he can know which elements are visible without knowing the size and actually creating the objects.

edit: wait, maybe it instantly creates the objects that go inside the treeviewitem and use them to calculate the size?

+6
source share
2 answers

VirtualizingStackPanel has two modes. One of them is called ScrollToContent, and in this mode VirtualizingStackPanel uses element indices. As an example, 10 elements are visible, and you have 1000 items, so the ScrollBar will be displayed small.

The second mode is called ScrollToPixels, and in this mode, VirtualizingStackPanel manages a list of items that are virtualized and that are implemented. If the item has not yet been implemented, VirtualizingStackPanel uses the MinHeight value, which if none of them is set by the user is 16 pixels for Microsoft. As an example, 10 elements are visible, and each element has a height of 20 pixels. This will be 200 pixels for the height of the viewport, but you will have a total of 1000 elements, so the size will then be 200 + (1000 - 10) * 16 = 16040 pixels. ScrollBar will also seem small and suitable.

As a result, VirtualizingStackPanel is a complicated thing, and it works great basically. It also allows you to virtualize vertically and horizontally, which is amazing. If you want to write your own VirtualizationStackPanel, I suggest you stop reinventing the wheel. You will end up with the same as in the code, since the guys from Microsoft did it because the wait time was when someone else developed VirtualizingStackPanel :)

I flipped VirtualizingStackPanel using the RedGate tool. Take a look at this:

private Size ContainerSizeForItem(ItemsControl itemsControl, object item, int index, out UIElement container) { Size containerSize; container = index >= 0 ? ((ItemContainerGenerator)Generator).ContainerFromIndex(index) as UIElement : null; if (container != null) { containerSize = container.DesiredSize; } else { // It virtualized; grab the height off the item if available. object value = itemsControl.ReadItemValue(item, _desiredSizeStorageIndex); if (value != null) { containerSize = (Size)value; } else { // // No stored container height; simply guess. // containerSize = new Size(); if (Orientation == Orientation.Horizontal) { containerSize.Width = ContainerStackingSizeEstimate(itemsControl, /*isHorizontal = */ true); containerSize.Height = DesiredSize.Height; } else { containerSize.Height = ContainerStackingSizeEstimate(itemsControl, /*isHorizontal = */ false); containerSize.Width = DesiredSize.Width; } } } return containerSize; } private double ContainerStackingSizeEstimate(IProvideStackingSize estimate, bool isHorizontal) { double stackingSize = 0d; if (estimate != null) { stackingSize = estimate.EstimatedContainerSize(isHorizontal); } if (stackingSize <= 0d || DoubleUtil.IsNaN(stackingSize)) { stackingSize = ScrollViewer._scrollLineDelta; } return stackingSize; } 

If you mirror ScrollViewer, you will find the following:

 internal const double _scrollLineDelta = 16.0; // Default physical amount to scroll with one Up/Down 

As you can see, the size is guessed when the container is not available, which means its set is 16.0 pixels, which is the default for Microsoft.

Btw pixel scrolling has been there in wpf since the beginning, since .Net 3.5 just sees a TreeView, for example. :) :)

+3
source

The elements of VirtualizingStackPanel are not directly dependent on the size of the content; it processes children based on the index.
The degree in the laying direction is determined solely by the number of children. VirtualizingStackPanel has no idea what the size of the child is until it implements this child.

When the viewport scrolls, the following elements are implemented, so you cannot use smooth scrolling with virtualization (except .Net4.5, where pixel scrolling was added)

There is a great 4-part blog on creating VirtualizingPanel in WPF, I used it to create VirtualizingWrapPanel , and it gave me a great idea of ​​how Virtualization works

http://blogs.msdn.com/b/dancre/archive/2006/02/06/implementing-a-virtualized-panel-in-wpf-avalon.aspx

+3
source

Source: https://habr.com/ru/post/956032/


All Articles