WPF ListView非常缓慢 - 为什么?(ElementHost或其他原因?)

28

我有一个Windows Forms应用程序,其中包含一个单独的ElementHost,其中包含一个WPF UserControl... 在我的WPF中,我有一个非常简单的ListView:

<ListView Margin="4" ItemsSource="{Binding Notifications}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />
            <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" />
            <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}" />
            <GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" />
            <GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" />
            <GridViewColumn Header="Zip" DisplayMemberBinding="{Binding Zip}" />
        </GridView>
    </ListView.View>
</ListView>

如果我的数据源有10个项目,则表单在不到一秒钟的时间内加载完毕。如果我的数据源有1000个项目,则需要7秒钟的时间!!! 我的计时器仅考虑加载时间(不考虑获取项目所需的时间)。

那么我的问题是:

使用ElementHost会影响性能吗?

WPF DataBinding会影响性能吗?

ListView是垃圾控件吗?(顺便说一句,使用WPFToolkit的DataGrid结果相同)?


1
那么我会用一个答案问你的问题:你认为使用WPF列表视图开箱即用,并且有1000个项目,应该消耗2GB的内存并需要7秒钟才能加载吗?你认为这是WPF设计师在软件工程方面出色表现的结果吗? - cdiggins
4个回答

34
使用虚拟化技术
<ListView ItemsSource="{BindingNames}"Name="lv">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                   <!--<StackPanel/>
                    If StackPanel was used, the memory consumed was over 2GB and dead slow.
                    -->
                   <VirtualizingStackPanel>
                    <!--Memory footprint is only 200 mb-->
                    </VirtualizingStackPanel>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView> 

这既令人惊叹又令人惊讶。有没有办法在不使用DataTemplating的情况下获得与使用GridView相同的外观/感觉? - Timothy Khouri
是的。只需将“<ListView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel/> </ItemsPanelTemplate> </ListView.ItemsPanel>”部分放入您的代码中即可。这是加速事情的部分。 - Chris Jester-Young
5
请注意,VirtualizingStackPanels 是 ListView 的默认项面板模板。但是,使用一些功能,如分组,会覆盖默认设置。 - scobi
2
您还需要确保 ScrollViewer.CanContentScroll 属性未设置为 false,否则将禁用虚拟化(如 scobi 所推断)。 - Rodney Thomson

12

6

我曾经遇到一个问题,这里提供的答案并没有解决我的问题。在我的情况下,将ListViewMaxHeight属性设置为比实际显示高度更高的值立即解决了问题,感谢这个答案,即使我无法解释它是如何起作用的。


MaxHeight 可以改变游戏规则 - 特别是对于 ListView 这样会拉伸父控件高度的控件,比如 DockPanel 中的最后一个项目。设置固定的 MaxHeight 使得控件更快,之前它是无法使用的。 - Mios

0

我曾经遇到过同样的问题。将ListView替换为包含DataGridTextColumn项的DataGrid可以解决这个问题。

<DataGrid Margin="4" ItemsSource="{Binding Notifications}">
    <DataGrid.Columns>
    <DataGridTextColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />
    <DataGridTextColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" />
</DataGrid.Columns>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接