2

我有ItemsControlVirtualizingStackPanel作为这样的项目面板:

<ItemsControl Style="{StaticResource ItemsControl}" Name="itemsControl" 
              Margin="0,100,0,0" HorizontalAlignment="Stretch" Height="80">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBox  />                    
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>                    
                <VirtualizingStackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
</ItemsControl>

风格如下:

<Style x:Key="ItemsControl" TargetType="ItemsControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ItemsControl">
                <ScrollViewer VerticalScrollBarVisibility="Hidden" 
                              HorizontalScrollBarVisibility="Visible">
                    <ItemsPresenter />
                </ScrollViewer>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我将一个包含 100.000 个元素的集合设置为ItemsSource并获得了非常好的性能。一切都很好,除了一件事。当我在其中一个文本框中输入文本然后开始滚动时,我看到该文本出现在整个列表中的任何地方!

我了解VirtualizingStackPanel的作用。它不断加载在我们滚动时变得可见的元素。我了解它的虚拟化技术的某些方面,但我不知道如何理解这种奇怪的行为。我找不到关于 WPF/Silverlight 虚拟化的好文档,所以,请解释一下发生了什么

4

2 回答 2

6

VirtualizingStackPanel实际上并不连续加载元素。相反,它重新使用现有元素(控件)并简单地替换它们后面的 DataContext。

因此,如果您有VirtualizingStackPanel100,000 个项目,并且一次只有 10 个可见,它通常会呈现大约 14 个项目(滚动缓冲区的额外项目)。当你滚动时,这 14 个控件后面的 DataContext 会发生变化,但实际的控件本身永远不会被替换。

如果您执行类似在 TextBox #1 中输入 Text 之类的操作,并且TextBox.Text未绑定任何内容,则 Text 将始终显示,因为该控件正在被重用。如果您将 绑定TextBox.Text到一个值,那么当您滚动时 DataContext 将发生变化,这将替换显示的文本。

于 2011-10-04T14:16:08.927 回答
0

不确定如何在 VirtualizingStackPanel 中直接关闭回收,但这是 ListBox 中的语法。我会作为评论发布,但我想要格式化的代码。

   <ListBox VirtualizingStackPanel.VirtualizationMode="Standard" />
于 2011-10-04T14:36:21.617 回答