我有一个 ItemsControl 包含我想虚拟化的数据列表,但是 VirtualizingStackPanel.IsVirtualizing="True" 似乎不适合 ItemsControl.

是真的,还是我不知道的另一种方法?

要测试我一直在使用以下代码块:

<ItemsControl ItemsSource="{Binding Path=AccountViews.Tables[0]}"
              VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <TextBlock Initialized="TextBlock_Initialized"  
                   Margin="5,50,5,50" Text="{Binding Path=Name}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

如果我更改 ItemsControlListBox, ,我可以看到 Initialized 活动只运行几次(巨大的利润是这样,我只需要查看一些记录),但是作为一个 ItemsControl 每个项目都会初始化。

我尝试设置 ItemsControlPanelTemplateVirtualizingStackPanel 但这似乎无济于事。

有帮助吗?

解决方案

实际上,它不仅仅是制作 ItemsPanelTemplate 采用 VirtualizingStackPanel. 。默认值 ControlTemplate 为了 ItemsControl 没有 ScrollViewer, ,这是虚拟化的关键。添加到默认控制模板 ItemsControl (使用控制模板 ListBox 作为模板)为我们提供以下内容:

<ItemsControl
    VirtualizingStackPanel.IsVirtualizing="True"
    ScrollViewer.CanContentScroll="True"
    ItemsSource="{Binding Path=AccountViews.Tables[0]}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock
                Initialized="TextBlock_Initialized"
                Text="{Binding Path=Name}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate>
        <Border
            BorderThickness="{TemplateBinding Border.BorderThickness}"
            Padding="{TemplateBinding Control.Padding}"
            BorderBrush="{TemplateBinding Border.BorderBrush}"
            Background="{TemplateBinding Panel.Background}"
            SnapsToDevicePixels="True">
                <ScrollViewer
                    Padding="{TemplateBinding Control.Padding}"
                    Focusable="False">
                    <ItemsPresenter
                        SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                </ScrollViewer>
            </Border>
            </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

(顺便说一句,查看默认控制模板的绝佳工具是 告诉我模板)

要注意的事情:

你必须设置 ScrollViewer.CanContentScroll="True", , 看 这里 为什么。

另请注意我放 VirtualizingStackPanel.VirtualizationMode="Recycling". 。这将减少次数 TextBlock_Initialized 但是,在屏幕上可见许多文本块。您可以阅读有关UI虚拟化的更多信息 这里.

编辑:忘记说明明显:作为替代解决方案,您可以替换 ItemsControlListBox :)另外,查看 在MSDN页面上优化性能 并注意 ItemsControl 不在“实现性能功能的控件”表中,这就是为什么我们需要编辑控制模板的原因。

其他提示

以Davidn的答案为基础,这是您可以在ItemScontrol上使用的样式来虚拟化:

<!--Virtualised ItemsControl-->
<Style x:Key="ItemsControlVirtualizedStyle" TargetType="ItemsControl">
    <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ItemsControl">
                <Border
                    BorderThickness="{TemplateBinding Border.BorderThickness}"
                    Padding="{TemplateBinding Control.Padding}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    Background="{TemplateBinding Panel.Background}"
                    SnapsToDevicePixels="True"
                >
                    <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我不喜欢使用列表框的建议,因为它们允许您在不一定需要的地方选择行。

只是默认 ItemsPanel 不是 VirtualizingStackPanel. 。您需要更改它:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top