Фильтрация коллекции ObservableCollection?
когда я привязываю ListBox непосредственно к ObservableCollection, я получаю обновления в реальном времени, отображаемые в моем ListBox, но как только я добавляю другие методы LINQ в mix, мой ListBox больше не уведомляется о каких-либо изменениях в ObservableCollection.
вот, позвольте мне проиллюстрировать на примере;
public partial class MainPage : PhoneApplicationPage
{
ObservableCollection<String> Words = new ObservableCollection<string>();
public MainPage()
{
InitializeComponent();
listBox1.ItemsSource = Words;
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
Words.Add(DateTime.Now.ToString());
}
}
здесь я добавил кнопку и список на простую страницу, и нажатие кнопки заставляет новый элемент немедленно появляться в списке.
, если я изменюсь с listBox1.ItemsSource = Words;
to
listBox1.ItemsSource = Words.Where(w => w.Contains(":"));
список больше не обновляется.
как я могу добавить "фильтр" между моей ObservableCollection и ListBox, и все еще получить его для обновления без необходимости устанавливать .Опять же, что ItemsSource?
3 ответов
попробуйте использовать 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, но IEnumerable, созданный Linq. Этот новый "список" не уведомляет ListBox об изменениях в списке.
вы должны использовать ICollectionView.Filter
свойства:
ICollectionView view = CollectionViewSource.GetDefaultView(Words);
view.Filter = WordFilter;
...
bool WordFilter(object o)
{
string w = (string)o;
return w.Contains(":")
}