WPF使用转换器绑定ObservableCollection

时间:2013-05-04 09:37:57

标签: c# wpf data-binding observablecollection

我有一个字符串的ObservableCollection,我想把它与转换器绑定到ListBox,并只显示以某些前缀开头的字符串。
我写道:

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}}" />

但列表框在更新(添加或删除)后不会更新 我注意到,如果我从绑定中删除转换器,它的工作完美。 我的代码出了什么问题?

2 个答案:

答案 0 :(得分:4)

您的转换器正在从原始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

编辑:如何过滤

     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}"/>

答案 1 :(得分:1)

添加或删除元素时可能不使用转换器。实现所需内容的最简单方法可能是在类中实现INotifyPropertyChanged,并在每次添加或删除项时触发PropertyChanged事件。 一般来说,“正确”的方式是使用CollectionView