我想通过数据源进行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,但我很困惑如何做到这一点
由于 乔纳森
答案 0 :(得分:9)
CollectionViewSource
本身支持通过其Filter
属性进行过滤。你为什么不把过滤逻辑放在那里?
答案 1 :(得分:6)
好吧,我有类似的问题,但附带以下解决方案对我有用:
据说,组合框显示作者列表和列表框中的所有书籍,我想按选定作者过滤书籍或显示未经过滤的所有书籍。
相关窗口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()
更新列表框答案 2 :(得分:4)
您可能需要手动刷新:
currentViewSource.View.Refresh()
答案 3 :(得分:0)
你在谈论什么过滤器?如果你是一个CollectionView,然后绑定到那个,那么即使控件可以接收也不会有任何改变。