2

我有一个 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}}" />

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

4

2 回答 2

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}"/>
于 2013-05-04T09:44:32.110 回答
1

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

于 2013-05-04T09:46:16.430 回答