从 ListBox 的 ScrollInfo 获取有效值

Getting valid values from ScrollInfo of a ListBox

我有一个列表框,我面临的问题是试图从 IScrollInfo 对象中获取有效值。

我通过将 ListBox 上的 MaxHeight 设置为 150 知道 ViewportHeight 应该在这个大小左右并且全高是两倍大所以 ExtentHeight 应该大约是 300。

我从中得到以下值:
_scrollInfo.ExtentHeight = 13
_scrollInfo.ViewportHeight = 7
_scrollInfo.VerticalOffset = varying but 1-6

值来自:
UIElement scrollable = _scrollInfo as UIElement;
似乎是正确的。
scrollable.RenderSize.Height = 146 大致正确。

我想知道的是:

当我的 ListBox 控件首次加载时,它被绑定到一个空 ObservableCollection。直到后来才添加项目。可能是 IScrollInfo 对象保留了 ListBox 为空时的这些初始值吗?

IScrollInfo 对象的另一件事是 VirtualizingStackPanel 这与此事有什么关系吗?

[编辑]
已尝试将 VirtualizingStackPanel 更改为 StackPanel,但我仍然得到相同的结果。

此行为由 ScrollViewer.CanContentScroll="True" 给出 它基本上说,您不能按像素滚动,而只能按项目滚动。

考虑这个例子:

private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
    var scrollViewer = (ScrollViewer) sender;
    Trace.WriteLine(string.Format("ExtentHeight: {0}, ViewportHeight : {1}, VerticalOffset : {2}",
        scrollViewer.ExtentHeight, scrollViewer.ViewportHeight, scrollViewer.VerticalOffset));
}


<ScrollViewer Height="150" ScrollChanged="ScrollViewer_ScrollChanged" CanContentScroll="True">
    <VirtualizingStackPanel>
        <Rectangle Height="40" Margin="5" Fill="Red" />
        <Rectangle Height="40" Margin="5" Fill="Green" />
        <Rectangle Height="40" Margin="5" Fill="Blue" />
        <Rectangle Height="40" Margin="5" Fill="Red" />
        <Rectangle Height="40" Margin="5" Fill="Green" />
        <Rectangle Height="40" Margin="5" Fill="Blue" />
        <Rectangle Height="40" Margin="5" Fill="Red" />
    </VirtualizingStackPanel>
</ScrollViewer>

你得到以下输出:

ExtentHeight: 7, ViewportHeight : 3, VerticalOffset : 0   
ExtentHeight: 7, ViewportHeight : 3, VerticalOffset : 1
ExtentHeight: 7, ViewportHeight : 3, VerticalOffset : 2   

但是当你设置 CanContentScroll="False":

ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 3,01724137931035
ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 6,03448275862069
ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 9,05172413793104
ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 12,0689655172414
ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 15,0862068965517
ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 18,1034482758621
ExtentHeight: 350, ViewportHeight : 150, VerticalOffset : 21,1206896551724

在第一个示例中,您按项目滚动。您有七个项目,因此 ExtentHeight 为 7,有 3 个项目可见,因此 ViewportHeight 为 3。

在第二个示例中,您按像素滚动,因此 ExtentHeight 是所有项目的总高度,视口高度是 scrollviewver 的高度

这个故事的寓意是,在某些情况下,您不想测量所有项目的大小,因为它可能会对性能产生负面影响。尤其是在虚拟化元素时。