Listview 加载大列表非常慢

Sco*_*ott 2 c# wpf xaml listview

我有一个 WPF 应用程序,可以搜索大型数据集并将结果显示在ListView. 搜索可以返回一个小的结果集,或者结果集可以是数千个项目。搜索数据集并返回结果集只需不到一秒的时间。返回集是一个ObservableCollection. 我的ListView加载时很慢。绑定ListViewObservableCollectionXAML 中的 。这是 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>
Run Code Online (Sandbox Code Playgroud)

这是绑定到的视图模型属性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);
  }
}
Run Code Online (Sandbox Code Playgroud)

这是构建 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;
}
Run Code Online (Sandbox Code Playgroud)

在视图模型中,我有以下代码负责设置 FoundItems。它将返回的集合强制转换为 ObservableCollection。

  FoundItems = new ObservableCollection<DataAccess.TranslationItem>(p_trItems.SearchList(p_fCaseSensitive, p_fIgnoreAmpersands, p_fExactMatch, p_fSearchEnglish ? "E" : "I", p_sSearchString));
Run Code Online (Sandbox Code Playgroud)

这行代码前后的断点表明 FoundItems 的构建仅需几毫秒。

知道为什么加载这么慢吗?这是从旧应用程序的转换,我在循环中手动构建列表,并且只需要一两秒钟的加载。

Sco*_*ott 7

这最终是一个简单的修复。我在声明中添加了以下内容ListView

ScrollViewer.CanContentScroll="True"
Run Code Online (Sandbox Code Playgroud)

现在看起来像这样:

    <ListView Grid.ColumnSpan="2"
              ItemsSource="{Binding FoundItems}"
              SelectionMode="Single"
              MaxHeight="2000"
              VirtualizingPanel.IsContainerVirtualizable="True"
              VirtualizingPanel.IsVirtualizing="True"
              ScrollViewer.CanContentScroll="True">
Run Code Online (Sandbox Code Playgroud)

我的列表从至少需要一分钟加载大型列表变为几乎瞬时加载。