我有一个ListBox,我正在加载三种类型的对象,这些对象都继承自相同的父类型。我想使用CollectionViewSource根据类型过滤掉ListBox中的对象,但是我在编写过滤器时遇到了问题。
我的XAML如下:
<UserControl.Resources>
<CollectionViewSource x:Key="eventsViewSource"
Source="{Binding lifeCycleEvents}" >
<CollectionViewSource.SortDescriptions>
<compMod:SortDescription PropertyName="Date" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<ListBox Name="lstEventHistory" ItemsSource="{Binding Source={StaticResource eventsViewSource}}">
...
</ListBox>
在代码隐藏中,我正在加载从异步方法调用返回的对象的可观察集合:
private ObservableCollection<LifeCycleEvent> lifeCycleEvents;
...
lifeCycleEvents= e.Result;
CollectionViewSource eventsViewSource = this.Resources["eventsViewSource"] as CollectionViewSource;
eventsViewSource.Source = lifeCycleEvents;
现在我想写一个过滤器,它只会根据用户在UI中点击的复选框显示某种类型的对象。
以下是编写一个过滤器失败的尝试:
eventsViewSource.Filter = new Predicate<object>(rmaFilter);
public bool rmaFilter(object item)
{
if(item.GetType() == typeof(RmaEvent))
return true;
else
return false;
}
这会出现以下错误:“事件System.Windows.Data.CollectionViewSrouce.Filter只能出现在+ =或 - =”的左侧。
我找不到任何完全符合我需要的教程。那些,取决于Silverlight中不存在的默认视图。我查看了一个这样的教程here
任何提示都表示赞赏!
答案 0 :(得分:1)
CollectionView
和CollectionViewSource
的过滤器属性是一个事件,包含FilterEventHandler
类型的集合,而不是Predicate
。
为CollectionView中的每个项调用每个事件处理程序,以确定是否应显示它。
此外,从Filter属性中添加或删除事件处理程序将导致调用事件处理程序并更新集合。
因此,用于连接Filter事件处理程序的正确代码是:
eventsViewSource.Filter += new FilterEventHandler(rmaFilter);
要删除它:
eventsViewSource.Filter -= new FilterEventHandler(rmaFilter);
新的处理程序:
public void rmaFilter(object sender, FilterEventArgs args)
{
args.Accepted = args.Item is RmaType;
}
答案 1 :(得分:0)
根据MSDN文档,Filter是CollectionViewSource类型中的事件。 所以?正确的语法是:
eventsViewSource.Filter += new Predicate<object>(rmaFilter);
在教程中,您已经在上面进行了链接,作者使用了CollectionViewSource类型的static method,它返回了一个CollectionView对象。此CollectionView对象具有Filter属性(不是事件!),您可以使用=
语法