例如,尝试创建此简单的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) => { };
}
网格中只有100个字符串。文本框允许过滤字符串。
但是,例如将123
写入过滤器,然后再删除它会导致应用程序多秒钟的冻结。为什么不是即时的?
编辑:在.NET 4.5中,甚至带有10,000个项目也是即时的。这似乎是.NET 4.6中的一个回归?
FilteredList
引发四次PropertyChanged事件。每次属性更改时,整个DataGrid内容都会被重新创建,因为整个ItemsSource
集合都被替换。还要注意,在属性getter中的ToArray()
是多余的。 - Clemens