Listview加载大列表的速度非常慢
本文关键字:速度 非常 列表 加载 Listview | 更新日期: 2023-09-27 18:11:47
我有一个WPF应用程序,它搜索一个大数据集并在ListView
中显示结果。搜索可以返回一个小的结果集,也可以返回包含数千个条目的结果集。搜索数据集并返回结果集只需要不到一秒的时间。返回集是一个ObservableCollection
。我的ListView
是缓慢的,当它被加载。在XAML中,ListView
绑定到ObservableCollection
。这是XAML:
<GroupBox Header="Translations" Grid.Row="2" Margin="10,0,10,8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListView Grid.ColumnSpan="2"
ItemsSource="{Binding FoundItems}"
SelectionMode="Single"
MaxHeight="2000"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True">
<ListView.View>
<GridView>
<GridViewColumn Header="Translation File Name" Width="NaN" DisplayMemberBinding="{Binding Path=FileName}" />
<GridViewColumn Header="English" Width="400" DisplayMemberBinding="{Binding Path=English}" />
<GridViewColumn Header="International" Width="400" DisplayMemberBinding="{Binding Path=International}" />
</GridView>
</ListView.View>
</ListView>
<Border Grid.Row="1" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="{DynamicResource AccentColorBrush}">
<Grid Margin="5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<RadioButton VerticalAlignment="Center" Content="Search English" IsChecked="{Binding Path=SearchEnglish}" />
<RadioButton VerticalAlignment="Center" Grid.Column="1" Content="Search International" IsChecked="{Binding Path=SearchInternational}" />
</Grid>
</Border>
</Grid>
</GroupBox>
这是ListView
绑定的视图模型属性:
public ObservableCollection<DataAccess.TranslationItem> FoundItems
{
get
{
return p_FoundItems;
}
set
{
p_FoundItems = value;
NotifyOfPropertyChange("FoundItems");
TranslationsFound = string.Format("{0} translations found", p_FoundItems.Count);
}
}
这是构建FoundItems集合的代码。执行和构建集合只需要几毫秒。速度问题绝对不在这里。它使用一个黑盒DLL来获取列表。然后,它构建一个可在ObservableCollection中使用的项集合。
public List<TranslationItem> SearchList(bool fCaseSensitive, bool fIgnoreAmpersands, bool fExactMatch,
string sSearchLanguage, string sSearchString)
{
List<TTranslations.TranslationItem> lstFound = null;
List<TranslationItem> lstReturn = new List<TranslationItem>();
p_trItems.SearchingFile += p_trItems_SearchingFile;
lstFound = p_trItems.SearchList(fCaseSensitive, fIgnoreAmpersands, fExactMatch, sSearchLanguage, sSearchString);
foreach (TTranslations.TranslationItem tiItem in lstFound)
lstReturn.Add(new TranslationItem(tiItem));
return lstReturn;
}
在视图模型中,我有以下负责设置FoundItems的代码。它将返回的集合强制转换为ObservableCollection。
FoundItems = new ObservableCollection<DataAccess.TranslationItem>(p_trItems.SearchList(p_fCaseSensitive, p_fIgnoreAmpersands, p_fExactMatch, p_fSearchEnglish ? "E" : "I", p_sSearchString));
这行代码前后都有一个断点,表明构建FoundItems只需要几毫秒。
知道为什么它会加载这么慢吗?这是对旧应用程序的转换,在旧应用程序中,我在循环中手动构建列表,这只需要一两秒钟的加载时间。
这最终是一个容易的修复。我在ListView
声明中添加了以下内容:
ScrollViewer.CanContentScroll="True"
现在看起来像这样:
<ListView Grid.ColumnSpan="2"
ItemsSource="{Binding FoundItems}"
SelectionMode="Single"
MaxHeight="2000"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True">
我的列表从至少一分钟加载大列表,到几乎瞬间。