首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >虚拟化ItemsControl?

虚拟化ItemsControl?
EN

Stack Overflow用户
提问于 2010-05-07 03:29:03
回答 3查看 57.7K关注 0票数 130

我有一个包含要虚拟化的数据列表的ItemsControl,但是VirtualizingStackPanel.IsVirtualizing="True"似乎不能与ItemsControl一起工作。

这是真的吗?还是有其他我不知道的方法?

为了测试,我使用了以下代码块:

代码语言:javascript
复制
<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>

如果我将ItemsControl更改为ListBox,我可以看到Initialized事件只运行了几次(巨大的边距只是因为我只需要查看几条记录),但是作为ItemsControl,每一项都会被初始化。

我尝试将ItemsControlPanelTemplate设置为VirtualizingStackPanel,但似乎无济于事。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-07 04:25:14

实际上,除了让ItemsPanelTemplate使用VirtualizingStackPanel之外,还有很多事情要做。ItemsControl的默认ControlTemplate没有ScrollViewer,这是虚拟化的关键。添加到ItemsControl的默认控件模板(使用ListBox的控件模板作为模板)将为我们提供以下内容:

代码语言:javascript
复制
<ItemsControl ItemsSource="{Binding AccountViews.Tables[0]}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <TextBlock Initialized="TextBlock_Initialized"
                 Text="{Binding Name}" />
    </DataTemplate>
  </ItemsControl.ItemTemplate>

  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <VirtualizingStackPanel IsVirtualizing="True"
                              VirtualizationMode="Recycling" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

  <ItemsControl.Template>
    <ControlTemplate TargetType="ItemsControl">
      <Border BorderThickness="{TemplateBinding BorderThickness}"
              BorderBrush="{TemplateBinding BorderBrush}"
              Background="{TemplateBinding Background}">
        <ScrollViewer CanContentScroll="True" 
                      Padding="{TemplateBinding Padding}"
                      Focusable="False">
          <ItemsPresenter />
        </ScrollViewer>
      </Border>
    </ControlTemplate>
  </ItemsControl.Template>
</ItemsControl>

(顺便说一句,查看默认控件模板的一个很好的工具是Show Me The Template)

注意事项:

您必须设置ScrollViewer.CanContentScroll="True",请参阅here了解原因。

另请注意,我将VirtualizingStackPanel.VirtualizationMode="Recycling"。无论屏幕上显示多少个TextBlocks,这都将减少调用TextBlock_Initialized的次数。你可以阅读更多关于UI虚拟化here 的内容。

编辑:忘记陈述显而易见的事实:作为替代解决方案,您可以将ItemsControl替换为ListBox :)另外,查看此Optimizing Performance on MSDN page,并注意到ItemsControl不在“实现性能特性的控件”表中,这就是我们需要编辑控件模板的原因。

票数 236
EN

Stack Overflow用户

发布于 2012-11-15 14:00:58

基于DavidN的回答,这里有一种你可以在ItemsControl上使用的风格来虚拟化它:

代码语言:javascript
复制
<!--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>

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

票数 43
EN

Stack Overflow用户

发布于 2010-05-07 04:15:16

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

代码语言:javascript
复制
<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
票数 -4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2783845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档