【问题标题】:WPF binding ObservableCollection with converterWPF 将 ObservableCollection 与转换器绑定
【发布时间】:2013-05-04 09:37:57
【问题描述】:

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

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

【问题讨论】:

  • 您不能使用 DynamicResource 进行转换器。抛出异常

标签: c# wpf data-binding observablecollection


【解决方案1】:

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

【讨论】:

  • 谢谢!你可以写一个我需要的例子吗?
  • @user2348001 用过滤器示例更新,应该没问题,但我是从“内存”写的,可能有一些错误。
  • 谢谢!但是当我从列表中更改现有值时,过滤器似乎没有更新
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-26
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    相关资源
    最近更新 更多