2013-05-04 6 views
0

У меня есть ObservableCollection строк, и я tring, чтобы связать его с конвертером ListBox и показать только строки, которые начинаются с некоторого префикса.
я писал:WPF binding ObservableCollection с конвертером

public ObservableCollection<string> Names { get; set; } 

public MainWindow() 
{ 
    InitializeComponent(); 
    Names= new ObservableCollection<Names>(); 
    DataContext = this; 
} 

и преобразователь:

class NamesListConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value == null) 
      return null; 
     return (value as ICollection<string>).Where((x) => x.StartsWith("A")); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return null; 
    } 
} 

и XAML:

<ListBox x:Name="filesList" ItemsSource="{Binding Path=Names, Converter={StaticResource NamesListConverter}}" /> 

но ListBox не обновить после обновления Бид (добавить или удалить).
Я заметил, что если я удалю конвертер из привязки, его работы отлично. Что не так с моим кодом?

+0

Вы не можете использовать DynamicResource для конвертера. Исключение брошено – user2348001

ответ

3

Ваш конвертер создает новую коллекцию из объектов в оригинальном ObservableCollection. Элемент ItemsSource, который устанавливается с использованием привязки, больше не является исходным ObservableCollection. Чтобы лучше понять, что это равно тому, что вы написали:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value == null) 
     return null; 
     var list = (value as ICollection<string>).Where((x) => x.StartsWith("A")).ToList(); 
     return list; 
    } 

Список, преобразователь возвращается новый объект с копией данных из исходной коллекции. Дальнейшие изменения в оригинальной коллекции не отражаются в этом новом списке, поэтому ListBox не знает об этих изменениях. Если вы хотите отфильтровать свои данные, загляните в CollectionViewSource.

EDIT: Как фильтровать

 public ObservableCollection<string> Names { get; set; } 
    public ICollectionView View { get; set; } 
    public MainWindow() 
    { 
     InitializeComponent(); 

     Names= new ObservableCollection<string>(); 
     var viewSource = new CollectionViewSource(); 
     viewSource.Source=Names; 

     //Get the ICollectionView and set Filter 
     View = viewSource.View; 

     //Filter predicat, only items that start with "A" 
     View.Filter = o => o.ToString().StartsWith("A"); 

     DataContext=this; 
    } 

В XAML установить ItemsSource к CollectionView

<ListBox x:Name="filesList" ItemsSource="{Binding Path=View}"/> 
+0

Спасибо! Вы можете порадовать пример того, что мне нужно? – user2348001

+0

@ user2348001 Обновление с примером фильтра, должно быть хорошо, но я написал его из «памяти», возможно, есть некоторые ошибки. – jure

+0

Спасибо! Но фильтр, похоже, не обновляет, меняет ли существующее значение из списка – user2348001

0

Возможно преобразователь не используется при добавлении или удалении элементов. Самый простой способ добиться того, что вы хотите, это реализовать INotifyPropertyChanged в вашем классе и запустить событие PropertyChanged при каждом добавлении или удалении элементов. В целом «правильный» способ заключается в использовании CollectionView.