簡體   English   中英

ListBox ItemsSource動態過濾器WPF

[英]ListBox ItemsSource dynamic filter WPF

我想通過數據源進行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,但我很困惑如何做到這一點

謝謝喬納森

CollectionViewSource本身支持通過其Filter屬性進行Filter 你為什么不把過濾邏輯放在那里?

好吧,我有類似的問題,但附帶以下適用於我的解決方案:

據說,組合框顯示作者列表和列表框所有書籍,我想按選定的作者過濾書籍或顯示未過濾的所有書籍。

相關窗口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()更新列表框

您可能想要手動刷新:

currentViewSource.View.Refresh()

你在說什么過濾器? 如果你是一個CollectionView然后綁定到那個,那么即使控件可以接收也不會有變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM