过滤ObservableCollection?

当我将ListBox直接绑定到ObservableCollection时,我得到了我的ListBox中显示的实时更新,但是只要我在混合中添加其他LINQ方法,我的ListBox就不再被告知对ObservableCollection的任何更改。

在这里,让我举一个例子来说明;

public partial class MainPage : PhoneApplicationPage { ObservableCollection Words = new ObservableCollection(); public MainPage() { InitializeComponent(); listBox1.ItemsSource = Words; } private void AddButton_Click(object sender, RoutedEventArgs e) { Words.Add(DateTime.Now.ToString()); } } 

在这里,我向一个简单的页面添加了一个Button和一个ListBox,然后单击该按钮使新项目立即出现在ListBox中。

但是,如果我改变了

  listBox1.ItemsSource = Words; 

  listBox1.ItemsSource = Words.Where(w => w.Contains(":")); 

ListBox不再更新。

如何在我的ObservableCollection和ListBox之间添加“filter”,并且仍然可以在不必再次设置.ItemsSource的情况下进行更新?

尝试使用CollectionViewSource,如下所示:

 WordsView = new CollectionViewSource(); WordsView.Filter += Words_Filter; WordsView.Source = Words; // ... void Words_Filter(object sender, FilterEventArgs e) { if (e.Item != null) e.Accepted = ((string)e.Item).Contains(":"); } 

为什么它不起作用:

 listBox1.ItemsSource = Words.Where(w => w.Contains(":")); 

你没有绑定ObservableCollection,而是绑定了Linq生成的IEnumerable。 这个新的“列表”不会通知ListBox有关列表中的更改。

您应该使用ICollectionView.Filter属性:

 ICollectionView view = CollectionViewSource.GetDefaultView(Words); view.Filter = WordFilter; ... bool WordFilter(object o) { string w = (string)o; return w.Contains(":") }