【问题标题】:ListBox ItemsSource dynamic filter WPFListBox ItemsSource 动态过滤器 WPF
【发布时间】:2009-01-12 10:16:22
【问题描述】:

我想通过数据源进行 UI 虚拟化。

这个想法是“过滤”我发送到 UI 的内容(在我的例子中是一个列表框)。

我注意到 ItemsSource(一个可观察的集合)被读取一次,并且更改过滤器不会触发刷新...

我不明白为什么 谢谢 乔纳森


我会尽量说清楚:

我有 CollectionViewSource:

<CollectionViewSource x:Key="MyItemView"
                                  Source="{Binding Path=Model.CurrentItem}" />

然后在我的 ListBox 中使用这个数据源:

<ListBox x:Name="myListBox"
                 ItemsSource="{Binding Source={StaticResource MyItemView}}"

我想实现一个转换器,它会返回过滤后的集合(基于当前日期):

<ListBox x:Name="myListBox"
                 ItemsSource="{Binding Source={StaticResource MyItemView}, Converter={StaticResource FilterByTime}, ConverterParameter=CurrentDate }"

我是这样实现的:

public class FilterByTimeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                System.Windows.Data.ListCollectionView list = value as System.Windows.Data.ListCollectionView;

                var model = DI.Resolve<ApplicationModel>();

                list.Filter = delegate(object item) 
                { 
                    bool r= (((MyModel)item).OriginalDate > model.TimeLine.CurrentDate.AddMonths(-1) 
                        && (((MyModel)item).OriginalDate < model.TimeLine.CurrentDate.AddMonths(1)));

                   // Console.WriteLine ("{0}<{1}<{2} : {3}",model.MyListBox.CurrentDate.AddMonths(-1),((MyModel)item).OriginalDate ,model. MyListBox.CurrentDate.AddMonths(1),r.ToString());
                    return r;
                };

                return list;
            }

            return DependencyProperty.UnsetValue;
        }

这很好用……但只有在第一次出现时才可以。 当当前日期更改并且过滤器更改时,列表不会更新。

也许我应该听听 CurrentDate PropertyChange,但我很困惑如何做到这一点

谢谢 乔纳森

【问题讨论】:

  • 请澄清您的问题。什么过滤器?这是您定义的属性吗?

标签: c# wpf data-binding


【解决方案1】:

CollectionViewSource 本身支持通过其Filter 属性进行过滤。你为什么不把你的过滤逻辑放在那里?

【讨论】:

    【解决方案2】:

    好吧,我也遇到了类似的问题,但提供了以下适合我的解决方案:

    假设,组合框显示作者列表和列表框所有书籍,我想按选定作者过滤书籍或显示所有未过滤的书籍。

    相关的窗口 XAML 片段:

    <ComboBox ItemsSource="{Binding Authors}"  DisplayMemberPath="FullName" SelectedValue="{Binding FilterAuthorBy, Mode=TwoWay}" />
    <ListBox Name="bookList" ItemsSource="{Binding Books}"/>
    

    在窗口构造函数上绑定本身是这样完成的:

    DataContext = new BookViewModel(this);
    

    而视图模型是这样定义的:

    public class BookViewModel
    {
       private Author _filterAuthorBy;
    
       public BookViewModel(IBookView view)
       {
          ...
          _books = new CollectionViewSource();
          _books.Source = _bookRepository.FindAll().ToArray();
          _books.Filter += (sender, e) =>
                             {
                                 Book book = e.Item as Book;
                                 if (_filterAuthorBy == null)
                                 {
                                     e.Accepted = true;
                                 }
                                 else
                                 {
                                     e.Accepted = book.Authors.Contains(_filterAuthorBy);
                                 }
                             };
       }
    
       public CollectionView Books
       {
           get
           {               
               return _books.View;
           }
       }
    
       public ObservableCollection<Author> Authors
       {
          get
          {
             return new ObservableCollection<Author>(_bookRepository.FindAllAuthors());
          }
       }
    
       public Author FilterAuthorBy
       {
           get
           {
               return _filterAuthorBy;
           }
           set
           {
               _filterAuthorBy = value;
               _books.View.Refresh();
           }
        } 
    }
    

    选定的作者被传递给 ViewModel,并通过调用 collectionViewSource.View.Refresh() 更新列表框

    【讨论】:

      【解决方案3】:

      您可能需要手动刷新:

      currentViewSource.View.Refresh()
      

      【讨论】:

        【解决方案4】:

        你在说什么过滤器?如果你是一个 CollectionView 然后绑定到那个,那么即使是控件也不会改变。

        【讨论】:

          猜你喜欢
          • 2011-07-13
          • 1970-01-01
          • 2014-08-16
          • 2010-11-29
          • 2010-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-13
          相关资源
          最近更新 更多