为什么在.NET 4.6中更改WPF DataGrid ItemsSource的速度非常慢?

时间:2016-10-20 15:43:43

标签: c# wpf datagrid

例如,尝试这个简单的WPF窗口:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox Grid.Row="0" Text="{Binding Path=Filter, UpdateSourceTrigger=PropertyChanged}" />

        <DataGrid Grid.Row="1" ItemsSource="{Binding FilteredList}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding}" />
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>

这个代码背后:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;

public partial class MainWindow : Window, INotifyPropertyChanged
{
    List<string> items = new List<string>();
    string filter = string.Empty;

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        for (int i = 0; i < 100; i++) items.Add(i.ToString());
    }

    public IEnumerable<string> FilteredList
    {
        get { return this.items.Where(item => item.Contains(filter)).ToArray(); }
    }

    public string Filter
    {
        get { return filter; }
        set
        {
            if (filter != value)
            {
                filter = value;
                PropertyChanged(this, new PropertyChangedEventArgs("FilteredList"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = (s, e) => { };
}

网格中只有一百个字符串。文本框允许过滤字符串。

但是将例如123写入过滤器然后再次删除它会冻结应用程序多秒钟。为什么这不是即时的?

编辑:在.NET 4.5中它确实是即时的,即使有10'000项。似乎是.NET 4.6中的回归?

2 个答案:

答案 0 :(得分:1)

问题是您每次都要替换整个集合。 您应该使用CollectionViewSource作为DataGrid的源。 CollectionViewSource接受过滤器表达式。因此,您可以基于原始IEnumerable创建CollectionViewSource,并根据文本框值创建过滤方法。然后调用CollectionViewSource的方法Refresh

答案 1 :(得分:1)

DataGrid.EnableColumnVirtualization 默认为 False。将其设置为 True 会有所帮助。