http://blogs.msdn.com/b/dancre/archive/tags/virtualizingtilepanel/
并且在它们的实现中,它们在virtualizingtilepanel上具有依赖属性,用于跟踪子大小.但是,WPF库的virtualizingstackpanel不要求我将子元素的大小设置为属性.但是,我不明白虚拟化堆栈面板如何在不实例化项目的情况下计算面板中的哪些项目可见.
我认为他们需要一个度量传递才能知道项目容器的大小,但是如果没有首先实例化这些项目,他们怎么知道呢?
我的目标是创建一个包含treeviewitems的面板并对其进行虚拟化,但是遵循virtualizingtilepanel中的示例只允许我虚拟化顶级项目.
我需要改变计算哪些项目可见的方式,但我不知道如何知道哪些项目是可见的而不知道大小并实际实例化项目.
编辑:等待,也许它会立即实例化在treeviewitem内部的对象并使用它们来计算大小?
解决方法
第二种模式称为ScrollToPixels,在此模式下,VirtualizingStackPanel管理哪些项目已虚拟化以及哪些项目已实现.如果某个项目尚未实现,VirtualizingStackPanel将使用其MinHeight值,如果没有用户设置为16像素的微软.例如,每个项目的高度为20个像素.对于视口高度,这将是200像素,但您总共有1000个项目,因此范围将是200(1000 – 10)* 16 = 16040像素. ScrollBar也会显得很小而且适当.
最后,VirtualizingStackPanel是一个复杂的东西,它的工作原理很棒.它还允许垂直和水平虚拟化,这是非常棒的.如果您想编写自己的VirtualizingStackPanel,我建议您停止重新发明轮子.你将最终在代码中做同样的事情,因为微软的人这样做,为什么在其他人已经开发VirtualizingStackPanel的时候会等待时间:)
我用RedGate工具反映了VirtualizingStackPanel.
看看这个:
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's 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; }
如果您反映ScrollViewer,您会发现:
internal const double _scrollLineDelta = 16.0; // Default physical amount to scroll with one Up/Down
正如您所看到的那样,当容器不可用时会猜到大小,这意味着它设置为16.0像素,这是microsoft的默认值.
顺便说一下像素滚动就在wpf中,因为自从.Net 3.5开始以来,就像看到TreeView一样.